From 4da823ba4be74cdd840c6db854ee57cc0c864d31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Miku=C5=82a?= Date: Thu, 19 Feb 2026 22:11:58 +0100 Subject: [PATCH 01/22] Do not enable split debuginfo for windows-gnu Because rustc doesn't handle split debuginfo for these targets, enabling that option causes them to be missing some of the debuginfo. --- bootstrap.example.toml | 7 ++++--- src/bootstrap/src/core/config/target_selection.rs | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/bootstrap.example.toml b/bootstrap.example.toml index e0cbb0c0e747c..432a681403614 100644 --- a/bootstrap.example.toml +++ b/bootstrap.example.toml @@ -1008,9 +1008,10 @@ # its historical default, but when compiling the compiler itself, we skip it by # default since we know it's safe to do so in that case. # -# On Windows platforms, packed debuginfo is the only supported option, -# producing a `.pdb` file. -#split-debuginfo = if linux { off } else if windows { packed } else if apple { unpacked } +# On Windows MSVC platforms, packed debuginfo is the only supported option, +# producing a `.pdb` file. On Windows GNU rustc doesn't support splitting debuginfo, +# and enabling it causes issues. +#split-debuginfo = if linux || windows-gnu { off } else if windows-msvc { packed } else if apple { unpacked } # Path to the `llvm-config` binary of the installation of a custom LLVM to link # against. Note that if this is specified we don't compile LLVM at all for this diff --git a/src/bootstrap/src/core/config/target_selection.rs b/src/bootstrap/src/core/config/target_selection.rs index 47f6d6f386dfb..8457607b897dd 100644 --- a/src/bootstrap/src/core/config/target_selection.rs +++ b/src/bootstrap/src/core/config/target_selection.rs @@ -142,7 +142,7 @@ impl SplitDebuginfo { pub fn default_for_platform(target: TargetSelection) -> Self { if target.contains("apple") { SplitDebuginfo::Unpacked - } else if target.is_windows() { + } else if target.is_msvc() { SplitDebuginfo::Packed } else { SplitDebuginfo::Off From 7adb9bac0c7d2bf469e6b76c6cc47099afb02123 Mon Sep 17 00:00:00 2001 From: "LevitatingBusinessMan (Rein Fernhout)" Date: Fri, 27 Feb 2026 09:30:27 +0100 Subject: [PATCH 02/22] Add is_disconnected functions to mpsc and mpmc channels --- library/std/src/sync/mpmc/mod.rs | 46 +++++++++++++++++++++++++++++++ library/std/src/sync/mpmc/zero.rs | 6 ++++ library/std/src/sync/mpsc.rs | 38 +++++++++++++++++++++++++ 3 files changed, 90 insertions(+) diff --git a/library/std/src/sync/mpmc/mod.rs b/library/std/src/sync/mpmc/mod.rs index 8df81a580f7b8..6249e8a033e8d 100644 --- a/library/std/src/sync/mpmc/mod.rs +++ b/library/std/src/sync/mpmc/mod.rs @@ -623,6 +623,29 @@ impl Sender { _ => false, } } + + /// Returns `true` if the channel is disconnected. + /// + /// # Examples + /// + /// ``` + /// #![feature(mpmc_channel)] + /// + /// use std::sync::mpmc::channel; + /// + /// let (tx, rx) = channel::(); + /// assert!(!tx.is_disconnected()); + /// drop(rx); + /// assert!(tx.is_disconnected()); + /// ``` + #[unstable(feature = "mpmc_channel", issue = "126840")] + pub fn is_disconnected(&self) -> bool { + match &self.flavor { + SenderFlavor::Array(chan) => chan.is_disconnected(), + SenderFlavor::List(chan) => chan.is_disconnected(), + SenderFlavor::Zero(chan) => chan.is_disconnected(), + } + } } #[unstable(feature = "mpmc_channel", issue = "126840")] @@ -1349,6 +1372,29 @@ impl Receiver { pub fn iter(&self) -> Iter<'_, T> { Iter { rx: self } } + + /// Returns `true` if the channel is disconnected. + /// + /// # Examples + /// + /// ``` + /// #![feature(mpmc_channel)] + /// + /// use std::sync::mpmc::channel; + /// + /// let (tx, rx) = channel::(); + /// assert!(!rx.is_disconnected()); + /// drop(tx); + /// assert!(rx.is_disconnected()); + /// ``` + #[unstable(feature = "mpmc_channel", issue = "126840")] + pub fn is_disconnected(&self) -> bool { + match &self.flavor { + ReceiverFlavor::Array(chan) => chan.is_disconnected(), + ReceiverFlavor::List(chan) => chan.is_disconnected(), + ReceiverFlavor::Zero(chan) => chan.is_disconnected(), + } + } } #[unstable(feature = "mpmc_channel", issue = "126840")] diff --git a/library/std/src/sync/mpmc/zero.rs b/library/std/src/sync/mpmc/zero.rs index f1ecf80fcb9f6..c743462501922 100644 --- a/library/std/src/sync/mpmc/zero.rs +++ b/library/std/src/sync/mpmc/zero.rs @@ -316,4 +316,10 @@ impl Channel { pub(crate) fn is_full(&self) -> bool { true } + + /// Returns `true` if the channel is disconnected. + pub(crate) fn is_disconnected(&self) -> bool { + let inner = self.inner.lock().unwrap(); + inner.is_disconnected + } } diff --git a/library/std/src/sync/mpsc.rs b/library/std/src/sync/mpsc.rs index 0ae23f6e13bf2..81bb5849fb77f 100644 --- a/library/std/src/sync/mpsc.rs +++ b/library/std/src/sync/mpsc.rs @@ -607,6 +607,25 @@ impl Sender { pub fn send(&self, t: T) -> Result<(), SendError> { self.inner.send(t) } + + /// Returns `true` if the channel is disconnected. + /// + /// # Examples + /// + /// ``` + /// #![feature(mpsc_is_disconnected)] + /// + /// use std::sync::mpsc::channel; + /// + /// let (tx, rx) = channel::(); + /// assert!(!tx.is_disconnected()); + /// drop(rx); + /// assert!(tx.is_disconnected()); + /// ``` + #[unstable(feature = "mpsc_is_disconnected", issue = "none")] + pub fn is_disconnected(&self) -> bool { + self.inner.is_disconnected() + } } #[stable(feature = "rust1", since = "1.0.0")] @@ -1038,6 +1057,25 @@ impl Receiver { pub fn try_iter(&self) -> TryIter<'_, T> { TryIter { rx: self } } + + /// Returns `true` if the channel is disconnected. + /// + /// # Examples + /// + /// ``` + /// #![feature(mpsc_is_disconnected)] + /// + /// use std::sync::mpsc::channel; + /// + /// let (tx, rx) = channel::(); + /// assert!(!rx.is_disconnected()); + /// drop(tx); + /// assert!(rx.is_disconnected()); + /// ``` + #[unstable(feature = "mpsc_is_disconnected", issue = "none")] + pub fn is_disconnected(&self) -> bool { + self.inner.is_disconnected() + } } #[stable(feature = "rust1", since = "1.0.0")] From feef7b4eafedfae6c8fd40caf711343b6cc3fe43 Mon Sep 17 00:00:00 2001 From: "LevitatingBusinessMan (Rein Fernhout)" Date: Sat, 28 Feb 2026 19:52:50 +0100 Subject: [PATCH 03/22] warn of possible race condition in channel is_disconnected doc --- library/std/src/sync/mpmc/mod.rs | 8 ++++++++ library/std/src/sync/mpsc.rs | 8 ++++++++ 2 files changed, 16 insertions(+) diff --git a/library/std/src/sync/mpmc/mod.rs b/library/std/src/sync/mpmc/mod.rs index 6249e8a033e8d..16ae8a88370be 100644 --- a/library/std/src/sync/mpmc/mod.rs +++ b/library/std/src/sync/mpmc/mod.rs @@ -626,6 +626,10 @@ impl Sender { /// Returns `true` if the channel is disconnected. /// + /// Note that a return value of `false` does not guarantee the channel will + /// remain connected. The channel may be disconnected immediately after this method + /// returns, so a subsequent [`Sender::send`] may still fail with [`SendError`]. + /// /// # Examples /// /// ``` @@ -1375,6 +1379,10 @@ impl Receiver { /// Returns `true` if the channel is disconnected. /// + /// Note that a return value of `false` does not guarantee the channel will + /// remain connected. The channel may be disconnected immediately after this method + /// returns, so a subsequent [`Receiver::recv`] may still fail with [`RecvError`]. + /// /// # Examples /// /// ``` diff --git a/library/std/src/sync/mpsc.rs b/library/std/src/sync/mpsc.rs index 81bb5849fb77f..2abf7bfe341d4 100644 --- a/library/std/src/sync/mpsc.rs +++ b/library/std/src/sync/mpsc.rs @@ -610,6 +610,10 @@ impl Sender { /// Returns `true` if the channel is disconnected. /// + /// Note that a return value of `false` does not guarantee the channel will + /// remain connected. The channel may be disconnected immediately after this method + /// returns, so a subsequent [`Sender::send`] may still fail with [`SendError`]. + /// /// # Examples /// /// ``` @@ -1060,6 +1064,10 @@ impl Receiver { /// Returns `true` if the channel is disconnected. /// + /// Note that a return value of `false` does not guarantee the channel will + /// remain connected. The channel may be disconnected immediately after this method + /// returns, so a subsequent [`Receiver::recv`] may still fail with [`RecvError`]. + /// /// # Examples /// /// ``` From ce2de643fc94a687f8fc2ba89495fa754bd87624 Mon Sep 17 00:00:00 2001 From: "LevitatingBusinessMan (Rein Fernhout)" Date: Tue, 10 Mar 2026 19:21:19 +0100 Subject: [PATCH 04/22] assign mpsc_is_disconnected issue 153668 --- library/std/src/sync/mpsc.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/std/src/sync/mpsc.rs b/library/std/src/sync/mpsc.rs index 2abf7bfe341d4..a1c49bb83010c 100644 --- a/library/std/src/sync/mpsc.rs +++ b/library/std/src/sync/mpsc.rs @@ -626,7 +626,7 @@ impl Sender { /// drop(rx); /// assert!(tx.is_disconnected()); /// ``` - #[unstable(feature = "mpsc_is_disconnected", issue = "none")] + #[unstable(feature = "mpsc_is_disconnected", issue = "153668")] pub fn is_disconnected(&self) -> bool { self.inner.is_disconnected() } @@ -1080,7 +1080,7 @@ impl Receiver { /// drop(tx); /// assert!(rx.is_disconnected()); /// ``` - #[unstable(feature = "mpsc_is_disconnected", issue = "none")] + #[unstable(feature = "mpsc_is_disconnected", issue = "153668")] pub fn is_disconnected(&self) -> bool { self.inner.is_disconnected() } From b36ee95a648153c1f00c27e6e741e2eeb838d34a Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Tue, 10 Mar 2026 17:06:59 -0700 Subject: [PATCH 05/22] ci: add runners for vanilla LLVM 22 Ubuntu 26.04 has `llvm-22` packages that we can test with. The `Dockerfile` is otherwise the same as the `llvm-21` runners. --- .../host-x86_64/x86_64-gnu-llvm-22/Dockerfile | 66 +++++++++++++++++++ src/ci/github-actions/jobs.yml | 25 +++++++ 2 files changed, 91 insertions(+) create mode 100644 src/ci/docker/host-x86_64/x86_64-gnu-llvm-22/Dockerfile diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-llvm-22/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu-llvm-22/Dockerfile new file mode 100644 index 0000000000000..a22e8de90804f --- /dev/null +++ b/src/ci/docker/host-x86_64/x86_64-gnu-llvm-22/Dockerfile @@ -0,0 +1,66 @@ +FROM ubuntu:26.04 + +ARG DEBIAN_FRONTEND=noninteractive + +RUN apt-get update && apt-get install -y --no-install-recommends \ + bzip2 \ + g++ \ + gcc-multilib \ + make \ + ninja-build \ + file \ + curl \ + ca-certificates \ + python3 \ + git \ + cmake \ + sudo \ + gdb \ + llvm-22-tools \ + llvm-22-dev \ + libedit-dev \ + libssl-dev \ + pkg-config \ + zlib1g-dev \ + xz-utils \ + nodejs \ + mingw-w64 \ + # libgccjit dependencies + flex \ + libmpfr-dev \ + libgmp-dev \ + libmpc3 \ + libmpc-dev \ + && rm -rf /var/lib/apt/lists/* + +# Install powershell (universal package) so we can test x.ps1 on Linux +# FIXME: need a "universal" version that supports libicu74, but for now it still works to ignore that dep. +RUN curl -sL "https://github.com/PowerShell/PowerShell/releases/download/v7.3.1/powershell_7.3.1-1.deb_amd64.deb" > powershell.deb && \ + dpkg --ignore-depends=libicu72 -i powershell.deb && \ + rm -f powershell.deb + +COPY scripts/sccache.sh /scripts/ +RUN sh /scripts/sccache.sh + +# We are disabling CI LLVM since this builder is intentionally using a host +# LLVM, rather than the typical src/llvm-project LLVM. +ENV NO_DOWNLOAD_CI_LLVM 1 +ENV EXTERNAL_LLVM 1 + +# Using llvm-link-shared due to libffi issues -- see #34486 +ENV RUST_CONFIGURE_ARGS \ + --build=x86_64-unknown-linux-gnu \ + --llvm-root=/usr/lib/llvm-22 \ + --enable-llvm-link-shared \ + --set rust.randomize-layout=true \ + --set rust.thin-lto-import-instr-limit=10 + +COPY scripts/shared.sh /scripts/ + +COPY scripts/x86_64-gnu-llvm.sh /scripts/ +COPY scripts/x86_64-gnu-llvm2.sh /scripts/ +COPY scripts/x86_64-gnu-llvm3.sh /scripts/ +COPY scripts/stage_2_test_set1.sh /scripts/ +COPY scripts/stage_2_test_set2.sh /scripts/ + +ENV SCRIPT "Must specify DOCKER_SCRIPT for this image" diff --git a/src/ci/github-actions/jobs.yml b/src/ci/github-actions/jobs.yml index 0687d142a3504..fd4d6bdb3ba38 100644 --- a/src/ci/github-actions/jobs.yml +++ b/src/ci/github-actions/jobs.yml @@ -426,6 +426,31 @@ auto: DOCKER_SCRIPT: x86_64-gnu-llvm3.sh <<: *job-linux-4c + # The x86_64-gnu-llvm-22 job is split into multiple jobs to run tests in parallel. + # x86_64-gnu-llvm-22-1 skips tests that run in x86_64-gnu-llvm-22-{2,3}. + - name: x86_64-gnu-llvm-22-1 + env: + RUST_BACKTRACE: 1 + IMAGE: x86_64-gnu-llvm-22 + DOCKER_SCRIPT: stage_2_test_set2.sh + <<: *job-linux-4c + + # Skip tests that run in x86_64-gnu-llvm-22-{1,3} + - name: x86_64-gnu-llvm-22-2 + env: + RUST_BACKTRACE: 1 + IMAGE: x86_64-gnu-llvm-22 + DOCKER_SCRIPT: x86_64-gnu-llvm2.sh + <<: *job-linux-4c + + # Skip tests that run in x86_64-gnu-llvm-22-{1,2} + - name: x86_64-gnu-llvm-22-3 + env: + RUST_BACKTRACE: 1 + IMAGE: x86_64-gnu-llvm-22 + DOCKER_SCRIPT: x86_64-gnu-llvm3.sh + <<: *job-linux-4c + - name: x86_64-gnu-nopt <<: *job-linux-4c From b3b6627dbb183c9b3012f13ca1775eeaa92b3193 Mon Sep 17 00:00:00 2001 From: Daniel Scherzer Date: Thu, 12 Mar 2026 19:55:48 -0700 Subject: [PATCH 06/22] Derive Macro Eq: link to more detailed documentation Match the other derive macros in the module (Ord, PartialEq, PartialOrd) by linking to the section in the trait documentation about how the derive macro works. --- 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 b3dc435dda176..49d7487c2803b 100644 --- a/library/core/src/cmp.rs +++ b/library/core/src/cmp.rs @@ -357,6 +357,7 @@ pub const trait Eq: [const] PartialEq + PointeeSized { } /// Derive macro generating an impl of the trait [`Eq`]. +/// The behavior of this macro is described in detail [here](Eq#derivable). #[rustc_builtin_macro] #[stable(feature = "builtin_macro_prelude", since = "1.38.0")] #[allow_internal_unstable(core_intrinsics, derive_eq_internals, structural_match)] From 6e7d6d78217f0311ed37d67ec85119020a1e847d Mon Sep 17 00:00:00 2001 From: Samuel Tardieu Date: Thu, 12 Mar 2026 16:43:36 +0100 Subject: [PATCH 07/22] Add `Wake` diagnostic item for `alloc::task::Wake` --- 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 aa1901314e37c..bc668f78bf740 100644 --- a/library/alloc/src/task.rs +++ b/library/alloc/src/task.rs @@ -87,6 +87,7 @@ use crate::sync::Arc; /// ``` #[cfg(target_has_atomic = "ptr")] #[stable(feature = "wake_trait", since = "1.51.0")] +#[rustc_diagnostic_item = "Wake"] pub trait Wake { /// Wake this task. #[stable(feature = "wake_trait", since = "1.51.0")] From 02ac1909090fa115fef35fa454cdad80839d19f0 Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Sat, 31 Jan 2026 02:10:07 -0600 Subject: [PATCH 08/22] dec2flt: Rename `Integer` to `Int` This is more consistent with what the trait is called elsewhere in tree (specifically compiler-builtins and test-float-parse). --- library/core/src/num/imp/dec2flt/float.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/library/core/src/num/imp/dec2flt/float.rs b/library/core/src/num/imp/dec2flt/float.rs index 21aabdc8addb4..1ccc50fde5904 100644 --- a/library/core/src/num/imp/dec2flt/float.rs +++ b/library/core/src/num/imp/dec2flt/float.rs @@ -12,7 +12,7 @@ pub trait CastInto: Copy { } /// Collection of traits that allow us to be generic over integer size. -pub trait Integer: +pub trait Int: Sized + Clone + Copy @@ -37,7 +37,7 @@ macro_rules! int { } } - impl Integer for $ty { + impl Int for $ty { const ZERO: Self = 0; const ONE: Self = 1; } @@ -68,7 +68,7 @@ pub trait RawFloat: + Debug { /// The unsigned integer with the same size as the float - type Int: Integer + Into; + type Int: Int + Into; /* general constants */ From b07c0439a4d2da5c67ab50ceff6415071049a474 Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Sat, 31 Jan 2026 02:57:22 -0600 Subject: [PATCH 09/22] dec2flt: Split up the `RawFloat` trait `RawFloat` is currently used specifically for the implementation of the lemire algorithm, but it is useful for more than that. Split it into three different traits: * `Float`: Anything that is reasonably applicable to all floating point types. * `FloatExt`: Items that should be part of `Float` but don't work for all float types. This will eventually be merged back into `Float`. * `Lemire`: Items that are specific to the Lemire algorithm. --- library/core/src/num/imp/dec2flt/decimal.rs | 9 +- library/core/src/num/imp/dec2flt/float.rs | 161 ++++++++++-------- library/core/src/num/imp/dec2flt/lemire.rs | 4 +- library/core/src/num/imp/dec2flt/mod.rs | 6 +- library/core/src/num/imp/dec2flt/parse.rs | 4 +- library/core/src/num/imp/dec2flt/slow.rs | 4 +- library/core/src/num/imp/flt2dec/decoder.rs | 4 +- library/coretests/tests/num/dec2flt/float.rs | 95 ++++++----- library/coretests/tests/num/dec2flt/lemire.rs | 2 +- 9 files changed, 156 insertions(+), 133 deletions(-) diff --git a/library/core/src/num/imp/dec2flt/decimal.rs b/library/core/src/num/imp/dec2flt/decimal.rs index 27a53d4b9e75b..583f6bcf3302c 100644 --- a/library/core/src/num/imp/dec2flt/decimal.rs +++ b/library/core/src/num/imp/dec2flt/decimal.rs @@ -1,9 +1,8 @@ //! Representation of a float as the significant digits and exponent. -use dec2flt::float::RawFloat; -use dec2flt::fpu::set_precision; - use crate::num::imp::dec2flt; +use dec2flt::float::Lemire; +use dec2flt::fpu::set_precision; const INT_POW10: [u64; 16] = [ 1, @@ -36,7 +35,7 @@ pub struct Decimal { impl Decimal { /// Detect if the float can be accurately reconstructed from native floats. #[inline] - fn can_use_fast_path(&self) -> bool { + fn can_use_fast_path(&self) -> bool { F::MIN_EXPONENT_FAST_PATH <= self.exponent && self.exponent <= F::MAX_EXPONENT_DISGUISED_FAST_PATH && self.mantissa <= F::MAX_MANTISSA_FAST_PATH @@ -53,7 +52,7 @@ impl Decimal { /// /// There is an exception: disguised fast-path cases, where we can shift /// powers-of-10 from the exponent to the significant digits. - pub fn try_fast_path(&self) -> Option { + pub fn try_fast_path(&self) -> Option { // Here we need to work around . // The fast path crucially depends on arithmetic being rounded to the correct number of bits // without any intermediate rounding. On x86 (without SSE or SSE2) this requires the precision diff --git a/library/core/src/num/imp/dec2flt/float.rs b/library/core/src/num/imp/dec2flt/float.rs index 1ccc50fde5904..da581a457f495 100644 --- a/library/core/src/num/imp/dec2flt/float.rs +++ b/library/core/src/num/imp/dec2flt/float.rs @@ -48,12 +48,8 @@ macro_rules! int { int!(u16, u32, u64); /// A helper trait to avoid duplicating basically all the conversion code for IEEE floats. -/// -/// See the parent module's doc comment for why this is necessary. -/// -/// Should **never ever** be implemented for other types or be used outside the `dec2flt` module. #[doc(hidden)] -pub trait RawFloat: +pub trait Float: Sized + Div + Neg @@ -128,8 +124,6 @@ pub trait RawFloat: const MIN_EXPONENT_ROUND_TO_EVEN: i32; const MAX_EXPONENT_ROUND_TO_EVEN: i32; - /* limits related to Fast pathing */ - /// Largest decimal exponent for a non-infinite value. /// /// This is the max exponent in binary converted to the max exponent in decimal. Allows fast @@ -151,41 +145,19 @@ pub trait RawFloat: /// compile time since intermediates exceed the range of an `f64`. const SMALLEST_POWER_OF_TEN: i32; - /// Maximum exponent for a fast path case, or `⌊(SIG_BITS+1)/log2(5)⌋` - // assuming FLT_EVAL_METHOD = 0 - const MAX_EXPONENT_FAST_PATH: i64 = { - let log2_5 = f64::consts::LOG2_10 - 1.0; - (Self::SIG_TOTAL_BITS as f64 / log2_5) as i64 - }; - - /// Minimum exponent for a fast path case, or `-⌊(SIG_BITS+1)/log2(5)⌋` - const MIN_EXPONENT_FAST_PATH: i64 = -Self::MAX_EXPONENT_FAST_PATH; - - /// Maximum exponent that can be represented for a disguised-fast path case. - /// This is `MAX_EXPONENT_FAST_PATH + ⌊(SIG_BITS+1)/log2(10)⌋` - const MAX_EXPONENT_DISGUISED_FAST_PATH: i64 = - Self::MAX_EXPONENT_FAST_PATH + (Self::SIG_TOTAL_BITS as f64 / f64::consts::LOG2_10) as i64; - - /// Maximum mantissa for the fast-path (`1 << 53` for f64). - const MAX_MANTISSA_FAST_PATH: u64 = 1 << Self::SIG_TOTAL_BITS; - - /// Converts integer into float through an as cast. - /// This is only called in the fast-path algorithm, and therefore - /// will not lose precision, since the value will always have - /// only if the value is <= Self::MAX_MANTISSA_FAST_PATH. - fn from_u64(v: u64) -> Self; - - /// Performs a raw transmutation from an integer. - fn from_u64_bits(v: u64) -> Self; - - /// Gets a small power-of-ten for fast-path multiplication. - fn pow10_fast_path(exponent: usize) -> Self; - /// Returns the category that this number falls into. fn classify(self) -> FpCategory; /// Transmute to the integer representation fn to_bits(self) -> Self::Int; +} + +/// Items that ideally would be on `Float`, but don't apply to all float types because they +/// rely on the mantissa fitting into a `u64` (which isn't true for `f128`). +#[doc(hidden)] +pub trait FloatExt: Float { + /// Performs a raw transmutation from an integer. + fn from_u64_bits(v: u64) -> Self; /// Returns the mantissa, exponent and sign as integers. /// @@ -212,6 +184,41 @@ pub trait RawFloat: } } +/// Extension to `Float` that are necessary for parsing using the Lemire method. +/// +/// See the parent module's doc comment for why this is necessary. +/// +/// Not intended for use outside of the `dec2flt` module. +#[doc(hidden)] +pub trait Lemire: FloatExt { + /// Maximum exponent for a fast path case, or `⌊(SIG_BITS+1)/log2(5)⌋` + // assuming FLT_EVAL_METHOD = 0 + const MAX_EXPONENT_FAST_PATH: i64 = { + let log2_5 = f64::consts::LOG2_10 - 1.0; + (Self::SIG_TOTAL_BITS as f64 / log2_5) as i64 + }; + + /// Minimum exponent for a fast path case, or `-⌊(SIG_BITS+1)/log2(5)⌋` + const MIN_EXPONENT_FAST_PATH: i64 = -Self::MAX_EXPONENT_FAST_PATH; + + /// Maximum exponent that can be represented for a disguised-fast path case. + /// This is `MAX_EXPONENT_FAST_PATH + ⌊(SIG_BITS+1)/log2(10)⌋` + const MAX_EXPONENT_DISGUISED_FAST_PATH: i64 = + Self::MAX_EXPONENT_FAST_PATH + (Self::SIG_TOTAL_BITS as f64 / f64::consts::LOG2_10) as i64; + + /// Maximum mantissa for the fast-path (`1 << 53` for f64). + const MAX_MANTISSA_FAST_PATH: u64 = 1 << Self::SIG_TOTAL_BITS; + + /// Gets a small power-of-ten for fast-path multiplication. + fn pow10_fast_path(exponent: usize) -> Self; + + /// Converts integer into float through an as cast. + /// This is only called in the fast-path algorithm, and therefore + /// will not lose precision, since the value will always have + /// only if the value is <= Self::MAX_MANTISSA_FAST_PATH. + fn from_u64(v: u64) -> Self; +} + /// Solve for `b` in `10^b = 2^a` const fn pow2_to_pow10(a: i64) -> i64 { let res = (a as f64) / f64::consts::LOG2_10; @@ -219,7 +226,7 @@ const fn pow2_to_pow10(a: i64) -> i64 { } #[cfg(target_has_reliable_f16)] -impl RawFloat for f16 { +impl Float for f16 { type Int = u16; const INFINITY: Self = Self::INFINITY; @@ -236,33 +243,39 @@ impl RawFloat for f16 { const MAX_EXPONENT_ROUND_TO_EVEN: i32 = 5; const SMALLEST_POWER_OF_TEN: i32 = -27; - #[inline] - fn from_u64(v: u64) -> Self { - debug_assert!(v <= Self::MAX_MANTISSA_FAST_PATH); - v as _ + fn to_bits(self) -> Self::Int { + self.to_bits() + } + + fn classify(self) -> FpCategory { + self.classify() } +} +#[cfg(target_has_reliable_f16)] +impl FloatExt for f16 { #[inline] fn from_u64_bits(v: u64) -> Self { Self::from_bits((v & 0xFFFF) as u16) } +} +#[cfg(target_has_reliable_f16)] +impl Lemire for f16 { fn pow10_fast_path(exponent: usize) -> Self { #[allow(clippy::use_self)] const TABLE: [f16; 8] = [1e0, 1e1, 1e2, 1e3, 1e4, 0.0, 0.0, 0.]; TABLE[exponent & 7] } - fn to_bits(self) -> Self::Int { - self.to_bits() - } - - fn classify(self) -> FpCategory { - self.classify() + #[inline] + fn from_u64(v: u64) -> Self { + debug_assert!(v <= Self::MAX_MANTISSA_FAST_PATH); + v as _ } } -impl RawFloat for f32 { +impl Float for f32 { type Int = u32; const INFINITY: Self = f32::INFINITY; @@ -279,17 +292,23 @@ impl RawFloat for f32 { const MAX_EXPONENT_ROUND_TO_EVEN: i32 = 10; const SMALLEST_POWER_OF_TEN: i32 = -65; - #[inline] - fn from_u64(v: u64) -> Self { - debug_assert!(v <= Self::MAX_MANTISSA_FAST_PATH); - v as _ + fn to_bits(self) -> Self::Int { + self.to_bits() } + fn classify(self) -> FpCategory { + self.classify() + } +} + +impl FloatExt for f32 { #[inline] fn from_u64_bits(v: u64) -> Self { f32::from_bits((v & 0xFFFFFFFF) as u32) } +} +impl Lemire for f32 { fn pow10_fast_path(exponent: usize) -> Self { #[allow(clippy::use_self)] const TABLE: [f32; 16] = @@ -297,16 +316,14 @@ impl RawFloat for f32 { TABLE[exponent & 15] } - fn to_bits(self) -> Self::Int { - self.to_bits() - } - - fn classify(self) -> FpCategory { - self.classify() + #[inline] + fn from_u64(v: u64) -> Self { + debug_assert!(v <= Self::MAX_MANTISSA_FAST_PATH); + v as _ } } -impl RawFloat for f64 { +impl Float for f64 { type Int = u64; const INFINITY: Self = Self::INFINITY; @@ -323,17 +340,23 @@ impl RawFloat for f64 { const MAX_EXPONENT_ROUND_TO_EVEN: i32 = 23; const SMALLEST_POWER_OF_TEN: i32 = -342; - #[inline] - fn from_u64(v: u64) -> Self { - debug_assert!(v <= Self::MAX_MANTISSA_FAST_PATH); - v as _ + fn to_bits(self) -> Self::Int { + self.to_bits() } + fn classify(self) -> FpCategory { + self.classify() + } +} + +impl FloatExt for f64 { #[inline] fn from_u64_bits(v: u64) -> Self { f64::from_bits(v) } +} +impl Lemire for f64 { fn pow10_fast_path(exponent: usize) -> Self { const TABLE: [f64; 32] = [ 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, @@ -342,11 +365,9 @@ impl RawFloat for f64 { TABLE[exponent & 31] } - fn to_bits(self) -> Self::Int { - self.to_bits() - } - - fn classify(self) -> FpCategory { - self.classify() + #[inline] + fn from_u64(v: u64) -> Self { + debug_assert!(v <= Self::MAX_MANTISSA_FAST_PATH); + v as _ } } diff --git a/library/core/src/num/imp/dec2flt/lemire.rs b/library/core/src/num/imp/dec2flt/lemire.rs index c3f2723509d05..8a97618cf7385 100644 --- a/library/core/src/num/imp/dec2flt/lemire.rs +++ b/library/core/src/num/imp/dec2flt/lemire.rs @@ -1,7 +1,7 @@ //! Implementation of the Eisel-Lemire algorithm. use dec2flt::common::BiasedFp; -use dec2flt::float::RawFloat; +use dec2flt::float::Float; use dec2flt::table::{LARGEST_POWER_OF_FIVE, POWER_OF_FIVE_128, SMALLEST_POWER_OF_FIVE}; use crate::num::imp::dec2flt; @@ -24,7 +24,7 @@ use crate::num::imp::dec2flt; /// at a Gigabyte per Second" in section 5, "Fast Algorithm", and /// section 6, "Exact Numbers And Ties", available online: /// . -pub fn compute_float(q: i64, mut w: u64) -> BiasedFp { +pub fn compute_float(q: i64, mut w: u64) -> BiasedFp { let fp_zero = BiasedFp::zero_pow2(0); let fp_inf = BiasedFp::zero_pow2(F::INFINITE_POWER); let fp_error = BiasedFp::zero_pow2(-1); diff --git a/library/core/src/num/imp/dec2flt/mod.rs b/library/core/src/num/imp/dec2flt/mod.rs index 3f5724add62bb..33e606694bc3e 100644 --- a/library/core/src/num/imp/dec2flt/mod.rs +++ b/library/core/src/num/imp/dec2flt/mod.rs @@ -88,7 +88,7 @@ )] use common::BiasedFp; -use float::RawFloat; +use float::{FloatExt, Lemire}; use lemire::compute_float; use parse::{parse_inf_nan, parse_number}; use slow::parse_long_mantissa; @@ -120,7 +120,7 @@ pub fn pfe_invalid() -> ParseFloatError { } /// Converts a `BiasedFp` to the closest machine float type. -fn biased_fp_to_float(x: BiasedFp) -> F { +fn biased_fp_to_float(x: BiasedFp) -> F { let mut word = x.m; word |= (x.p_biased as u64) << F::SIG_BITS; F::from_u64_bits(word) @@ -128,7 +128,7 @@ fn biased_fp_to_float(x: BiasedFp) -> F { /// Converts a decimal string into a floating point number. #[inline(always)] // Will be inlined into a function with `#[inline(never)]`, see above -pub fn dec2flt(s: &str) -> Result { +pub fn dec2flt(s: &str) -> Result { let mut s = s.as_bytes(); let Some(&c) = s.first() else { return Err(pfe_empty()) }; let negative = c == b'-'; diff --git a/library/core/src/num/imp/dec2flt/parse.rs b/library/core/src/num/imp/dec2flt/parse.rs index e4049bc164c61..e4e3e5bc0c0e3 100644 --- a/library/core/src/num/imp/dec2flt/parse.rs +++ b/library/core/src/num/imp/dec2flt/parse.rs @@ -2,7 +2,7 @@ use dec2flt::common::{ByteSlice, is_8digits}; use dec2flt::decimal::Decimal; -use dec2flt::float::RawFloat; +use dec2flt::float::Float; use crate::num::imp::dec2flt; @@ -197,7 +197,7 @@ pub fn parse_number(s: &[u8]) -> Option { } /// Try to parse a special, non-finite float. -pub(crate) fn parse_inf_nan(s: &[u8], negative: bool) -> Option { +pub(crate) fn parse_inf_nan(s: &[u8], negative: bool) -> Option { // Since a valid string has at most the length 8, we can load // all relevant characters into a u64 and work from there. // This also generates much better code. diff --git a/library/core/src/num/imp/dec2flt/slow.rs b/library/core/src/num/imp/dec2flt/slow.rs index 089b12f5be22e..784f3e00f5b48 100644 --- a/library/core/src/num/imp/dec2flt/slow.rs +++ b/library/core/src/num/imp/dec2flt/slow.rs @@ -2,7 +2,7 @@ use dec2flt::common::BiasedFp; use dec2flt::decimal_seq::{DecimalSeq, parse_decimal_seq}; -use dec2flt::float::RawFloat; +use dec2flt::float::Float; use crate::num::imp::dec2flt; @@ -25,7 +25,7 @@ use crate::num::imp::dec2flt; /// /// The algorithms described here are based on "Processing Long Numbers Quickly", /// available here: . -pub(crate) fn parse_long_mantissa(s: &[u8]) -> BiasedFp { +pub(crate) fn parse_long_mantissa(s: &[u8]) -> BiasedFp { const MAX_SHIFT: usize = 60; const NUM_POWERS: usize = 19; const POWERS: [u8; 19] = diff --git a/library/core/src/num/imp/flt2dec/decoder.rs b/library/core/src/num/imp/flt2dec/decoder.rs index 3d6ad6608efe3..6f8fb2b954f3a 100644 --- a/library/core/src/num/imp/flt2dec/decoder.rs +++ b/library/core/src/num/imp/flt2dec/decoder.rs @@ -1,7 +1,7 @@ //! Decodes a floating-point value into individual parts and error ranges. use crate::num::FpCategory; -use crate::num::imp::dec2flt::float::RawFloat; +use crate::num::imp::dec2flt::float::FloatExt; /// Decoded unsigned finite value, such that: /// @@ -40,7 +40,7 @@ pub enum FullDecoded { } /// A floating point type which can be `decode`d. -pub trait DecodableFloat: RawFloat + Copy { +pub trait DecodableFloat: FloatExt + Copy { /// The minimum positive normalized value. fn min_pos_norm_value() -> Self; } diff --git a/library/coretests/tests/num/dec2flt/float.rs b/library/coretests/tests/num/dec2flt/float.rs index 25e12435b4728..aa4c59dd66ea0 100644 --- a/library/coretests/tests/num/dec2flt/float.rs +++ b/library/coretests/tests/num/dec2flt/float.rs @@ -1,4 +1,4 @@ -use core::num::imp::dec2flt::float::RawFloat; +use core::num::imp::dec2flt::float::{Float, FloatExt, Lemire}; use crate::num::{ldexp_f32, ldexp_f64}; @@ -56,57 +56,60 @@ fn test_f64_integer_decode() { #[test] #[cfg(target_has_reliable_f16)] fn test_f16_consts() { - assert_eq!(::INFINITY, f16::INFINITY); - assert_eq!(::NEG_INFINITY, -f16::INFINITY); - assert_eq!(::NAN.to_bits(), f16::NAN.to_bits()); - assert_eq!(::NEG_NAN.to_bits(), (-f16::NAN).to_bits()); - assert_eq!(::SIG_BITS, 10); - assert_eq!(::MIN_EXPONENT_ROUND_TO_EVEN, -22); - assert_eq!(::MAX_EXPONENT_ROUND_TO_EVEN, 5); - assert_eq!(::MIN_EXPONENT_FAST_PATH, -4); - assert_eq!(::MAX_EXPONENT_FAST_PATH, 4); - assert_eq!(::MAX_EXPONENT_DISGUISED_FAST_PATH, 7); - assert_eq!(::EXP_MIN, -14); - assert_eq!(::EXP_SAT, 0x1f); - assert_eq!(::SMALLEST_POWER_OF_TEN, -27); - assert_eq!(::LARGEST_POWER_OF_TEN, 4); - assert_eq!(::MAX_MANTISSA_FAST_PATH, 2048); + assert_eq!(::INFINITY, f16::INFINITY); + assert_eq!(::NEG_INFINITY, -f16::INFINITY); + assert_eq!(::NAN.to_bits(), f16::NAN.to_bits()); + assert_eq!(::NEG_NAN.to_bits(), (-f16::NAN).to_bits()); + assert_eq!(::SIG_BITS, 10); + assert_eq!(::MIN_EXPONENT_ROUND_TO_EVEN, -22); + assert_eq!(::MAX_EXPONENT_ROUND_TO_EVEN, 5); + assert_eq!(::EXP_MIN, -14); + assert_eq!(::EXP_SAT, 0x1f); + assert_eq!(::SMALLEST_POWER_OF_TEN, -27); + assert_eq!(::LARGEST_POWER_OF_TEN, 4); + + assert_eq!(::MIN_EXPONENT_FAST_PATH, -4); + assert_eq!(::MAX_EXPONENT_FAST_PATH, 4); + assert_eq!(::MAX_EXPONENT_DISGUISED_FAST_PATH, 7); + assert_eq!(::MAX_MANTISSA_FAST_PATH, 2048); } #[test] fn test_f32_consts() { - assert_eq!(::INFINITY, f32::INFINITY); - assert_eq!(::NEG_INFINITY, -f32::INFINITY); - assert_eq!(::NAN.to_bits(), f32::NAN.to_bits()); - assert_eq!(::NEG_NAN.to_bits(), (-f32::NAN).to_bits()); - assert_eq!(::SIG_BITS, 23); - assert_eq!(::MIN_EXPONENT_ROUND_TO_EVEN, -17); - assert_eq!(::MAX_EXPONENT_ROUND_TO_EVEN, 10); - assert_eq!(::MIN_EXPONENT_FAST_PATH, -10); - assert_eq!(::MAX_EXPONENT_FAST_PATH, 10); - assert_eq!(::MAX_EXPONENT_DISGUISED_FAST_PATH, 17); - assert_eq!(::EXP_MIN, -126); - assert_eq!(::EXP_SAT, 0xff); - assert_eq!(::SMALLEST_POWER_OF_TEN, -65); - assert_eq!(::LARGEST_POWER_OF_TEN, 38); - assert_eq!(::MAX_MANTISSA_FAST_PATH, 16777216); + assert_eq!(::INFINITY, f32::INFINITY); + assert_eq!(::NEG_INFINITY, -f32::INFINITY); + assert_eq!(::NAN.to_bits(), f32::NAN.to_bits()); + assert_eq!(::NEG_NAN.to_bits(), (-f32::NAN).to_bits()); + assert_eq!(::SIG_BITS, 23); + assert_eq!(::MIN_EXPONENT_ROUND_TO_EVEN, -17); + assert_eq!(::MAX_EXPONENT_ROUND_TO_EVEN, 10); + assert_eq!(::EXP_MIN, -126); + assert_eq!(::EXP_SAT, 0xff); + assert_eq!(::SMALLEST_POWER_OF_TEN, -65); + assert_eq!(::LARGEST_POWER_OF_TEN, 38); + + assert_eq!(::MIN_EXPONENT_FAST_PATH, -10); + assert_eq!(::MAX_EXPONENT_FAST_PATH, 10); + assert_eq!(::MAX_EXPONENT_DISGUISED_FAST_PATH, 17); + assert_eq!(::MAX_MANTISSA_FAST_PATH, 16777216); } #[test] fn test_f64_consts() { - assert_eq!(::INFINITY, f64::INFINITY); - assert_eq!(::NEG_INFINITY, -f64::INFINITY); - assert_eq!(::NAN.to_bits(), f64::NAN.to_bits()); - assert_eq!(::NEG_NAN.to_bits(), (-f64::NAN).to_bits()); - assert_eq!(::SIG_BITS, 52); - assert_eq!(::MIN_EXPONENT_ROUND_TO_EVEN, -4); - assert_eq!(::MAX_EXPONENT_ROUND_TO_EVEN, 23); - assert_eq!(::MIN_EXPONENT_FAST_PATH, -22); - assert_eq!(::MAX_EXPONENT_FAST_PATH, 22); - assert_eq!(::MAX_EXPONENT_DISGUISED_FAST_PATH, 37); - assert_eq!(::EXP_MIN, -1022); - assert_eq!(::EXP_SAT, 0x7ff); - assert_eq!(::SMALLEST_POWER_OF_TEN, -342); - assert_eq!(::LARGEST_POWER_OF_TEN, 308); - assert_eq!(::MAX_MANTISSA_FAST_PATH, 9007199254740992); + assert_eq!(::INFINITY, f64::INFINITY); + assert_eq!(::NEG_INFINITY, -f64::INFINITY); + assert_eq!(::NAN.to_bits(), f64::NAN.to_bits()); + assert_eq!(::NEG_NAN.to_bits(), (-f64::NAN).to_bits()); + assert_eq!(::SIG_BITS, 52); + assert_eq!(::MIN_EXPONENT_ROUND_TO_EVEN, -4); + assert_eq!(::MAX_EXPONENT_ROUND_TO_EVEN, 23); + assert_eq!(::EXP_MIN, -1022); + assert_eq!(::EXP_SAT, 0x7ff); + assert_eq!(::SMALLEST_POWER_OF_TEN, -342); + assert_eq!(::LARGEST_POWER_OF_TEN, 308); + + assert_eq!(::MIN_EXPONENT_FAST_PATH, -22); + assert_eq!(::MAX_EXPONENT_FAST_PATH, 22); + assert_eq!(::MAX_EXPONENT_DISGUISED_FAST_PATH, 37); + assert_eq!(::MAX_MANTISSA_FAST_PATH, 9007199254740992); } diff --git a/library/coretests/tests/num/dec2flt/lemire.rs b/library/coretests/tests/num/dec2flt/lemire.rs index e4ce533ba44da..6679dca148aa6 100644 --- a/library/coretests/tests/num/dec2flt/lemire.rs +++ b/library/coretests/tests/num/dec2flt/lemire.rs @@ -1,6 +1,6 @@ use core::num::imp::dec2flt; -use dec2flt::float::RawFloat; +use dec2flt::float::Float; use dec2flt::lemire::compute_float; #[cfg(target_has_reliable_f16)] From bec94a33d541667abb706e8bab4dc791e64e87cc Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Sat, 31 Jan 2026 03:13:08 -0600 Subject: [PATCH 10/22] dec2flt: Move internal traits to better locations `Float` and `FloatExt` are already used by both parsing and printing, so move them out of `dec2flt` to a new module in `num::imp`. `Int` `Cast` have the potential to be used more places in the future, so move them there as well. `Lemire` is the only remaining trait; since it is small, move it into the `dec2flt` root. The `fmt::LowerExp` bound is removed from `Float` here since the trait is moving into a module without `#[cfg(not(no_fp_fmt_parse))]` and it isn't implemented with that config (it's not easily possible to add `cfg` attributes to a single supertrait, unfortunately). This isn't a problem since it isn't actually being used. --- library/core/src/num/imp/dec2flt/decimal.rs | 5 +- library/core/src/num/imp/dec2flt/lemire.rs | 3 +- library/core/src/num/imp/dec2flt/mod.rs | 90 ++++++++++++++- library/core/src/num/imp/dec2flt/parse.rs | 3 +- library/core/src/num/imp/dec2flt/slow.rs | 3 +- library/core/src/num/imp/flt2dec/decoder.rs | 2 +- library/core/src/num/imp/mod.rs | 3 + .../num/imp/{dec2flt/float.rs => traits.rs} | 106 +++--------------- library/coretests/tests/lib.rs | 1 + library/coretests/tests/num/dec2flt/float.rs | 3 +- library/coretests/tests/num/dec2flt/lemire.rs | 3 +- 11 files changed, 113 insertions(+), 109 deletions(-) rename library/core/src/num/imp/{dec2flt/float.rs => traits.rs} (74%) diff --git a/library/core/src/num/imp/dec2flt/decimal.rs b/library/core/src/num/imp/dec2flt/decimal.rs index 583f6bcf3302c..c9b0cc531b386 100644 --- a/library/core/src/num/imp/dec2flt/decimal.rs +++ b/library/core/src/num/imp/dec2flt/decimal.rs @@ -1,9 +1,10 @@ //! Representation of a float as the significant digits and exponent. -use crate::num::imp::dec2flt; -use dec2flt::float::Lemire; +use dec2flt::Lemire; use dec2flt::fpu::set_precision; +use crate::num::imp::dec2flt; + const INT_POW10: [u64; 16] = [ 1, 10, diff --git a/library/core/src/num/imp/dec2flt/lemire.rs b/library/core/src/num/imp/dec2flt/lemire.rs index 8a97618cf7385..f89d16c843477 100644 --- a/library/core/src/num/imp/dec2flt/lemire.rs +++ b/library/core/src/num/imp/dec2flt/lemire.rs @@ -1,10 +1,9 @@ //! Implementation of the Eisel-Lemire algorithm. use dec2flt::common::BiasedFp; -use dec2flt::float::Float; use dec2flt::table::{LARGEST_POWER_OF_FIVE, POWER_OF_FIVE_128, SMALLEST_POWER_OF_FIVE}; -use crate::num::imp::dec2flt; +use crate::num::imp::{Float, dec2flt}; /// Compute w * 10^q using an extended-precision float representation. /// diff --git a/library/core/src/num/imp/dec2flt/mod.rs b/library/core/src/num/imp/dec2flt/mod.rs index 33e606694bc3e..76b8d416ee0f1 100644 --- a/library/core/src/num/imp/dec2flt/mod.rs +++ b/library/core/src/num/imp/dec2flt/mod.rs @@ -88,24 +88,104 @@ )] use common::BiasedFp; -use float::{FloatExt, Lemire}; use lemire::compute_float; use parse::{parse_inf_nan, parse_number}; use slow::parse_long_mantissa; +use crate::f64; use crate::num::ParseFloatError; use crate::num::float_parse::FloatErrorKind; +use crate::num::imp::FloatExt; mod common; pub mod decimal; pub mod decimal_seq; mod fpu; -mod slow; -mod table; -// float is used in flt2dec, and all are used in unit tests. -pub mod float; pub mod lemire; pub mod parse; +mod slow; +mod table; + +/// Extension to `Float` that are necessary for parsing using the Lemire method. +/// +/// See the parent module's doc comment for why this is necessary. +/// +/// Not intended for use outside of the `dec2flt` module. +#[doc(hidden)] +pub trait Lemire: FloatExt { + /// Maximum exponent for a fast path case, or `⌊(SIG_BITS+1)/log2(5)⌋` + // assuming FLT_EVAL_METHOD = 0 + const MAX_EXPONENT_FAST_PATH: i64 = { + let log2_5 = f64::consts::LOG2_10 - 1.0; + (Self::SIG_TOTAL_BITS as f64 / log2_5) as i64 + }; + + /// Minimum exponent for a fast path case, or `-⌊(SIG_BITS+1)/log2(5)⌋` + const MIN_EXPONENT_FAST_PATH: i64 = -Self::MAX_EXPONENT_FAST_PATH; + + /// Maximum exponent that can be represented for a disguised-fast path case. + /// This is `MAX_EXPONENT_FAST_PATH + ⌊(SIG_BITS+1)/log2(10)⌋` + const MAX_EXPONENT_DISGUISED_FAST_PATH: i64 = + Self::MAX_EXPONENT_FAST_PATH + (Self::SIG_TOTAL_BITS as f64 / f64::consts::LOG2_10) as i64; + + /// Maximum mantissa for the fast-path (`1 << 53` for f64). + const MAX_MANTISSA_FAST_PATH: u64 = 1 << Self::SIG_TOTAL_BITS; + + /// Gets a small power-of-ten for fast-path multiplication. + fn pow10_fast_path(exponent: usize) -> Self; + + /// Converts integer into float through an as cast. + /// This is only called in the fast-path algorithm, and therefore + /// will not lose precision, since the value will always have + /// only if the value is <= Self::MAX_MANTISSA_FAST_PATH. + fn from_u64(v: u64) -> Self; +} + +#[cfg(target_has_reliable_f16)] +impl Lemire for f16 { + fn pow10_fast_path(exponent: usize) -> Self { + #[allow(clippy::use_self)] + const TABLE: [f16; 8] = [1e0, 1e1, 1e2, 1e3, 1e4, 0.0, 0.0, 0.]; + TABLE[exponent & 7] + } + + #[inline] + fn from_u64(v: u64) -> Self { + debug_assert!(v <= Self::MAX_MANTISSA_FAST_PATH); + v as _ + } +} + +impl Lemire for f32 { + fn pow10_fast_path(exponent: usize) -> Self { + #[allow(clippy::use_self)] + const TABLE: [f32; 16] = + [1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10, 0., 0., 0., 0., 0.]; + TABLE[exponent & 15] + } + + #[inline] + fn from_u64(v: u64) -> Self { + debug_assert!(v <= Self::MAX_MANTISSA_FAST_PATH); + v as _ + } +} + +impl Lemire for f64 { + fn pow10_fast_path(exponent: usize) -> Self { + const TABLE: [f64; 32] = [ + 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, + 1e16, 1e17, 1e18, 1e19, 1e20, 1e21, 1e22, 0., 0., 0., 0., 0., 0., 0., 0., 0., + ]; + TABLE[exponent & 31] + } + + #[inline] + fn from_u64(v: u64) -> Self { + debug_assert!(v <= Self::MAX_MANTISSA_FAST_PATH); + v as _ + } +} #[inline] pub(super) fn pfe_empty() -> ParseFloatError { diff --git a/library/core/src/num/imp/dec2flt/parse.rs b/library/core/src/num/imp/dec2flt/parse.rs index e4e3e5bc0c0e3..ee55eadbc7b9e 100644 --- a/library/core/src/num/imp/dec2flt/parse.rs +++ b/library/core/src/num/imp/dec2flt/parse.rs @@ -2,9 +2,8 @@ use dec2flt::common::{ByteSlice, is_8digits}; use dec2flt::decimal::Decimal; -use dec2flt::float::Float; -use crate::num::imp::dec2flt; +use crate::num::imp::{Float, dec2flt}; const MIN_19DIGIT_INT: u64 = 100_0000_0000_0000_0000; diff --git a/library/core/src/num/imp/dec2flt/slow.rs b/library/core/src/num/imp/dec2flt/slow.rs index 784f3e00f5b48..f1b2525cf38e6 100644 --- a/library/core/src/num/imp/dec2flt/slow.rs +++ b/library/core/src/num/imp/dec2flt/slow.rs @@ -2,9 +2,8 @@ use dec2flt::common::BiasedFp; use dec2flt::decimal_seq::{DecimalSeq, parse_decimal_seq}; -use dec2flt::float::Float; -use crate::num::imp::dec2flt; +use crate::num::imp::{Float, dec2flt}; /// Parse the significant digits and biased, binary exponent of a float. /// diff --git a/library/core/src/num/imp/flt2dec/decoder.rs b/library/core/src/num/imp/flt2dec/decoder.rs index 6f8fb2b954f3a..5ccc91f4c9faf 100644 --- a/library/core/src/num/imp/flt2dec/decoder.rs +++ b/library/core/src/num/imp/flt2dec/decoder.rs @@ -1,7 +1,7 @@ //! Decodes a floating-point value into individual parts and error ranges. use crate::num::FpCategory; -use crate::num::imp::dec2flt::float::FloatExt; +use crate::num::imp::FloatExt; /// Decoded unsigned finite value, such that: /// diff --git a/library/core/src/num/imp/mod.rs b/library/core/src/num/imp/mod.rs index d35409f91bde9..6fccfd1c238ed 100644 --- a/library/core/src/num/imp/mod.rs +++ b/library/core/src/num/imp/mod.rs @@ -16,3 +16,6 @@ pub(crate) mod int_log10; pub(crate) mod int_sqrt; pub(crate) mod libm; pub(crate) mod overflow_panic; +mod traits; + +pub use traits::{Float, FloatExt, Int}; diff --git a/library/core/src/num/imp/dec2flt/float.rs b/library/core/src/num/imp/traits.rs similarity index 74% rename from library/core/src/num/imp/dec2flt/float.rs rename to library/core/src/num/imp/traits.rs index da581a457f495..7b84f7a4a5aa2 100644 --- a/library/core/src/num/imp/dec2flt/float.rs +++ b/library/core/src/num/imp/traits.rs @@ -1,10 +1,14 @@ -//! Helper trait for generic float types. +//! Numeric traits used for internal implementations. -use core::f64; +#![doc(hidden)] +#![unstable( + feature = "num_internals", + reason = "internal routines only exposed for testing", + issue = "none" +)] -use crate::fmt::{Debug, LowerExp}; use crate::num::FpCategory; -use crate::ops::{self, Add, Div, Mul, Neg}; +use crate::{f64, fmt, ops}; /// Lossy `as` casting between two types. pub trait CastInto: Copy { @@ -16,7 +20,7 @@ pub trait Int: Sized + Clone + Copy - + Debug + + fmt::Debug + ops::Shr + ops::Shl + ops::BitAnd @@ -51,17 +55,16 @@ int!(u16, u32, u64); #[doc(hidden)] pub trait Float: Sized - + Div - + Neg - + Mul - + Add - + LowerExp + + ops::Div + + ops::Neg + + ops::Mul + + ops::Add + + fmt::Debug + PartialEq + PartialOrd + Default + Clone + Copy - + Debug { /// The unsigned integer with the same size as the float type Int: Int + Into; @@ -184,41 +187,6 @@ pub trait FloatExt: Float { } } -/// Extension to `Float` that are necessary for parsing using the Lemire method. -/// -/// See the parent module's doc comment for why this is necessary. -/// -/// Not intended for use outside of the `dec2flt` module. -#[doc(hidden)] -pub trait Lemire: FloatExt { - /// Maximum exponent for a fast path case, or `⌊(SIG_BITS+1)/log2(5)⌋` - // assuming FLT_EVAL_METHOD = 0 - const MAX_EXPONENT_FAST_PATH: i64 = { - let log2_5 = f64::consts::LOG2_10 - 1.0; - (Self::SIG_TOTAL_BITS as f64 / log2_5) as i64 - }; - - /// Minimum exponent for a fast path case, or `-⌊(SIG_BITS+1)/log2(5)⌋` - const MIN_EXPONENT_FAST_PATH: i64 = -Self::MAX_EXPONENT_FAST_PATH; - - /// Maximum exponent that can be represented for a disguised-fast path case. - /// This is `MAX_EXPONENT_FAST_PATH + ⌊(SIG_BITS+1)/log2(10)⌋` - const MAX_EXPONENT_DISGUISED_FAST_PATH: i64 = - Self::MAX_EXPONENT_FAST_PATH + (Self::SIG_TOTAL_BITS as f64 / f64::consts::LOG2_10) as i64; - - /// Maximum mantissa for the fast-path (`1 << 53` for f64). - const MAX_MANTISSA_FAST_PATH: u64 = 1 << Self::SIG_TOTAL_BITS; - - /// Gets a small power-of-ten for fast-path multiplication. - fn pow10_fast_path(exponent: usize) -> Self; - - /// Converts integer into float through an as cast. - /// This is only called in the fast-path algorithm, and therefore - /// will not lose precision, since the value will always have - /// only if the value is <= Self::MAX_MANTISSA_FAST_PATH. - fn from_u64(v: u64) -> Self; -} - /// Solve for `b` in `10^b = 2^a` const fn pow2_to_pow10(a: i64) -> i64 { let res = (a as f64) / f64::consts::LOG2_10; @@ -260,21 +228,6 @@ impl FloatExt for f16 { } } -#[cfg(target_has_reliable_f16)] -impl Lemire for f16 { - fn pow10_fast_path(exponent: usize) -> Self { - #[allow(clippy::use_self)] - const TABLE: [f16; 8] = [1e0, 1e1, 1e2, 1e3, 1e4, 0.0, 0.0, 0.]; - TABLE[exponent & 7] - } - - #[inline] - fn from_u64(v: u64) -> Self { - debug_assert!(v <= Self::MAX_MANTISSA_FAST_PATH); - v as _ - } -} - impl Float for f32 { type Int = u32; @@ -308,21 +261,6 @@ impl FloatExt for f32 { } } -impl Lemire for f32 { - fn pow10_fast_path(exponent: usize) -> Self { - #[allow(clippy::use_self)] - const TABLE: [f32; 16] = - [1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10, 0., 0., 0., 0., 0.]; - TABLE[exponent & 15] - } - - #[inline] - fn from_u64(v: u64) -> Self { - debug_assert!(v <= Self::MAX_MANTISSA_FAST_PATH); - v as _ - } -} - impl Float for f64 { type Int = u64; @@ -355,19 +293,3 @@ impl FloatExt for f64 { f64::from_bits(v) } } - -impl Lemire for f64 { - fn pow10_fast_path(exponent: usize) -> Self { - const TABLE: [f64; 32] = [ - 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, - 1e16, 1e17, 1e18, 1e19, 1e20, 1e21, 1e22, 0., 0., 0., 0., 0., 0., 0., 0., 0., - ]; - TABLE[exponent & 31] - } - - #[inline] - fn from_u64(v: u64) -> Self { - debug_assert!(v <= Self::MAX_MANTISSA_FAST_PATH); - v as _ - } -} diff --git a/library/coretests/tests/lib.rs b/library/coretests/tests/lib.rs index 72112f8b01133..b3fd53cbb9dce 100644 --- a/library/coretests/tests/lib.rs +++ b/library/coretests/tests/lib.rs @@ -88,6 +88,7 @@ #![feature(next_index)] #![feature(non_exhaustive_omitted_patterns_lint)] #![feature(nonzero_from_str_radix)] +#![feature(num_internals)] #![feature(numfmt)] #![feature(one_sided_range)] #![feature(panic_internals)] diff --git a/library/coretests/tests/num/dec2flt/float.rs b/library/coretests/tests/num/dec2flt/float.rs index aa4c59dd66ea0..0713c5c651fb3 100644 --- a/library/coretests/tests/num/dec2flt/float.rs +++ b/library/coretests/tests/num/dec2flt/float.rs @@ -1,4 +1,5 @@ -use core::num::imp::dec2flt::float::{Float, FloatExt, Lemire}; +use core::num::imp::dec2flt::Lemire; +use core::num::imp::{Float, FloatExt}; use crate::num::{ldexp_f32, ldexp_f64}; diff --git a/library/coretests/tests/num/dec2flt/lemire.rs b/library/coretests/tests/num/dec2flt/lemire.rs index 6679dca148aa6..e5a7ae346f425 100644 --- a/library/coretests/tests/num/dec2flt/lemire.rs +++ b/library/coretests/tests/num/dec2flt/lemire.rs @@ -1,6 +1,5 @@ -use core::num::imp::dec2flt; +use core::num::imp::{Float, dec2flt}; -use dec2flt::float::Float; use dec2flt::lemire::compute_float; #[cfg(target_has_reliable_f16)] From 24d86b5f2b69665d6b6c0868239e37da221f2e19 Mon Sep 17 00:00:00 2001 From: Bhavya Gautam Date: Tue, 3 Mar 2026 06:35:43 +0000 Subject: [PATCH 11/22] Fix rust build failure for vxworks --- library/std/build.rs | 24 +++++++++++++++ library/std/src/os/vxworks/fs.rs | 30 +++++++++++++++++++ library/std/src/sys/fs/unix.rs | 18 ++++++++--- src/doc/rustc/src/platform-support/vxworks.md | 6 ++++ 4 files changed, 74 insertions(+), 4 deletions(-) diff --git a/library/std/build.rs b/library/std/build.rs index c0a6e30b38082..5f2e441bf7d83 100644 --- a/library/std/build.rs +++ b/library/std/build.rs @@ -79,4 +79,28 @@ fn main() { println!("cargo:rustc-cfg=backtrace_in_libstd"); println!("cargo:rustc-env=STD_ENV_ARCH={}", env::var("CARGO_CFG_TARGET_ARCH").unwrap()); + + println!("cargo:rustc-check-cfg=cfg(vxworks_lt_25_09)"); + + if target_os == "vxworks" { + match vxworks_version_code() { + Some((major, minor)) if (major, minor) < (25, 9) => { + println!("cargo:rustc-cfg=vxworks_lt_25_09"); + } + _ => {} + } + } +} + +/// Retrieve the VxWorks release version from the environment variable set by the VxWorks build +/// environment, in `(minor, patch)` form. +fn vxworks_version_code() -> Option<(u32, u32)> { + let version = env::var("WIND_RELEASE_ID").ok()?; + + let mut pieces = version.trim().split(['.']); + + let major: u32 = pieces.next().and_then(|x| x.parse().ok()).unwrap_or(0); + let minor: u32 = pieces.next().and_then(|x| x.parse().ok()).unwrap_or(0); + + Some((major, minor)) } diff --git a/library/std/src/os/vxworks/fs.rs b/library/std/src/os/vxworks/fs.rs index b88ed19b067a5..a21748ce9fe00 100644 --- a/library/std/src/os/vxworks/fs.rs +++ b/library/std/src/os/vxworks/fs.rs @@ -69,24 +69,54 @@ impl MetadataExt for Metadata { fn st_size(&self) -> u64 { self.as_inner().as_inner().st_size as u64 } + #[cfg(vxworks_lt_25_09)] fn st_atime(&self) -> i64 { self.as_inner().as_inner().st_atime as i64 } + #[cfg(not(vxworks_lt_25_09))] + fn st_atime(&self) -> i64 { + self.as_inner().as_inner().st_atim.tv_sec as i64 + } + #[cfg(vxworks_lt_25_09)] fn st_atime_nsec(&self) -> i64 { 0 } + #[cfg(not(vxworks_lt_25_09))] + fn st_atime_nsec(&self) -> i64 { + self.as_inner().as_inner().st_atim.tv_nsec as i64 + } + #[cfg(vxworks_lt_25_09)] fn st_mtime(&self) -> i64 { self.as_inner().as_inner().st_mtime as i64 } + #[cfg(not(vxworks_lt_25_09))] + fn st_mtime(&self) -> i64 { + self.as_inner().as_inner().st_mtim.tv_sec as i64 + } + #[cfg(vxworks_lt_25_09)] fn st_mtime_nsec(&self) -> i64 { 0 } + #[cfg(not(vxworks_lt_25_09))] + fn st_mtime_nsec(&self) -> i64 { + self.as_inner().as_inner().st_mtim.tv_nsec as i64 + } + #[cfg(vxworks_lt_25_09)] fn st_ctime(&self) -> i64 { self.as_inner().as_inner().st_ctime as i64 } + #[cfg(not(vxworks_lt_25_09))] + fn st_ctime(&self) -> i64 { + self.as_inner().as_inner().st_ctim.tv_sec as i64 + } + #[cfg(vxworks_lt_25_09)] fn st_ctime_nsec(&self) -> i64 { 0 } + #[cfg(not(vxworks_lt_25_09))] + fn st_ctime_nsec(&self) -> i64 { + self.as_inner().as_inner().st_ctim.tv_nsec as i64 + } fn st_blksize(&self) -> u64 { self.as_inner().as_inner().st_blksize as u64 } diff --git a/library/std/src/sys/fs/unix.rs b/library/std/src/sys/fs/unix.rs index 7db474544f04a..2a8571871b732 100644 --- a/library/std/src/sys/fs/unix.rs +++ b/library/std/src/sys/fs/unix.rs @@ -634,7 +634,7 @@ impl FileAttr { } #[cfg(any( - target_os = "vxworks", + all(target_os = "vxworks", vxworks_lt_25_09), target_os = "espidf", target_os = "vita", target_os = "rtems", @@ -643,7 +643,12 @@ impl FileAttr { SystemTime::new(self.stat.st_mtime as i64, 0) } - #[cfg(any(target_os = "horizon", target_os = "hurd", target_os = "nuttx"))] + #[cfg(any( + target_os = "horizon", + target_os = "hurd", + target_os = "nuttx", + all(target_os = "vxworks", not(vxworks_lt_25_09)) + ))] pub fn modified(&self) -> io::Result { SystemTime::new(self.stat.st_mtim.tv_sec as i64, self.stat.st_mtim.tv_nsec as i64) } @@ -669,7 +674,7 @@ impl FileAttr { } #[cfg(any( - target_os = "vxworks", + all(target_os = "vxworks", vxworks_lt_25_09), target_os = "espidf", target_os = "vita", target_os = "rtems" @@ -678,7 +683,12 @@ impl FileAttr { SystemTime::new(self.stat.st_atime as i64, 0) } - #[cfg(any(target_os = "horizon", target_os = "hurd", target_os = "nuttx"))] + #[cfg(any( + target_os = "horizon", + target_os = "hurd", + target_os = "nuttx", + all(target_os = "vxworks", not(vxworks_lt_25_09)) + ))] pub fn accessed(&self) -> io::Result { SystemTime::new(self.stat.st_atim.tv_sec as i64, self.stat.st_atim.tv_nsec as i64) } diff --git a/src/doc/rustc/src/platform-support/vxworks.md b/src/doc/rustc/src/platform-support/vxworks.md index 091c757a2ee36..0cf3822f759e7 100644 --- a/src/doc/rustc/src/platform-support/vxworks.md +++ b/src/doc/rustc/src/platform-support/vxworks.md @@ -28,6 +28,12 @@ Target triplets available: The minimum supported version is VxWorks 7. +### Environment + +#### `WIND_RELEASE_ID` + +In VxWorks build environment, the environment variable `WIND_RELEASE_ID` indicates the VxWorks release version used for the build. The `WIND_RELEASE_ID` can be used to conditionally compile features/code or handle version specific behaviour. + ## Building Rust for each target can be cross-compiled with its specific target vsb configuration. Std support is added but not yet fully tested. From 69fd61e40e854ecd75e19b32ebb913d1a8c7d121 Mon Sep 17 00:00:00 2001 From: cyrgani Date: Tue, 17 Mar 2026 16:15:14 +0000 Subject: [PATCH 12/22] merge `kindck/send-*` tests --- tests/ui/kindck/kindck-send-object.rs | 26 ---- tests/ui/kindck/kindck-send-object.stderr | 33 ----- tests/ui/kindck/kindck-send-object1.rs | 33 ----- tests/ui/kindck/kindck-send-object1.stderr | 41 ------ tests/ui/kindck/kindck-send-object2.rs | 24 ---- tests/ui/kindck/kindck-send-object2.stderr | 33 ----- tests/ui/kindck/kindck-send-owned.rs | 16 --- tests/ui/kindck/kindck-send-owned.stderr | 19 --- tests/ui/kindck/kindck-send-unsafe.rs | 15 --- tests/ui/kindck/kindck-send-unsafe.stderr | 29 ---- tests/ui/kindck/send-trait-objects-basic.rs | 55 ++++++++ .../ui/kindck/send-trait-objects-basic.stderr | 127 ++++++++++++++++++ 12 files changed, 182 insertions(+), 269 deletions(-) delete mode 100644 tests/ui/kindck/kindck-send-object.rs delete mode 100644 tests/ui/kindck/kindck-send-object.stderr delete mode 100644 tests/ui/kindck/kindck-send-object1.rs delete mode 100644 tests/ui/kindck/kindck-send-object1.stderr delete mode 100644 tests/ui/kindck/kindck-send-object2.rs delete mode 100644 tests/ui/kindck/kindck-send-object2.stderr delete mode 100644 tests/ui/kindck/kindck-send-owned.rs delete mode 100644 tests/ui/kindck/kindck-send-owned.stderr delete mode 100644 tests/ui/kindck/kindck-send-unsafe.rs delete mode 100644 tests/ui/kindck/kindck-send-unsafe.stderr create mode 100644 tests/ui/kindck/send-trait-objects-basic.rs create mode 100644 tests/ui/kindck/send-trait-objects-basic.stderr diff --git a/tests/ui/kindck/kindck-send-object.rs b/tests/ui/kindck/kindck-send-object.rs deleted file mode 100644 index f5d44246efe5a..0000000000000 --- a/tests/ui/kindck/kindck-send-object.rs +++ /dev/null @@ -1,26 +0,0 @@ -// Test which of the builtin types are considered sendable. The tests -// in this file all test the "kind" violates detected during kindck. -// See all `regions-bounded-by-send.rs` - -fn assert_send() { } -trait Dummy { } -trait Message : Send { } - -// careful with object types, who knows what they close over... - -fn object_ref_with_static_bound_not_ok() { - assert_send::<&'static (dyn Dummy + 'static)>(); - //~^ ERROR `&'static (dyn Dummy + 'static)` cannot be sent between threads safely [E0277] -} - -fn box_object_with_no_bound_not_ok<'a>() { - assert_send::>(); - //~^ ERROR `dyn Dummy` cannot be sent between threads safely -} - -fn object_with_send_bound_ok() { - assert_send::<&'static (dyn Dummy + Sync)>(); - assert_send::>(); -} - -fn main() { } diff --git a/tests/ui/kindck/kindck-send-object.stderr b/tests/ui/kindck/kindck-send-object.stderr deleted file mode 100644 index b71d4029350e1..0000000000000 --- a/tests/ui/kindck/kindck-send-object.stderr +++ /dev/null @@ -1,33 +0,0 @@ -error[E0277]: `&'static (dyn Dummy + 'static)` cannot be sent between threads safely - --> $DIR/kindck-send-object.rs:12:19 - | -LL | assert_send::<&'static (dyn Dummy + 'static)>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `&'static (dyn Dummy + 'static)` cannot be sent between threads safely - | - = help: the trait `Sync` is not implemented for `(dyn Dummy + 'static)` - = note: required for `&'static (dyn Dummy + 'static)` to implement `Send` -note: required by a bound in `assert_send` - --> $DIR/kindck-send-object.rs:5:18 - | -LL | fn assert_send() { } - | ^^^^ required by this bound in `assert_send` - -error[E0277]: `dyn Dummy` cannot be sent between threads safely - --> $DIR/kindck-send-object.rs:17:19 - | -LL | assert_send::>(); - | ^^^^^^^^^^^^^^ `dyn Dummy` cannot be sent between threads safely - | - = help: the trait `Send` is not implemented for `dyn Dummy` - = 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` - --> $DIR/kindck-send-object.rs:5:18 - | -LL | fn assert_send() { } - | ^^^^ required by this bound in `assert_send` - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/kindck/kindck-send-object1.rs b/tests/ui/kindck/kindck-send-object1.rs deleted file mode 100644 index 76a9fc6019abc..0000000000000 --- a/tests/ui/kindck/kindck-send-object1.rs +++ /dev/null @@ -1,33 +0,0 @@ -// Test which object types are considered sendable. This test -// is broken into two parts because some errors occur in distinct -// phases in the compiler. See kindck-send-object2.rs as well! - -fn assert_send() { } -trait Dummy { } - -// careful with object types, who knows what they close over... -fn test51<'a>() { - assert_send::<&'a dyn Dummy>(); - //~^ ERROR `&'a (dyn Dummy + 'a)` cannot be sent between threads safely [E0277] -} -fn test52<'a>() { - assert_send::<&'a (dyn Dummy + Sync)>(); - //~^ ERROR: lifetime may not live long enough -} - -// ...unless they are properly bounded -fn test60() { - assert_send::<&'static (dyn Dummy + Sync)>(); -} -fn test61() { - assert_send::>(); -} - -// closure and object types can have lifetime bounds which make -// them not ok -fn test_71<'a>() { - assert_send::>(); - //~^ ERROR `(dyn Dummy + 'a)` cannot be sent between threads safely -} - -fn main() { } diff --git a/tests/ui/kindck/kindck-send-object1.stderr b/tests/ui/kindck/kindck-send-object1.stderr deleted file mode 100644 index 2184ae704673d..0000000000000 --- a/tests/ui/kindck/kindck-send-object1.stderr +++ /dev/null @@ -1,41 +0,0 @@ -error[E0277]: `&'a (dyn Dummy + 'a)` cannot be sent between threads safely - --> $DIR/kindck-send-object1.rs:10:19 - | -LL | assert_send::<&'a dyn Dummy>(); - | ^^^^^^^^^^^^^ `&'a (dyn Dummy + 'a)` cannot be sent between threads safely - | - = help: the trait `Sync` is not implemented for `(dyn Dummy + 'a)` - = note: required for `&'a (dyn Dummy + 'a)` to implement `Send` -note: required by a bound in `assert_send` - --> $DIR/kindck-send-object1.rs:5:18 - | -LL | fn assert_send() { } - | ^^^^ required by this bound in `assert_send` - -error[E0277]: `(dyn Dummy + 'a)` cannot be sent between threads safely - --> $DIR/kindck-send-object1.rs:29:19 - | -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 `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` - --> $DIR/kindck-send-object1.rs:5:18 - | -LL | fn assert_send() { } - | ^^^^ required by this bound in `assert_send` - -error: lifetime may not live long enough - --> $DIR/kindck-send-object1.rs:14:5 - | -LL | fn test52<'a>() { - | -- lifetime `'a` defined here -LL | assert_send::<&'a (dyn Dummy + Sync)>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static` - -error: aborting due to 3 previous errors - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/kindck/kindck-send-object2.rs b/tests/ui/kindck/kindck-send-object2.rs deleted file mode 100644 index d37074e657462..0000000000000 --- a/tests/ui/kindck/kindck-send-object2.rs +++ /dev/null @@ -1,24 +0,0 @@ -// Continue kindck-send-object1.rs. - -fn assert_send() { } -trait Dummy { } - -fn test50() { - assert_send::<&'static dyn Dummy>(); - //~^ ERROR `&'static (dyn Dummy + 'static)` cannot be sent between threads safely [E0277] -} - -fn test53() { - assert_send::>(); - //~^ ERROR `dyn Dummy` cannot be sent between threads safely -} - -// ...unless they are properly bounded -fn test60() { - assert_send::<&'static (dyn Dummy + Sync)>(); -} -fn test61() { - assert_send::>(); -} - -fn main() { } diff --git a/tests/ui/kindck/kindck-send-object2.stderr b/tests/ui/kindck/kindck-send-object2.stderr deleted file mode 100644 index 52a7055b42291..0000000000000 --- a/tests/ui/kindck/kindck-send-object2.stderr +++ /dev/null @@ -1,33 +0,0 @@ -error[E0277]: `&'static (dyn Dummy + 'static)` cannot be sent between threads safely - --> $DIR/kindck-send-object2.rs:7:19 - | -LL | assert_send::<&'static dyn Dummy>(); - | ^^^^^^^^^^^^^^^^^^ `&'static (dyn Dummy + 'static)` cannot be sent between threads safely - | - = help: the trait `Sync` is not implemented for `(dyn Dummy + 'static)` - = note: required for `&'static (dyn Dummy + 'static)` to implement `Send` -note: required by a bound in `assert_send` - --> $DIR/kindck-send-object2.rs:3:18 - | -LL | fn assert_send() { } - | ^^^^ required by this bound in `assert_send` - -error[E0277]: `dyn Dummy` cannot be sent between threads safely - --> $DIR/kindck-send-object2.rs:12:19 - | -LL | assert_send::>(); - | ^^^^^^^^^^^^^^ `dyn Dummy` cannot be sent between threads safely - | - = help: the trait `Send` is not implemented for `dyn Dummy` - = 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` - --> $DIR/kindck-send-object2.rs:3:18 - | -LL | fn assert_send() { } - | ^^^^ required by this bound in `assert_send` - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/kindck/kindck-send-owned.rs b/tests/ui/kindck/kindck-send-owned.rs deleted file mode 100644 index 65efb69041d59..0000000000000 --- a/tests/ui/kindck/kindck-send-owned.rs +++ /dev/null @@ -1,16 +0,0 @@ -// Test which of the builtin types are considered sendable. - -fn assert_send() { } - -// owned content are ok -fn test30() { assert_send::>(); } -fn test31() { assert_send::(); } -fn test32() { assert_send:: >(); } - -// but not if they own a bad thing -fn test40() { - assert_send::>(); - //~^ ERROR `*mut u8` cannot be sent between threads safely -} - -fn main() { } diff --git a/tests/ui/kindck/kindck-send-owned.stderr b/tests/ui/kindck/kindck-send-owned.stderr deleted file mode 100644 index c433d80cf140c..0000000000000 --- a/tests/ui/kindck/kindck-send-owned.stderr +++ /dev/null @@ -1,19 +0,0 @@ -error[E0277]: `*mut u8` cannot be sent between threads safely - --> $DIR/kindck-send-owned.rs:12:19 - | -LL | assert_send::>(); - | ^^^^^^^^^^^^ `*mut u8` cannot be sent between threads safely - | - = help: the trait `Send` is not implemented for `*mut u8` - = 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` - --> $DIR/kindck-send-owned.rs:3:18 - | -LL | fn assert_send() { } - | ^^^^ required by this bound in `assert_send` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/kindck/kindck-send-unsafe.rs b/tests/ui/kindck/kindck-send-unsafe.rs deleted file mode 100644 index eb1f2a549b16b..0000000000000 --- a/tests/ui/kindck/kindck-send-unsafe.rs +++ /dev/null @@ -1,15 +0,0 @@ -extern crate core; - -fn assert_send() {} - -fn test70() { - assert_send::<*mut isize>(); - //~^ ERROR `*mut isize` cannot be sent between threads safely -} - -fn test71<'a>() { - assert_send::<*mut &'a isize>(); - //~^ ERROR `*mut &'a isize` cannot be sent between threads safely -} - -fn main() {} diff --git a/tests/ui/kindck/kindck-send-unsafe.stderr b/tests/ui/kindck/kindck-send-unsafe.stderr deleted file mode 100644 index f1a5054abbc47..0000000000000 --- a/tests/ui/kindck/kindck-send-unsafe.stderr +++ /dev/null @@ -1,29 +0,0 @@ -error[E0277]: `*mut isize` cannot be sent between threads safely - --> $DIR/kindck-send-unsafe.rs:6:19 - | -LL | assert_send::<*mut isize>(); - | ^^^^^^^^^^ `*mut isize` cannot be sent between threads safely - | - = help: the trait `Send` is not implemented for `*mut isize` -note: required by a bound in `assert_send` - --> $DIR/kindck-send-unsafe.rs:3:19 - | -LL | fn assert_send() {} - | ^^^^ required by this bound in `assert_send` - -error[E0277]: `*mut &'a isize` cannot be sent between threads safely - --> $DIR/kindck-send-unsafe.rs:11:19 - | -LL | assert_send::<*mut &'a isize>(); - | ^^^^^^^^^^^^^^ `*mut &'a isize` cannot be sent between threads safely - | - = help: the trait `Send` is not implemented for `*mut &'a isize` -note: required by a bound in `assert_send` - --> $DIR/kindck-send-unsafe.rs:3:19 - | -LL | fn assert_send() {} - | ^^^^ required by this bound in `assert_send` - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/kindck/send-trait-objects-basic.rs b/tests/ui/kindck/send-trait-objects-basic.rs new file mode 100644 index 0000000000000..c999d4d0f6950 --- /dev/null +++ b/tests/ui/kindck/send-trait-objects-basic.rs @@ -0,0 +1,55 @@ +// Test which trait objects and basic types are considered sendable, considering lifetimes. + +fn assert_send_static() {} +fn assert_send() {} + +trait Dummy {} + +fn test1<'a>() { + assert_send_static::<&'a dyn Dummy>(); + //~^ ERROR `&'a (dyn Dummy + 'a)` cannot be sent between threads safely [E0277] +} + +fn test2<'a>() { + assert_send_static::<&'a (dyn Dummy + Sync)>(); + //~^ ERROR: lifetime may not live long enough +} + +fn test3<'a>() { + assert_send_static::>(); + //~^ ERROR `(dyn Dummy + 'a)` cannot be sent between threads safely +} + +fn test4<'a>() { + assert_send::<*mut &'a isize>(); + //~^ ERROR `*mut &'a isize` cannot be sent between threads safely +} + +fn main() { + assert_send_static::<&'static (dyn Dummy + Sync)>(); + assert_send_static::>(); + + assert_send::<&'static dyn Dummy>(); + //~^ ERROR `&'static (dyn Dummy + 'static)` cannot be sent between threads safely [E0277] + assert_send::>(); + //~^ ERROR `dyn Dummy` cannot be sent between threads safely + assert_send::<&'static (dyn Dummy + Sync)>(); + assert_send::>(); + + // owned content is ok + assert_send::>(); + assert_send::(); + assert_send::>(); + + // but not if it owns a bad thing + assert_send::>(); + //~^ ERROR `*mut u8` cannot be sent between threads safely + + assert_send::<*mut isize>(); + //~^ ERROR `*mut isize` cannot be sent between threads safely +} + +fn object_ref_with_static_bound_not_ok() { + assert_send::<&'static (dyn Dummy + 'static)>(); + //~^ ERROR `&'static (dyn Dummy + 'static)` cannot be sent between threads safely [E0277] +} diff --git a/tests/ui/kindck/send-trait-objects-basic.stderr b/tests/ui/kindck/send-trait-objects-basic.stderr new file mode 100644 index 0000000000000..0393f7bc19df7 --- /dev/null +++ b/tests/ui/kindck/send-trait-objects-basic.stderr @@ -0,0 +1,127 @@ +error[E0277]: `&'a (dyn Dummy + 'a)` cannot be sent between threads safely + --> $DIR/send-trait-objects-basic.rs:9:26 + | +LL | assert_send_static::<&'a dyn Dummy>(); + | ^^^^^^^^^^^^^ `&'a (dyn Dummy + 'a)` cannot be sent between threads safely + | + = help: the trait `Sync` is not implemented for `(dyn Dummy + 'a)` + = note: required for `&'a (dyn Dummy + 'a)` to implement `Send` +note: required by a bound in `assert_send_static` + --> $DIR/send-trait-objects-basic.rs:3:26 + | +LL | fn assert_send_static() {} + | ^^^^ required by this bound in `assert_send_static` + +error[E0277]: `(dyn Dummy + 'a)` cannot be sent between threads safely + --> $DIR/send-trait-objects-basic.rs:19:26 + | +LL | assert_send_static::>(); + | ^^^^^^^^^^^^^^^^^^^ `(dyn Dummy + 'a)` cannot be sent between threads safely + | + = help: the trait `Send` is not implemented for `(dyn Dummy + 'a)` + = 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_static` + --> $DIR/send-trait-objects-basic.rs:3:26 + | +LL | fn assert_send_static() {} + | ^^^^ required by this bound in `assert_send_static` + +error[E0277]: `*mut &'a isize` cannot be sent between threads safely + --> $DIR/send-trait-objects-basic.rs:24:19 + | +LL | assert_send::<*mut &'a isize>(); + | ^^^^^^^^^^^^^^ `*mut &'a isize` cannot be sent between threads safely + | + = help: the trait `Send` is not implemented for `*mut &'a isize` +note: required by a bound in `assert_send` + --> $DIR/send-trait-objects-basic.rs:4:19 + | +LL | fn assert_send() {} + | ^^^^ required by this bound in `assert_send` + +error[E0277]: `&'static (dyn Dummy + 'static)` cannot be sent between threads safely + --> $DIR/send-trait-objects-basic.rs:32:19 + | +LL | assert_send::<&'static dyn Dummy>(); + | ^^^^^^^^^^^^^^^^^^ `&'static (dyn Dummy + 'static)` cannot be sent between threads safely + | + = help: the trait `Sync` is not implemented for `(dyn Dummy + 'static)` + = note: required for `&'static (dyn Dummy + 'static)` to implement `Send` +note: required by a bound in `assert_send` + --> $DIR/send-trait-objects-basic.rs:4:19 + | +LL | fn assert_send() {} + | ^^^^ required by this bound in `assert_send` + +error[E0277]: `dyn Dummy` cannot be sent between threads safely + --> $DIR/send-trait-objects-basic.rs:34:19 + | +LL | assert_send::>(); + | ^^^^^^^^^^^^^^ `dyn Dummy` cannot be sent between threads safely + | + = help: the trait `Send` is not implemented for `dyn Dummy` + = 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` + --> $DIR/send-trait-objects-basic.rs:4:19 + | +LL | fn assert_send() {} + | ^^^^ required by this bound in `assert_send` + +error[E0277]: `*mut u8` cannot be sent between threads safely + --> $DIR/send-trait-objects-basic.rs:45:19 + | +LL | assert_send::>(); + | ^^^^^^^^^^^^ `*mut u8` cannot be sent between threads safely + | + = help: the trait `Send` is not implemented for `*mut u8` + = 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` + --> $DIR/send-trait-objects-basic.rs:4:19 + | +LL | fn assert_send() {} + | ^^^^ required by this bound in `assert_send` + +error[E0277]: `*mut isize` cannot be sent between threads safely + --> $DIR/send-trait-objects-basic.rs:48:19 + | +LL | assert_send::<*mut isize>(); + | ^^^^^^^^^^ `*mut isize` cannot be sent between threads safely + | + = help: the trait `Send` is not implemented for `*mut isize` +note: required by a bound in `assert_send` + --> $DIR/send-trait-objects-basic.rs:4:19 + | +LL | fn assert_send() {} + | ^^^^ required by this bound in `assert_send` + +error[E0277]: `&'static (dyn Dummy + 'static)` cannot be sent between threads safely + --> $DIR/send-trait-objects-basic.rs:53:19 + | +LL | assert_send::<&'static (dyn Dummy + 'static)>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `&'static (dyn Dummy + 'static)` cannot be sent between threads safely + | + = help: the trait `Sync` is not implemented for `(dyn Dummy + 'static)` + = note: required for `&'static (dyn Dummy + 'static)` to implement `Send` +note: required by a bound in `assert_send` + --> $DIR/send-trait-objects-basic.rs:4:19 + | +LL | fn assert_send() {} + | ^^^^ required by this bound in `assert_send` + +error: lifetime may not live long enough + --> $DIR/send-trait-objects-basic.rs:14:5 + | +LL | fn test2<'a>() { + | -- lifetime `'a` defined here +LL | assert_send_static::<&'a (dyn Dummy + Sync)>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static` + +error: aborting due to 9 previous errors + +For more information about this error, try `rustc --explain E0277`. From caeda1869aab15cdd25d43d2de43d43b4cfbee07 Mon Sep 17 00:00:00 2001 From: cyrgani Date: Tue, 17 Mar 2026 21:49:58 +0000 Subject: [PATCH 13/22] reformat and update remaining `ui/kindck` tests --- tests/ui/kindck/kindck-copy.rs | 31 ++++----- tests/ui/kindck/kindck-copy.stderr | 68 +++++++++---------- tests/ui/kindck/kindck-impl-type-params-2.rs | 15 ---- .../kindck/kindck-impl-type-params-2.stderr | 24 ------- tests/ui/kindck/kindck-impl-type-params.rs | 6 +- .../ui/kindck/kindck-impl-type-params.stderr | 30 ++++---- .../kindck-inherited-copy-bound.curr.stderr | 56 --------------- .../ui/kindck/kindck-inherited-copy-bound.rs | 10 ++- .../kindck/kindck-inherited-copy-bound.stderr | 26 +++---- tests/ui/kindck/kindck-nonsendable-1.rs | 4 +- tests/ui/kindck/kindck-nonsendable-1.stderr | 18 ++--- 11 files changed, 96 insertions(+), 192 deletions(-) delete mode 100644 tests/ui/kindck/kindck-impl-type-params-2.rs delete mode 100644 tests/ui/kindck/kindck-impl-type-params-2.stderr delete mode 100644 tests/ui/kindck/kindck-inherited-copy-bound.curr.stderr diff --git a/tests/ui/kindck/kindck-copy.rs b/tests/ui/kindck/kindck-copy.rs index 36bf0d2b785f6..c953b60260df4 100644 --- a/tests/ui/kindck/kindck-copy.rs +++ b/tests/ui/kindck/kindck-copy.rs @@ -2,9 +2,9 @@ use std::rc::Rc; -fn assert_copy() { } +fn assert_copy() {} -trait Dummy { } +trait Dummy {} #[derive(Copy, Clone)] struct MyStruct { @@ -16,8 +16,8 @@ struct MyNoncopyStruct { x: Box, } -fn test<'a,T,U:Copy>(_: &'a isize) { - // lifetime pointers are ok... +fn test<'a, T, U: Copy>(_: &'a isize) { + // references are ok... assert_copy::<&'static isize>(); assert_copy::<&'a isize>(); assert_copy::<&'a str>(); @@ -25,25 +25,25 @@ fn test<'a,T,U:Copy>(_: &'a isize) { // ...unless they are mutable assert_copy::<&'static mut isize>(); //~ ERROR : Copy` is not satisfied - assert_copy::<&'a mut isize>(); //~ ERROR : Copy` is not satisfied + assert_copy::<&'a mut isize>(); //~ ERROR : Copy` is not satisfied // boxes are not ok - assert_copy::>(); //~ ERROR : Copy` is not satisfied - assert_copy::(); //~ ERROR : Copy` is not satisfied - assert_copy:: >(); //~ ERROR : Copy` is not satisfied + assert_copy::>(); //~ ERROR : Copy` is not satisfied + assert_copy::(); //~ ERROR : Copy` is not satisfied + assert_copy::>(); //~ ERROR : Copy` is not satisfied assert_copy::>(); //~ ERROR : Copy` is not satisfied - // borrowed object types are generally ok + // borrowed trait objects are generally ok assert_copy::<&'a dyn Dummy>(); assert_copy::<&'a (dyn Dummy + Send)>(); assert_copy::<&'static (dyn Dummy + Send)>(); - // owned object types are not ok + // boxed trait objects are not ok assert_copy::>(); //~ ERROR : Copy` is not satisfied assert_copy::>(); //~ ERROR : Copy` is not satisfied - // mutable object types are not ok - assert_copy::<&'a mut (dyn Dummy + Send)>(); //~ ERROR : Copy` is not satisfied + // mutable references to trait objects are not ok + assert_copy::<&'a mut (dyn Dummy + Send)>(); //~ ERROR : Copy` is not satisfied // raw ptrs are ok assert_copy::<*const isize>(); @@ -55,7 +55,7 @@ fn test<'a,T,U:Copy>(_: &'a isize) { assert_copy::<()>(); // tuples are ok - assert_copy::<(isize,isize)>(); + assert_copy::<(isize, isize)>(); // structs of POD are ok assert_copy::(); @@ -64,8 +64,7 @@ fn test<'a,T,U:Copy>(_: &'a isize) { assert_copy::(); //~ ERROR : Copy` is not satisfied // ref counted types are not ok - assert_copy::>(); //~ ERROR : Copy` is not satisfied + assert_copy::>(); //~ ERROR : Copy` is not satisfied } -pub fn main() { -} +pub fn main() {} diff --git a/tests/ui/kindck/kindck-copy.stderr b/tests/ui/kindck/kindck-copy.stderr index f5623ddd4f795..01b4a5a646476 100644 --- a/tests/ui/kindck/kindck-copy.stderr +++ b/tests/ui/kindck/kindck-copy.stderr @@ -5,10 +5,10 @@ LL | assert_copy::<&'static mut isize>(); | ^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `&'static mut isize` | note: required by a bound in `assert_copy` - --> $DIR/kindck-copy.rs:5:18 + --> $DIR/kindck-copy.rs:5:19 | -LL | fn assert_copy() { } - | ^^^^ required by this bound in `assert_copy` +LL | fn assert_copy() {} + | ^^^^ required by this bound in `assert_copy` help: consider removing the leading `&`-reference | LL - assert_copy::<&'static mut isize>(); @@ -22,10 +22,10 @@ LL | assert_copy::<&'a mut isize>(); | ^^^^^^^^^^^^^ the trait `Copy` is not implemented for `&'a mut isize` | note: required by a bound in `assert_copy` - --> $DIR/kindck-copy.rs:5:18 + --> $DIR/kindck-copy.rs:5:19 | -LL | fn assert_copy() { } - | ^^^^ required by this bound in `assert_copy` +LL | fn assert_copy() {} + | ^^^^ required by this bound in `assert_copy` help: consider removing the leading `&`-reference | LL - assert_copy::<&'a mut isize>(); @@ -39,10 +39,10 @@ LL | assert_copy::>(); | ^^^^^^^^^^ the trait `Copy` is not implemented for `Box` | note: required by a bound in `assert_copy` - --> $DIR/kindck-copy.rs:5:18 + --> $DIR/kindck-copy.rs:5:19 | -LL | fn assert_copy() { } - | ^^^^ required by this bound in `assert_copy` +LL | fn assert_copy() {} + | ^^^^ required by this bound in `assert_copy` error[E0277]: the trait bound `String: Copy` is not satisfied --> $DIR/kindck-copy.rs:32:19 @@ -51,22 +51,22 @@ LL | assert_copy::(); | ^^^^^^ the trait `Copy` is not implemented for `String` | note: required by a bound in `assert_copy` - --> $DIR/kindck-copy.rs:5:18 + --> $DIR/kindck-copy.rs:5:19 | -LL | fn assert_copy() { } - | ^^^^ required by this bound in `assert_copy` +LL | fn assert_copy() {} + | ^^^^ required by this bound in `assert_copy` error[E0277]: the trait bound `Vec: Copy` is not satisfied --> $DIR/kindck-copy.rs:33:19 | -LL | assert_copy:: >(); +LL | assert_copy::>(); | ^^^^^^^^^^ the trait `Copy` is not implemented for `Vec` | note: required by a bound in `assert_copy` - --> $DIR/kindck-copy.rs:5:18 + --> $DIR/kindck-copy.rs:5:19 | -LL | fn assert_copy() { } - | ^^^^ required by this bound in `assert_copy` +LL | fn assert_copy() {} + | ^^^^ required by this bound in `assert_copy` error[E0277]: the trait bound `Box<&'a mut isize>: Copy` is not satisfied --> $DIR/kindck-copy.rs:34:19 @@ -75,10 +75,10 @@ LL | assert_copy::>(); | ^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `Box<&'a mut isize>` | note: required by a bound in `assert_copy` - --> $DIR/kindck-copy.rs:5:18 + --> $DIR/kindck-copy.rs:5:19 | -LL | fn assert_copy() { } - | ^^^^ required by this bound in `assert_copy` +LL | fn assert_copy() {} + | ^^^^ required by this bound in `assert_copy` error[E0277]: the trait bound `Box: Copy` is not satisfied --> $DIR/kindck-copy.rs:42:19 @@ -87,10 +87,10 @@ LL | assert_copy::>(); | ^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `Box` | note: required by a bound in `assert_copy` - --> $DIR/kindck-copy.rs:5:18 + --> $DIR/kindck-copy.rs:5:19 | -LL | fn assert_copy() { } - | ^^^^ required by this bound in `assert_copy` +LL | fn assert_copy() {} + | ^^^^ required by this bound in `assert_copy` error[E0277]: the trait bound `Box: Copy` is not satisfied --> $DIR/kindck-copy.rs:43:19 @@ -99,10 +99,10 @@ LL | assert_copy::>(); | ^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `Box` | note: required by a bound in `assert_copy` - --> $DIR/kindck-copy.rs:5:18 + --> $DIR/kindck-copy.rs:5:19 | -LL | fn assert_copy() { } - | ^^^^ required by this bound in `assert_copy` +LL | fn assert_copy() {} + | ^^^^ required by this bound in `assert_copy` error[E0277]: the trait bound `&'a mut (dyn Dummy + Send + 'a): Copy` is not satisfied --> $DIR/kindck-copy.rs:46:19 @@ -111,10 +111,10 @@ LL | assert_copy::<&'a mut (dyn Dummy + Send)>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `&'a mut (dyn Dummy + Send + 'a)` | note: required by a bound in `assert_copy` - --> $DIR/kindck-copy.rs:5:18 + --> $DIR/kindck-copy.rs:5:19 | -LL | fn assert_copy() { } - | ^^^^ required by this bound in `assert_copy` +LL | fn assert_copy() {} + | ^^^^ required by this bound in `assert_copy` error[E0277]: the trait bound `MyNoncopyStruct: Copy` is not satisfied --> $DIR/kindck-copy.rs:64:19 @@ -128,10 +128,10 @@ help: the trait `Copy` is not implemented for `MyNoncopyStruct` LL | struct MyNoncopyStruct { | ^^^^^^^^^^^^^^^^^^^^^^ note: required by a bound in `assert_copy` - --> $DIR/kindck-copy.rs:5:18 + --> $DIR/kindck-copy.rs:5:19 | -LL | fn assert_copy() { } - | ^^^^ required by this bound in `assert_copy` +LL | fn assert_copy() {} + | ^^^^ required by this bound in `assert_copy` error[E0277]: the trait bound `Rc: Copy` is not satisfied --> $DIR/kindck-copy.rs:67:19 @@ -140,10 +140,10 @@ LL | assert_copy::>(); | ^^^^^^^^^ the trait `Copy` is not implemented for `Rc` | note: required by a bound in `assert_copy` - --> $DIR/kindck-copy.rs:5:18 + --> $DIR/kindck-copy.rs:5:19 | -LL | fn assert_copy() { } - | ^^^^ required by this bound in `assert_copy` +LL | fn assert_copy() {} + | ^^^^ required by this bound in `assert_copy` error: aborting due to 11 previous errors diff --git a/tests/ui/kindck/kindck-impl-type-params-2.rs b/tests/ui/kindck/kindck-impl-type-params-2.rs deleted file mode 100644 index 8b0771985dc3f..0000000000000 --- a/tests/ui/kindck/kindck-impl-type-params-2.rs +++ /dev/null @@ -1,15 +0,0 @@ -trait Foo { -} - - - -impl Foo for T { -} - -fn take_param(foo: &T) { } - -fn main() { - let x: Box<_> = Box::new(3); - take_param(&x); - //~^ ERROR the trait bound `Box<{integer}>: Foo` is not satisfied -} diff --git a/tests/ui/kindck/kindck-impl-type-params-2.stderr b/tests/ui/kindck/kindck-impl-type-params-2.stderr deleted file mode 100644 index 38dc94f9104d5..0000000000000 --- a/tests/ui/kindck/kindck-impl-type-params-2.stderr +++ /dev/null @@ -1,24 +0,0 @@ -error[E0277]: the trait bound `Box<{integer}>: Foo` is not satisfied - --> $DIR/kindck-impl-type-params-2.rs:13:16 - | -LL | take_param(&x); - | ---------- ^^ the trait `Copy` is not implemented for `Box<{integer}>` - | | - | required by a bound introduced by this call - | -note: required for `Box<{integer}>` to implement `Foo` - --> $DIR/kindck-impl-type-params-2.rs:6:14 - | -LL | impl Foo for T { - | ---- ^^^ ^ - | | - | unsatisfied trait bound introduced here -note: required by a bound in `take_param` - --> $DIR/kindck-impl-type-params-2.rs:9:17 - | -LL | fn take_param(foo: &T) { } - | ^^^ required by this bound in `take_param` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/kindck/kindck-impl-type-params.rs b/tests/ui/kindck/kindck-impl-type-params.rs index 707c5dbaec30e..ba54bc313c089 100644 --- a/tests/ui/kindck/kindck-impl-type-params.rs +++ b/tests/ui/kindck/kindck-impl-type-params.rs @@ -6,7 +6,9 @@ use std::marker; struct S(marker::PhantomData); trait Gettable { - fn get(&self) -> T { panic!() } + fn get(&self) -> T { + panic!() + } } impl Gettable for S {} @@ -45,4 +47,4 @@ fn foo3<'a>() { //~^ ERROR : Copy` is not satisfied } -fn main() { } +fn main() {} diff --git a/tests/ui/kindck/kindck-impl-type-params.stderr b/tests/ui/kindck/kindck-impl-type-params.stderr index 0c9ab13f4774a..b2e52ae57ea4a 100644 --- a/tests/ui/kindck/kindck-impl-type-params.stderr +++ b/tests/ui/kindck/kindck-impl-type-params.stderr @@ -1,11 +1,11 @@ error[E0277]: `T` cannot be sent between threads safely - --> $DIR/kindck-impl-type-params.rs:16:13 + --> $DIR/kindck-impl-type-params.rs:18:13 | LL | let a = &t as &dyn Gettable; | ^^ `T` cannot be sent between threads safely | note: required for `S` to implement `Gettable` - --> $DIR/kindck-impl-type-params.rs:12:32 + --> $DIR/kindck-impl-type-params.rs:14:32 | LL | impl Gettable for S {} | ---- ^^^^^^^^^^^ ^^^^ @@ -18,13 +18,13 @@ LL | fn f(val: T) { | +++++++++++++++++++ error[E0277]: the trait bound `T: Copy` is not satisfied - --> $DIR/kindck-impl-type-params.rs:16:13 + --> $DIR/kindck-impl-type-params.rs:18:13 | LL | let a = &t as &dyn Gettable; | ^^ the trait `Copy` is not implemented for `T` | note: required for `S` to implement `Gettable` - --> $DIR/kindck-impl-type-params.rs:12:32 + --> $DIR/kindck-impl-type-params.rs:14:32 | LL | impl Gettable for S {} | ---- ^^^^^^^^^^^ ^^^^ @@ -37,13 +37,13 @@ LL | fn f(val: T) { | +++++++++++++++++++ error[E0277]: `T` cannot be sent between threads safely - --> $DIR/kindck-impl-type-params.rs:23:31 + --> $DIR/kindck-impl-type-params.rs:25:31 | LL | let a: &dyn Gettable = &t; | ^^ `T` cannot be sent between threads safely | note: required for `S` to implement `Gettable` - --> $DIR/kindck-impl-type-params.rs:12:32 + --> $DIR/kindck-impl-type-params.rs:14:32 | LL | impl Gettable for S {} | ---- ^^^^^^^^^^^ ^^^^ @@ -56,13 +56,13 @@ LL | fn g(val: T) { | +++++++++++++++++++ error[E0277]: the trait bound `T: Copy` is not satisfied - --> $DIR/kindck-impl-type-params.rs:23:31 + --> $DIR/kindck-impl-type-params.rs:25:31 | LL | let a: &dyn Gettable = &t; | ^^ the trait `Copy` is not implemented for `T` | note: required for `S` to implement `Gettable` - --> $DIR/kindck-impl-type-params.rs:12:32 + --> $DIR/kindck-impl-type-params.rs:14:32 | LL | impl Gettable for S {} | ---- ^^^^^^^^^^^ ^^^^ @@ -75,18 +75,18 @@ LL | fn g(val: T) { | +++++++++++++++++++ error[E0277]: the trait bound `String: Copy` is not satisfied - --> $DIR/kindck-impl-type-params.rs:36:13 + --> $DIR/kindck-impl-type-params.rs:38:13 | LL | let a = t as Box>; | ^ the trait `Copy` is not implemented for `String` | help: the trait `Gettable` is implemented for `S` - --> $DIR/kindck-impl-type-params.rs:12:1 + --> $DIR/kindck-impl-type-params.rs:14:1 | LL | impl Gettable for S {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: required for `S` to implement `Gettable` - --> $DIR/kindck-impl-type-params.rs:12:32 + --> $DIR/kindck-impl-type-params.rs:14:32 | LL | impl Gettable for S {} | ---- ^^^^^^^^^^^ ^^^^ @@ -95,18 +95,18 @@ LL | impl Gettable for S {} = note: required for the cast from `Box>` to `Box>` error[E0277]: the trait bound `Foo: Copy` is not satisfied - --> $DIR/kindck-impl-type-params.rs:44:37 + --> $DIR/kindck-impl-type-params.rs:46:37 | LL | let a: Box> = t; | ^ the trait `Copy` is not implemented for `Foo` | help: the trait `Gettable` is implemented for `S` - --> $DIR/kindck-impl-type-params.rs:12:1 + --> $DIR/kindck-impl-type-params.rs:14:1 | LL | impl Gettable for S {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: required for `S` to implement `Gettable` - --> $DIR/kindck-impl-type-params.rs:12:32 + --> $DIR/kindck-impl-type-params.rs:14:32 | LL | impl Gettable for S {} | ---- ^^^^^^^^^^^ ^^^^ @@ -120,7 +120,7 @@ LL | struct Foo; // does not impl Copy | error: lifetime may not live long enough - --> $DIR/kindck-impl-type-params.rs:30:13 + --> $DIR/kindck-impl-type-params.rs:32:13 | LL | fn foo<'a>() { | -- lifetime `'a` defined here diff --git a/tests/ui/kindck/kindck-inherited-copy-bound.curr.stderr b/tests/ui/kindck/kindck-inherited-copy-bound.curr.stderr deleted file mode 100644 index 95048c4454b31..0000000000000 --- a/tests/ui/kindck/kindck-inherited-copy-bound.curr.stderr +++ /dev/null @@ -1,56 +0,0 @@ -error[E0277]: the trait bound `Box<{integer}>: Foo` is not satisfied - --> $DIR/kindck-inherited-copy-bound.rs:21:16 - | -LL | take_param(&x); - | ---------- ^^ the trait `Copy` is not implemented for `Box<{integer}>` - | | - | required by a bound introduced by this call - | -note: required for `Box<{integer}>` to implement `Foo` - --> $DIR/kindck-inherited-copy-bound.rs:14:14 - | -LL | impl Foo for T { - | ---- ^^^ ^ - | | - | unsatisfied trait bound introduced here -note: required by a bound in `take_param` - --> $DIR/kindck-inherited-copy-bound.rs:17:17 - | -LL | fn take_param(foo: &T) { } - | ^^^ required by this bound in `take_param` - -error[E0038]: the trait `Foo` is not dyn compatible - --> $DIR/kindck-inherited-copy-bound.rs:28:19 - | -LL | let z = &x as &dyn Foo; - | ^^^^^^^^ `Foo` is not dyn compatible - | -note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit - --> $DIR/kindck-inherited-copy-bound.rs:10:13 - | -LL | trait Foo : Copy { - | --- ^^^^ ...because it requires `Self: Sized` - | | - | this trait is not dyn compatible... - -error[E0038]: the trait `Foo` is not dyn compatible - --> $DIR/kindck-inherited-copy-bound.rs:28:13 - | -LL | let z = &x as &dyn Foo; - | ^^ `Foo` is not dyn compatible - | -note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit - --> $DIR/kindck-inherited-copy-bound.rs:10:13 - | -LL | trait Foo : Copy { - | --- ^^^^ ...because it requires `Self: Sized` - | | - | this trait is not dyn compatible... - = note: required for the cast from `&Box<{integer}>` to `&dyn Foo` - -error: aborting due to 3 previous errors - -Some errors have detailed explanations: E0038, E0277. -For more information about an error, try `rustc --explain E0038`. diff --git a/tests/ui/kindck/kindck-inherited-copy-bound.rs b/tests/ui/kindck/kindck-inherited-copy-bound.rs index 92c2b273c2c15..dd9fea3dcde35 100644 --- a/tests/ui/kindck/kindck-inherited-copy-bound.rs +++ b/tests/ui/kindck/kindck-inherited-copy-bound.rs @@ -1,16 +1,14 @@ // Test that Copy bounds inherited by trait are checked. - use std::any::Any; -trait Foo : Copy { +trait Foo: Copy { fn foo(&self) {} } -impl Foo for T { -} +impl Foo for T {} -fn take_param(foo: &T) { } +fn take_param(foo: &T) {} fn a() { let x: Box<_> = Box::new(3); @@ -24,4 +22,4 @@ fn b() { //~^ ERROR E0038 } -fn main() { } +fn main() {} diff --git a/tests/ui/kindck/kindck-inherited-copy-bound.stderr b/tests/ui/kindck/kindck-inherited-copy-bound.stderr index c15aabacddd17..d6c9cab5b57a7 100644 --- a/tests/ui/kindck/kindck-inherited-copy-bound.stderr +++ b/tests/ui/kindck/kindck-inherited-copy-bound.stderr @@ -1,5 +1,5 @@ error[E0277]: the trait bound `Box<{integer}>: Foo` is not satisfied - --> $DIR/kindck-inherited-copy-bound.rs:17:16 + --> $DIR/kindck-inherited-copy-bound.rs:15:16 | LL | take_param(&x); | ---------- ^^ the trait `Copy` is not implemented for `Box<{integer}>` @@ -7,30 +7,30 @@ LL | take_param(&x); | required by a bound introduced by this call | note: required for `Box<{integer}>` to implement `Foo` - --> $DIR/kindck-inherited-copy-bound.rs:10:14 + --> $DIR/kindck-inherited-copy-bound.rs:9:15 | -LL | impl Foo for T { - | ---- ^^^ ^ - | | - | unsatisfied trait bound introduced here +LL | impl Foo for T {} + | ---- ^^^ ^ + | | + | unsatisfied trait bound introduced here note: required by a bound in `take_param` - --> $DIR/kindck-inherited-copy-bound.rs:13:17 + --> $DIR/kindck-inherited-copy-bound.rs:11:18 | -LL | fn take_param(foo: &T) { } - | ^^^ required by this bound in `take_param` +LL | fn take_param(foo: &T) {} + | ^^^ required by this bound in `take_param` error[E0038]: the trait `Foo` is not dyn compatible - --> $DIR/kindck-inherited-copy-bound.rs:23:24 + --> $DIR/kindck-inherited-copy-bound.rs:21:24 | LL | let z = &x as &dyn Foo; | ^^^ `Foo` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable for more information, visit - --> $DIR/kindck-inherited-copy-bound.rs:6:13 + --> $DIR/kindck-inherited-copy-bound.rs:5:12 | -LL | trait Foo : Copy { - | --- ^^^^ ...because it requires `Self: Sized` +LL | trait Foo: Copy { + | --- ^^^^ ...because it requires `Self: Sized` | | | this trait is not dyn compatible... diff --git a/tests/ui/kindck/kindck-nonsendable-1.rs b/tests/ui/kindck/kindck-nonsendable-1.rs index b32fd78624b8e..78ef834afabdb 100644 --- a/tests/ui/kindck/kindck-nonsendable-1.rs +++ b/tests/ui/kindck/kindck-nonsendable-1.rs @@ -2,10 +2,10 @@ use std::rc::Rc; fn foo(_x: Rc) {} -fn bar(_: F) { } +fn bar(_: F) {} fn main() { let x = Rc::new(3); - bar(move|| foo(x)); + bar(move || foo(x)); //~^ ERROR `Rc` cannot be sent between threads safely } diff --git a/tests/ui/kindck/kindck-nonsendable-1.stderr b/tests/ui/kindck/kindck-nonsendable-1.stderr index 8bb784d1d4966..4bf8e17e3ed96 100644 --- a/tests/ui/kindck/kindck-nonsendable-1.stderr +++ b/tests/ui/kindck/kindck-nonsendable-1.stderr @@ -1,24 +1,24 @@ error[E0277]: `Rc` cannot be sent between threads safely --> $DIR/kindck-nonsendable-1.rs:9:9 | -LL | bar(move|| foo(x)); - | --- ------^^^^^^^ +LL | bar(move || foo(x)); + | --- -------^^^^^^^ | | | | | `Rc` cannot be sent between threads safely - | | within this `{closure@$DIR/kindck-nonsendable-1.rs:9:9: 9:15}` + | | within this `{closure@$DIR/kindck-nonsendable-1.rs:9:9: 9:16}` | required by a bound introduced by this call | - = help: within `{closure@$DIR/kindck-nonsendable-1.rs:9:9: 9:15}`, the trait `Send` is not implemented for `Rc` + = help: within `{closure@$DIR/kindck-nonsendable-1.rs:9:9: 9:16}`, the trait `Send` is not implemented for `Rc` note: required because it's used within this closure --> $DIR/kindck-nonsendable-1.rs:9:9 | -LL | bar(move|| foo(x)); - | ^^^^^^ +LL | bar(move || foo(x)); + | ^^^^^^^ note: required by a bound in `bar` - --> $DIR/kindck-nonsendable-1.rs:5:21 + --> $DIR/kindck-nonsendable-1.rs:5:22 | -LL | fn bar(_: F) { } - | ^^^^ required by this bound in `bar` +LL | fn bar(_: F) {} + | ^^^^ required by this bound in `bar` error: aborting due to 1 previous error From 62b9fa15e72e613c1e318e895b84bf593768f9db Mon Sep 17 00:00:00 2001 From: cyrgani Date: Tue, 17 Mar 2026 22:02:05 +0000 Subject: [PATCH 14/22] move tests from `ui/kindck` to `ui/traits` --- tests/ui/README.md | 4 -- .../basic-copyable-types.rs} | 0 .../basic-copyable-types.stderr} | 46 +++++++++---------- .../closure-rc-not-send.rs} | 0 .../closure-rc-not-send.stderr} | 10 ++-- .../copy-bounds-impl-type-params.rs} | 0 .../copy-bounds-impl-type-params.stderr} | 30 ++++++------ .../inherited-copy-bound.rs} | 0 .../inherited-copy-bound.stderr} | 10 ++-- .../send-trait-objects-basic.rs | 0 .../send-trait-objects-basic.stderr | 0 11 files changed, 48 insertions(+), 52 deletions(-) rename tests/ui/{kindck/kindck-copy.rs => traits/basic-copyable-types.rs} (100%) rename tests/ui/{kindck/kindck-copy.stderr => traits/basic-copyable-types.stderr} (83%) rename tests/ui/{kindck/kindck-nonsendable-1.rs => traits/closure-rc-not-send.rs} (100%) rename tests/ui/{kindck/kindck-nonsendable-1.stderr => traits/closure-rc-not-send.stderr} (66%) rename tests/ui/{kindck/kindck-impl-type-params.rs => traits/copy-bounds-impl-type-params.rs} (100%) rename tests/ui/{kindck/kindck-impl-type-params.stderr => traits/copy-bounds-impl-type-params.stderr} (86%) rename tests/ui/{kindck/kindck-inherited-copy-bound.rs => traits/inherited-copy-bound.rs} (100%) rename tests/ui/{kindck/kindck-inherited-copy-bound.stderr => traits/inherited-copy-bound.stderr} (83%) rename tests/ui/{kindck => traits}/send-trait-objects-basic.rs (100%) rename tests/ui/{kindck => traits}/send-trait-objects-basic.stderr (100%) diff --git a/tests/ui/README.md b/tests/ui/README.md index 848df58f27143..845f02918de92 100644 --- a/tests/ui/README.md +++ b/tests/ui/README.md @@ -784,10 +784,6 @@ These tests revolve around the `--json` compiler flag. See [JSON Output](https:/ Tests exercising keywords, such as attempting to use them as identifiers when not contextual keywords. -## `tests/ui/kindck/` - -**FIXME**: `kindck` is no longer a thing, these tests probably need to be audited and rehomed. - ## `tests/ui/label/` Exercises block and loop `'label`s. diff --git a/tests/ui/kindck/kindck-copy.rs b/tests/ui/traits/basic-copyable-types.rs similarity index 100% rename from tests/ui/kindck/kindck-copy.rs rename to tests/ui/traits/basic-copyable-types.rs diff --git a/tests/ui/kindck/kindck-copy.stderr b/tests/ui/traits/basic-copyable-types.stderr similarity index 83% rename from tests/ui/kindck/kindck-copy.stderr rename to tests/ui/traits/basic-copyable-types.stderr index 01b4a5a646476..b4fa957533357 100644 --- a/tests/ui/kindck/kindck-copy.stderr +++ b/tests/ui/traits/basic-copyable-types.stderr @@ -1,11 +1,11 @@ error[E0277]: the trait bound `&'static mut isize: Copy` is not satisfied - --> $DIR/kindck-copy.rs:27:19 + --> $DIR/basic-copyable-types.rs:27:19 | LL | assert_copy::<&'static mut isize>(); | ^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `&'static mut isize` | note: required by a bound in `assert_copy` - --> $DIR/kindck-copy.rs:5:19 + --> $DIR/basic-copyable-types.rs:5:19 | LL | fn assert_copy() {} | ^^^^ required by this bound in `assert_copy` @@ -16,13 +16,13 @@ LL + assert_copy::(); | error[E0277]: the trait bound `&'a mut isize: Copy` is not satisfied - --> $DIR/kindck-copy.rs:28:19 + --> $DIR/basic-copyable-types.rs:28:19 | LL | assert_copy::<&'a mut isize>(); | ^^^^^^^^^^^^^ the trait `Copy` is not implemented for `&'a mut isize` | note: required by a bound in `assert_copy` - --> $DIR/kindck-copy.rs:5:19 + --> $DIR/basic-copyable-types.rs:5:19 | LL | fn assert_copy() {} | ^^^^ required by this bound in `assert_copy` @@ -33,114 +33,114 @@ LL + assert_copy::(); | error[E0277]: the trait bound `Box: Copy` is not satisfied - --> $DIR/kindck-copy.rs:31:19 + --> $DIR/basic-copyable-types.rs:31:19 | LL | assert_copy::>(); | ^^^^^^^^^^ the trait `Copy` is not implemented for `Box` | note: required by a bound in `assert_copy` - --> $DIR/kindck-copy.rs:5:19 + --> $DIR/basic-copyable-types.rs:5:19 | LL | fn assert_copy() {} | ^^^^ required by this bound in `assert_copy` error[E0277]: the trait bound `String: Copy` is not satisfied - --> $DIR/kindck-copy.rs:32:19 + --> $DIR/basic-copyable-types.rs:32:19 | LL | assert_copy::(); | ^^^^^^ the trait `Copy` is not implemented for `String` | note: required by a bound in `assert_copy` - --> $DIR/kindck-copy.rs:5:19 + --> $DIR/basic-copyable-types.rs:5:19 | LL | fn assert_copy() {} | ^^^^ required by this bound in `assert_copy` error[E0277]: the trait bound `Vec: Copy` is not satisfied - --> $DIR/kindck-copy.rs:33:19 + --> $DIR/basic-copyable-types.rs:33:19 | LL | assert_copy::>(); | ^^^^^^^^^^ the trait `Copy` is not implemented for `Vec` | note: required by a bound in `assert_copy` - --> $DIR/kindck-copy.rs:5:19 + --> $DIR/basic-copyable-types.rs:5:19 | LL | fn assert_copy() {} | ^^^^ required by this bound in `assert_copy` error[E0277]: the trait bound `Box<&'a mut isize>: Copy` is not satisfied - --> $DIR/kindck-copy.rs:34:19 + --> $DIR/basic-copyable-types.rs:34:19 | LL | assert_copy::>(); | ^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `Box<&'a mut isize>` | note: required by a bound in `assert_copy` - --> $DIR/kindck-copy.rs:5:19 + --> $DIR/basic-copyable-types.rs:5:19 | LL | fn assert_copy() {} | ^^^^ required by this bound in `assert_copy` error[E0277]: the trait bound `Box: Copy` is not satisfied - --> $DIR/kindck-copy.rs:42:19 + --> $DIR/basic-copyable-types.rs:42:19 | LL | assert_copy::>(); | ^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `Box` | note: required by a bound in `assert_copy` - --> $DIR/kindck-copy.rs:5:19 + --> $DIR/basic-copyable-types.rs:5:19 | LL | fn assert_copy() {} | ^^^^ required by this bound in `assert_copy` error[E0277]: the trait bound `Box: Copy` is not satisfied - --> $DIR/kindck-copy.rs:43:19 + --> $DIR/basic-copyable-types.rs:43:19 | LL | assert_copy::>(); | ^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `Box` | note: required by a bound in `assert_copy` - --> $DIR/kindck-copy.rs:5:19 + --> $DIR/basic-copyable-types.rs:5:19 | LL | fn assert_copy() {} | ^^^^ required by this bound in `assert_copy` error[E0277]: the trait bound `&'a mut (dyn Dummy + Send + 'a): Copy` is not satisfied - --> $DIR/kindck-copy.rs:46:19 + --> $DIR/basic-copyable-types.rs:46:19 | LL | assert_copy::<&'a mut (dyn Dummy + Send)>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `&'a mut (dyn Dummy + Send + 'a)` | note: required by a bound in `assert_copy` - --> $DIR/kindck-copy.rs:5:19 + --> $DIR/basic-copyable-types.rs:5:19 | LL | fn assert_copy() {} | ^^^^ required by this bound in `assert_copy` error[E0277]: the trait bound `MyNoncopyStruct: Copy` is not satisfied - --> $DIR/kindck-copy.rs:64:19 + --> $DIR/basic-copyable-types.rs:64:19 | LL | assert_copy::(); | ^^^^^^^^^^^^^^^ unsatisfied trait bound | help: the trait `Copy` is not implemented for `MyNoncopyStruct` - --> $DIR/kindck-copy.rs:15:1 + --> $DIR/basic-copyable-types.rs:15:1 | LL | struct MyNoncopyStruct { | ^^^^^^^^^^^^^^^^^^^^^^ note: required by a bound in `assert_copy` - --> $DIR/kindck-copy.rs:5:19 + --> $DIR/basic-copyable-types.rs:5:19 | LL | fn assert_copy() {} | ^^^^ required by this bound in `assert_copy` error[E0277]: the trait bound `Rc: Copy` is not satisfied - --> $DIR/kindck-copy.rs:67:19 + --> $DIR/basic-copyable-types.rs:67:19 | LL | assert_copy::>(); | ^^^^^^^^^ the trait `Copy` is not implemented for `Rc` | note: required by a bound in `assert_copy` - --> $DIR/kindck-copy.rs:5:19 + --> $DIR/basic-copyable-types.rs:5:19 | LL | fn assert_copy() {} | ^^^^ required by this bound in `assert_copy` diff --git a/tests/ui/kindck/kindck-nonsendable-1.rs b/tests/ui/traits/closure-rc-not-send.rs similarity index 100% rename from tests/ui/kindck/kindck-nonsendable-1.rs rename to tests/ui/traits/closure-rc-not-send.rs diff --git a/tests/ui/kindck/kindck-nonsendable-1.stderr b/tests/ui/traits/closure-rc-not-send.stderr similarity index 66% rename from tests/ui/kindck/kindck-nonsendable-1.stderr rename to tests/ui/traits/closure-rc-not-send.stderr index 4bf8e17e3ed96..5e73f13648d5c 100644 --- a/tests/ui/kindck/kindck-nonsendable-1.stderr +++ b/tests/ui/traits/closure-rc-not-send.stderr @@ -1,21 +1,21 @@ error[E0277]: `Rc` cannot be sent between threads safely - --> $DIR/kindck-nonsendable-1.rs:9:9 + --> $DIR/closure-rc-not-send.rs:9:9 | LL | bar(move || foo(x)); | --- -------^^^^^^^ | | | | | `Rc` cannot be sent between threads safely - | | within this `{closure@$DIR/kindck-nonsendable-1.rs:9:9: 9:16}` + | | within this `{closure@$DIR/closure-rc-not-send.rs:9:9: 9:16}` | required by a bound introduced by this call | - = help: within `{closure@$DIR/kindck-nonsendable-1.rs:9:9: 9:16}`, the trait `Send` is not implemented for `Rc` + = help: within `{closure@$DIR/closure-rc-not-send.rs:9:9: 9:16}`, the trait `Send` is not implemented for `Rc` note: required because it's used within this closure - --> $DIR/kindck-nonsendable-1.rs:9:9 + --> $DIR/closure-rc-not-send.rs:9:9 | LL | bar(move || foo(x)); | ^^^^^^^ note: required by a bound in `bar` - --> $DIR/kindck-nonsendable-1.rs:5:22 + --> $DIR/closure-rc-not-send.rs:5:22 | LL | fn bar(_: F) {} | ^^^^ required by this bound in `bar` diff --git a/tests/ui/kindck/kindck-impl-type-params.rs b/tests/ui/traits/copy-bounds-impl-type-params.rs similarity index 100% rename from tests/ui/kindck/kindck-impl-type-params.rs rename to tests/ui/traits/copy-bounds-impl-type-params.rs diff --git a/tests/ui/kindck/kindck-impl-type-params.stderr b/tests/ui/traits/copy-bounds-impl-type-params.stderr similarity index 86% rename from tests/ui/kindck/kindck-impl-type-params.stderr rename to tests/ui/traits/copy-bounds-impl-type-params.stderr index b2e52ae57ea4a..08fde8fb5df35 100644 --- a/tests/ui/kindck/kindck-impl-type-params.stderr +++ b/tests/ui/traits/copy-bounds-impl-type-params.stderr @@ -1,11 +1,11 @@ error[E0277]: `T` cannot be sent between threads safely - --> $DIR/kindck-impl-type-params.rs:18:13 + --> $DIR/copy-bounds-impl-type-params.rs:18:13 | LL | let a = &t as &dyn Gettable; | ^^ `T` cannot be sent between threads safely | note: required for `S` to implement `Gettable` - --> $DIR/kindck-impl-type-params.rs:14:32 + --> $DIR/copy-bounds-impl-type-params.rs:14:32 | LL | impl Gettable for S {} | ---- ^^^^^^^^^^^ ^^^^ @@ -18,13 +18,13 @@ LL | fn f(val: T) { | +++++++++++++++++++ error[E0277]: the trait bound `T: Copy` is not satisfied - --> $DIR/kindck-impl-type-params.rs:18:13 + --> $DIR/copy-bounds-impl-type-params.rs:18:13 | LL | let a = &t as &dyn Gettable; | ^^ the trait `Copy` is not implemented for `T` | note: required for `S` to implement `Gettable` - --> $DIR/kindck-impl-type-params.rs:14:32 + --> $DIR/copy-bounds-impl-type-params.rs:14:32 | LL | impl Gettable for S {} | ---- ^^^^^^^^^^^ ^^^^ @@ -37,13 +37,13 @@ LL | fn f(val: T) { | +++++++++++++++++++ error[E0277]: `T` cannot be sent between threads safely - --> $DIR/kindck-impl-type-params.rs:25:31 + --> $DIR/copy-bounds-impl-type-params.rs:25:31 | LL | let a: &dyn Gettable = &t; | ^^ `T` cannot be sent between threads safely | note: required for `S` to implement `Gettable` - --> $DIR/kindck-impl-type-params.rs:14:32 + --> $DIR/copy-bounds-impl-type-params.rs:14:32 | LL | impl Gettable for S {} | ---- ^^^^^^^^^^^ ^^^^ @@ -56,13 +56,13 @@ LL | fn g(val: T) { | +++++++++++++++++++ error[E0277]: the trait bound `T: Copy` is not satisfied - --> $DIR/kindck-impl-type-params.rs:25:31 + --> $DIR/copy-bounds-impl-type-params.rs:25:31 | LL | let a: &dyn Gettable = &t; | ^^ the trait `Copy` is not implemented for `T` | note: required for `S` to implement `Gettable` - --> $DIR/kindck-impl-type-params.rs:14:32 + --> $DIR/copy-bounds-impl-type-params.rs:14:32 | LL | impl Gettable for S {} | ---- ^^^^^^^^^^^ ^^^^ @@ -75,18 +75,18 @@ LL | fn g(val: T) { | +++++++++++++++++++ error[E0277]: the trait bound `String: Copy` is not satisfied - --> $DIR/kindck-impl-type-params.rs:38:13 + --> $DIR/copy-bounds-impl-type-params.rs:38:13 | LL | let a = t as Box>; | ^ the trait `Copy` is not implemented for `String` | help: the trait `Gettable` is implemented for `S` - --> $DIR/kindck-impl-type-params.rs:14:1 + --> $DIR/copy-bounds-impl-type-params.rs:14:1 | LL | impl Gettable for S {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: required for `S` to implement `Gettable` - --> $DIR/kindck-impl-type-params.rs:14:32 + --> $DIR/copy-bounds-impl-type-params.rs:14:32 | LL | impl Gettable for S {} | ---- ^^^^^^^^^^^ ^^^^ @@ -95,18 +95,18 @@ LL | impl Gettable for S {} = note: required for the cast from `Box>` to `Box>` error[E0277]: the trait bound `Foo: Copy` is not satisfied - --> $DIR/kindck-impl-type-params.rs:46:37 + --> $DIR/copy-bounds-impl-type-params.rs:46:37 | LL | let a: Box> = t; | ^ the trait `Copy` is not implemented for `Foo` | help: the trait `Gettable` is implemented for `S` - --> $DIR/kindck-impl-type-params.rs:14:1 + --> $DIR/copy-bounds-impl-type-params.rs:14:1 | LL | impl Gettable for S {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: required for `S` to implement `Gettable` - --> $DIR/kindck-impl-type-params.rs:14:32 + --> $DIR/copy-bounds-impl-type-params.rs:14:32 | LL | impl Gettable for S {} | ---- ^^^^^^^^^^^ ^^^^ @@ -120,7 +120,7 @@ LL | struct Foo; // does not impl Copy | error: lifetime may not live long enough - --> $DIR/kindck-impl-type-params.rs:32:13 + --> $DIR/copy-bounds-impl-type-params.rs:32:13 | LL | fn foo<'a>() { | -- lifetime `'a` defined here diff --git a/tests/ui/kindck/kindck-inherited-copy-bound.rs b/tests/ui/traits/inherited-copy-bound.rs similarity index 100% rename from tests/ui/kindck/kindck-inherited-copy-bound.rs rename to tests/ui/traits/inherited-copy-bound.rs diff --git a/tests/ui/kindck/kindck-inherited-copy-bound.stderr b/tests/ui/traits/inherited-copy-bound.stderr similarity index 83% rename from tests/ui/kindck/kindck-inherited-copy-bound.stderr rename to tests/ui/traits/inherited-copy-bound.stderr index d6c9cab5b57a7..c251d59224463 100644 --- a/tests/ui/kindck/kindck-inherited-copy-bound.stderr +++ b/tests/ui/traits/inherited-copy-bound.stderr @@ -1,5 +1,5 @@ error[E0277]: the trait bound `Box<{integer}>: Foo` is not satisfied - --> $DIR/kindck-inherited-copy-bound.rs:15:16 + --> $DIR/inherited-copy-bound.rs:15:16 | LL | take_param(&x); | ---------- ^^ the trait `Copy` is not implemented for `Box<{integer}>` @@ -7,27 +7,27 @@ LL | take_param(&x); | required by a bound introduced by this call | note: required for `Box<{integer}>` to implement `Foo` - --> $DIR/kindck-inherited-copy-bound.rs:9:15 + --> $DIR/inherited-copy-bound.rs:9:15 | LL | impl Foo for T {} | ---- ^^^ ^ | | | unsatisfied trait bound introduced here note: required by a bound in `take_param` - --> $DIR/kindck-inherited-copy-bound.rs:11:18 + --> $DIR/inherited-copy-bound.rs:11:18 | LL | fn take_param(foo: &T) {} | ^^^ required by this bound in `take_param` error[E0038]: the trait `Foo` is not dyn compatible - --> $DIR/kindck-inherited-copy-bound.rs:21:24 + --> $DIR/inherited-copy-bound.rs:21:24 | LL | let z = &x as &dyn Foo; | ^^^ `Foo` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable for more information, visit - --> $DIR/kindck-inherited-copy-bound.rs:5:12 + --> $DIR/inherited-copy-bound.rs:5:12 | LL | trait Foo: Copy { | --- ^^^^ ...because it requires `Self: Sized` diff --git a/tests/ui/kindck/send-trait-objects-basic.rs b/tests/ui/traits/send-trait-objects-basic.rs similarity index 100% rename from tests/ui/kindck/send-trait-objects-basic.rs rename to tests/ui/traits/send-trait-objects-basic.rs diff --git a/tests/ui/kindck/send-trait-objects-basic.stderr b/tests/ui/traits/send-trait-objects-basic.stderr similarity index 100% rename from tests/ui/kindck/send-trait-objects-basic.stderr rename to tests/ui/traits/send-trait-objects-basic.stderr From eda328c6cfce47bb99d2daba946bf938dad8f78e Mon Sep 17 00:00:00 2001 From: cyrgani Date: Tue, 17 Mar 2026 22:08:51 +0000 Subject: [PATCH 15/22] delete incorrect test --- .../kindck-implicit-close-over-mut-var.rs | 49 ------------------- 1 file changed, 49 deletions(-) delete mode 100644 tests/ui/borrowck/kindck-implicit-close-over-mut-var.rs diff --git a/tests/ui/borrowck/kindck-implicit-close-over-mut-var.rs b/tests/ui/borrowck/kindck-implicit-close-over-mut-var.rs deleted file mode 100644 index 22ed8bd3beefa..0000000000000 --- a/tests/ui/borrowck/kindck-implicit-close-over-mut-var.rs +++ /dev/null @@ -1,49 +0,0 @@ -//@ run-pass - -#![allow(unused_must_use)] -#![allow(dead_code)] -use std::thread; - -fn user(_i: isize) {} - -fn foo() { - // Here, i is *copied* into the proc (heap closure). - // Requires allocation. The proc's copy is not mutable. - let mut i = 0; - let t = thread::spawn(move|| { - user(i); - println!("spawned {}", i) - }); - i += 1; - println!("original {}", i); - t.join(); -} - -fn bar() { - // Here, the original i has not been moved, only copied, so is still - // mutable outside of the proc. - let mut i = 0; - while i < 10 { - let t = thread::spawn(move|| { - user(i); - }); - i += 1; - t.join(); - } -} - -fn car() { - // Here, i must be shadowed in the proc to be mutable. - let mut i = 0; - while i < 10 { - let t = thread::spawn(move|| { - let mut i = i; - i += 1; - user(i); - }); - i += 1; - t.join(); - } -} - -pub fn main() {} From a4d23841001ace656ed84df9792f257830f44fa3 Mon Sep 17 00:00:00 2001 From: Jynn Nelson Date: Wed, 18 Mar 2026 12:21:09 +0100 Subject: [PATCH 16/22] Move hashes into a separate json file --- src/bootstrap/src/core/build_steps/setup.rs | 66 ++++--------------- .../src/core/build_steps/setup/hashes.json | 53 +++++++++++++++ .../src/core/build_steps/setup/tests.rs | 10 ++- 3 files changed, 69 insertions(+), 60 deletions(-) create mode 100644 src/bootstrap/src/core/build_steps/setup/hashes.json diff --git a/src/bootstrap/src/core/build_steps/setup.rs b/src/bootstrap/src/core/build_steps/setup.rs index f4e6a20ec8497..1854637fc93ba 100644 --- a/src/bootstrap/src/core/build_steps/setup.rs +++ b/src/bootstrap/src/core/build_steps/setup.rs @@ -12,7 +12,10 @@ use std::io::Write; use std::path::{MAIN_SEPARATOR_STR, Path, PathBuf}; use std::str::FromStr; use std::{fmt, fs, io}; +use std::collections::HashMap; +use std::sync::LazyLock; +use serde_derive::Deserialize; use sha2::Digest; use crate::core::builder::{Builder, RunConfig, ShouldRun, Step}; @@ -529,7 +532,8 @@ undesirable, simply delete the `pre-push` file from .git/hooks." } /// Handles editor-specific setup differences -#[derive(Clone, Debug, Eq, PartialEq)] +#[derive(Clone, Debug, Eq, PartialEq, Hash, Deserialize)] +#[serde(rename_all = "lowercase")] enum EditorKind { Emacs, Helix, @@ -588,59 +592,13 @@ Select which editor you would like to set up [default: None]: "; /// New entries should be appended whenever this is updated so we can detect /// outdated vs. user-modified settings files. fn hashes(&self) -> &'static [&'static str] { - match self { - EditorKind::Emacs => &[ - "51068d4747a13732440d1a8b8f432603badb1864fa431d83d0fd4f8fa57039e0", - "d29af4d949bbe2371eac928a3c31cf9496b1701aa1c45f11cd6c759865ad5c45", - "b5dd299b93dca3ceeb9b335f929293cb3d4bf4977866fbe7ceeac2a8a9f99088", - "631c837b0e98ae35fd48b0e5f743b1ca60adadf2d0a2b23566ba25df372cf1a9", - "080955765db84bb6cbf178879f489c4e2369397626a6ecb3debedb94a9d0b3ce", - "f501475c6654187091c924ae26187fa5791d74d4a8ab3fb61fbbe4c0275aade1", - "54bc48fe1996177f5eef86d7231b33978e6d8b737cb0a899e622b7e975c95308", - "08d30e455ceec6e01d9bcef8b9449f2ddd14d278ca8627cdad90e02d9f44e938", - ], - EditorKind::Helix => &[ - "2d3069b8cf1b977e5d4023965eb6199597755e6c96c185ed5f2854f98b83d233", - "6736d61409fbebba0933afd2e4c44ff2f97c1cb36cf0299a7f4a7819b8775040", - "f252dcc30ca85a193a699581e5e929d5bd6c19d40d7a7ade5e257a9517a124a5", - "198c195ed0c070d15907b279b8b4ea96198ca71b939f5376454f3d636ab54da5", - "1c43ead340b20792b91d02b08494ee68708e7e09f56b6766629b4b72079208f1", - "eec09a09452682060afd23dd5d3536ccac5615b3cdbf427366446901215fb9f6", - "cb653043852d9d5ff4a5be56407b859ff9928be055ad3f307eb309aad04765e6", - "e28b1930d16d3d8bbdeed7bd4a995613e648b49e08c9b6f5271880f520637fed", - ], - EditorKind::Vim | EditorKind::VsCode => &[ - "ea67e259dedf60d4429b6c349a564ffcd1563cf41c920a856d1f5b16b4701ac8", - "56e7bf011c71c5d81e0bf42e84938111847a810eee69d906bba494ea90b51922", - "af1b5efe196aed007577899db9dae15d6dbc923d6fa42fa0934e68617ba9bbe0", - "3468fea433c25fff60be6b71e8a215a732a7b1268b6a83bf10d024344e140541", - "47d227f424bf889b0d899b9cc992d5695e1b78c406e183cd78eafefbe5488923", - "b526bd58d0262dd4dda2bff5bc5515b705fb668a46235ace3e057f807963a11a", - "828666b021d837a33e78d870b56d34c88a5e2c85de58b693607ec574f0c27000", - "811fb3b063c739d261fd8590dd30242e117908f5a095d594fa04585daa18ec4d", - "4eecb58a2168b252077369da446c30ed0e658301efe69691979d1ef0443928f4", - "c394386e6133bbf29ffd32c8af0bb3d4aac354cba9ee051f29612aa9350f8f8d", - "e53e9129ca5ee5dcbd6ec8b68c2d87376474eb154992deba3c6d9ab1703e0717", - "f954316090936c7e590c253ca9d524008375882fa13c5b41d7e2547a896ff893", - "701b73751efd7abd6487f2c79348dab698af7ac4427b79fa3d2087c867144b12", - "a61df796c0c007cb6512127330564e49e57d558dec715703916a928b072a1054", - "02a49ac2d31f00ef6e4531c44e00dac51cea895112e480553f1ba060b3942a47", - "0aa4748848de0d1cb7ece92a0123c8897fef6de2f58aff8fda1426f098b7a798", - "e5e357862e5d6d0d9da335e9823c07b8a7dc42bbf18d72cc5206ad1049cd8fcc", - "a68fd5828e75f3e921f265e29ce1e9efa554083c3773fdb4b8e1ab3b2d9dc6cd", - ], - EditorKind::Zed => &[ - "bbce727c269d1bd0c98afef4d612eb4ce27aea3c3a8968c5f10b31affbc40b6c", - "a5380cf5dd9328731aecc5dfb240d16dac46ed272126b9728006151ef42f5909", - "2e96bf0d443852b12f016c8fc9840ab3d0a2b4fe0b0fb3a157e8d74d5e7e0e26", - "4fadd4c87389a601a27db0d3d74a142fa3a2e656ae78982e934dbe24bee32ad6", - "f0bb3d23ab1a49175ab0ef5c4071af95bb03d01d460776cdb716d91333443382", - "5ef83292111d9a8bb63b6afc3abf42d0bc78fe24985f0d2e039e73258b5dab8f", - "74420c13094b530a986b37c4f1d23cb58c0e8e2295f5858ded129fb1574e66f9", - "2d3b592c089b2ad2c528686a1e371af49922edad1c59accd5d5f31612a441568", - "0767a2398ccc253274b184adbb9e018ce931bd0ef45baad06dad19b652c52951", - ], - } + const ALL_HASHES: &str = include_str!("setup/hashes.json"); + static PARSED_HASHES: LazyLock>> = LazyLock::new(|| { + let mut map: HashMap<_, Vec<_>> = serde_json::from_str(ALL_HASHES).unwrap(); + map.insert(EditorKind::Vim, map.get(&EditorKind::VsCode).unwrap().clone()); + map + }); + &*PARSED_HASHES.get(self).unwrap() } fn settings_path(&self, config: &Config) -> PathBuf { diff --git a/src/bootstrap/src/core/build_steps/setup/hashes.json b/src/bootstrap/src/core/build_steps/setup/hashes.json new file mode 100644 index 0000000000000..be657b5772002 --- /dev/null +++ b/src/bootstrap/src/core/build_steps/setup/hashes.json @@ -0,0 +1,53 @@ +{ + "emacs": [ + "51068d4747a13732440d1a8b8f432603badb1864fa431d83d0fd4f8fa57039e0", + "d29af4d949bbe2371eac928a3c31cf9496b1701aa1c45f11cd6c759865ad5c45", + "b5dd299b93dca3ceeb9b335f929293cb3d4bf4977866fbe7ceeac2a8a9f99088", + "631c837b0e98ae35fd48b0e5f743b1ca60adadf2d0a2b23566ba25df372cf1a9", + "080955765db84bb6cbf178879f489c4e2369397626a6ecb3debedb94a9d0b3ce", + "f501475c6654187091c924ae26187fa5791d74d4a8ab3fb61fbbe4c0275aade1", + "54bc48fe1996177f5eef86d7231b33978e6d8b737cb0a899e622b7e975c95308", + "08d30e455ceec6e01d9bcef8b9449f2ddd14d278ca8627cdad90e02d9f44e938" + ], + "helix": [ + "2d3069b8cf1b977e5d4023965eb6199597755e6c96c185ed5f2854f98b83d233", + "6736d61409fbebba0933afd2e4c44ff2f97c1cb36cf0299a7f4a7819b8775040", + "f252dcc30ca85a193a699581e5e929d5bd6c19d40d7a7ade5e257a9517a124a5", + "198c195ed0c070d15907b279b8b4ea96198ca71b939f5376454f3d636ab54da5", + "1c43ead340b20792b91d02b08494ee68708e7e09f56b6766629b4b72079208f1", + "eec09a09452682060afd23dd5d3536ccac5615b3cdbf427366446901215fb9f6", + "cb653043852d9d5ff4a5be56407b859ff9928be055ad3f307eb309aad04765e6", + "e28b1930d16d3d8bbdeed7bd4a995613e648b49e08c9b6f5271880f520637fed" + ], + "vscode": [ + "ea67e259dedf60d4429b6c349a564ffcd1563cf41c920a856d1f5b16b4701ac8", + "56e7bf011c71c5d81e0bf42e84938111847a810eee69d906bba494ea90b51922", + "af1b5efe196aed007577899db9dae15d6dbc923d6fa42fa0934e68617ba9bbe0", + "3468fea433c25fff60be6b71e8a215a732a7b1268b6a83bf10d024344e140541", + "47d227f424bf889b0d899b9cc992d5695e1b78c406e183cd78eafefbe5488923", + "b526bd58d0262dd4dda2bff5bc5515b705fb668a46235ace3e057f807963a11a", + "828666b021d837a33e78d870b56d34c88a5e2c85de58b693607ec574f0c27000", + "811fb3b063c739d261fd8590dd30242e117908f5a095d594fa04585daa18ec4d", + "4eecb58a2168b252077369da446c30ed0e658301efe69691979d1ef0443928f4", + "c394386e6133bbf29ffd32c8af0bb3d4aac354cba9ee051f29612aa9350f8f8d", + "e53e9129ca5ee5dcbd6ec8b68c2d87376474eb154992deba3c6d9ab1703e0717", + "f954316090936c7e590c253ca9d524008375882fa13c5b41d7e2547a896ff893", + "701b73751efd7abd6487f2c79348dab698af7ac4427b79fa3d2087c867144b12", + "a61df796c0c007cb6512127330564e49e57d558dec715703916a928b072a1054", + "02a49ac2d31f00ef6e4531c44e00dac51cea895112e480553f1ba060b3942a47", + "0aa4748848de0d1cb7ece92a0123c8897fef6de2f58aff8fda1426f098b7a798", + "e5e357862e5d6d0d9da335e9823c07b8a7dc42bbf18d72cc5206ad1049cd8fcc", + "a68fd5828e75f3e921f265e29ce1e9efa554083c3773fdb4b8e1ab3b2d9dc6cd" + ], + "zed": [ + "bbce727c269d1bd0c98afef4d612eb4ce27aea3c3a8968c5f10b31affbc40b6c", + "a5380cf5dd9328731aecc5dfb240d16dac46ed272126b9728006151ef42f5909", + "2e96bf0d443852b12f016c8fc9840ab3d0a2b4fe0b0fb3a157e8d74d5e7e0e26", + "4fadd4c87389a601a27db0d3d74a142fa3a2e656ae78982e934dbe24bee32ad6", + "f0bb3d23ab1a49175ab0ef5c4071af95bb03d01d460776cdb716d91333443382", + "5ef83292111d9a8bb63b6afc3abf42d0bc78fe24985f0d2e039e73258b5dab8f", + "74420c13094b530a986b37c4f1d23cb58c0e8e2295f5858ded129fb1574e66f9", + "2d3b592c089b2ad2c528686a1e371af49922edad1c59accd5d5f31612a441568", + "0767a2398ccc253274b184adbb9e018ce931bd0ef45baad06dad19b652c52951" + ] +} diff --git a/src/bootstrap/src/core/build_steps/setup/tests.rs b/src/bootstrap/src/core/build_steps/setup/tests.rs index e8f83ff75e404..6eafbb40b4674 100644 --- a/src/bootstrap/src/core/build_steps/setup/tests.rs +++ b/src/bootstrap/src/core/build_steps/setup/tests.rs @@ -8,13 +8,11 @@ fn check_matching_settings_hash() { for editor in EditorKind::ALL { let mut hasher = sha2::Sha256::new(); hasher.update(&editor.settings_template()); - let hash = hex_encode(hasher.finalize().as_slice()); + let actual = hex_encode(hasher.finalize().as_slice()); + let expected = *editor.hashes().last().unwrap(); assert_eq!( - &hash, - editor.hashes().last().unwrap(), - "Update `EditorKind::hashes()` with the new hash of `{}` for `EditorKind::{:?}`", - editor.settings_template(), - editor, + expected, actual, + "Update `setup/hashes.json` with the new hash of `{actual}` for `EditorKind::{editor:?}`", ); } } From ca2139d3262232d6b15471783f503ffe125531f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 16 Mar 2026 22:38:16 +0000 Subject: [PATCH 17/22] Point at return type when it is the source of the type expectation When calling an fn that returns a return type as a returned expression, point at the return type to explain that it affects the expected type. ``` error[E0308]: mismatched types --> f56.rs:5:15 | 3 | fn main() { | - the call expression's return type is influenced by this return type 4 | let a = 0; 5 | ptr::read(&a) | --------- ^^ expected `*const ()`, found `&{integer}` | | | arguments to this function are incorrect | = note: expected raw pointer `*const ()` found reference `&{integer}` note: function defined here --> library/core/src/ptr/mod.rs:1681:21 | 1681 | pub const unsafe fn read(src: *const T) -> T { | ^^^^ ``` --- .../rustc_hir_typeck/src/fn_ctxt/checks.rs | 41 ++++++++++++++++++- .../expectation-from-return-type.rs | 21 ++++++++++ .../expectation-from-return-type.stderr | 35 ++++++++++++++++ ...ransforming-option-ref-issue-127545.stderr | 6 +++ ...call-return-type-due-to-generic-arg.stderr | 3 ++ 5 files changed, 105 insertions(+), 1 deletion(-) create mode 100644 tests/ui/mismatched_types/expectation-from-return-type.rs create mode 100644 tests/ui/mismatched_types/expectation-from-return-type.stderr diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index 9faa75e18480d..f53259e91eec1 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -11,7 +11,7 @@ use rustc_hir::attrs::DivergingBlockBehavior; use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res}; use rustc_hir::def_id::DefId; use rustc_hir::intravisit::Visitor; -use rustc_hir::{Expr, ExprKind, HirId, LangItem, Node, QPath, is_range_literal}; +use rustc_hir::{Expr, ExprKind, FnRetTy, HirId, LangItem, Node, QPath, is_range_literal}; use rustc_hir_analysis::check::potentially_plural_count; use rustc_hir_analysis::hir_ty_lowering::{HirTyLowerer, PermitVariants}; use rustc_index::IndexVec; @@ -1587,6 +1587,45 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } err.span_note(spans, format!("{} defined here", self.tcx.def_descr(def_id))); + if let DefKind::Fn | DefKind::AssocFn = self.tcx.def_kind(def_id) + && let ty::Param(_) = + self.tcx.fn_sig(def_id).instantiate_identity().skip_binder().output().kind() + && let parent = self.tcx.hir_get_parent_item(call_expr.hir_id).def_id + && let Some((output, body_id)) = match self.tcx.hir_node_by_def_id(parent) { + hir::Node::Item(hir::Item { + kind: hir::ItemKind::Fn { sig, body, .. }, + .. + }) + | hir::Node::TraitItem(hir::TraitItem { + kind: hir::TraitItemKind::Fn(sig, hir::TraitFn::Provided(body)), + .. + }) + | hir::Node::ImplItem(hir::ImplItem { + kind: hir::ImplItemKind::Fn(sig, body), + .. + }) => Some((sig.decl.output, body)), + _ => None, + } + && let expr = self.tcx.hir_body(*body_id).value + && (expr.peel_blocks().span == call_expr.span + || matches!( + self.tcx.parent_hir_node(call_expr.hir_id), + hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Ret(_), .. }) + )) + { + err.span_label( + output.span(), + match output { + FnRetTy::DefaultReturn(_) => format!( + "this implicit `()` return type influences the call expression's return type" + ), + FnRetTy::Return(_) => { + "this return type influences the call expression's return type" + .to_string() + } + }, + ); + } } else if let Some(hir::Node::Expr(e)) = self.tcx.hir_get_if_local(def_id) && let hir::ExprKind::Closure(hir::Closure { body, .. }) = &e.kind { diff --git a/tests/ui/mismatched_types/expectation-from-return-type.rs b/tests/ui/mismatched_types/expectation-from-return-type.rs new file mode 100644 index 0000000000000..ffe3d929984df --- /dev/null +++ b/tests/ui/mismatched_types/expectation-from-return-type.rs @@ -0,0 +1,21 @@ +use std::ptr; + +fn main() { //~ NOTE: this implicit `()` return type influences the call expression's return type + let a = 0; + ptr::read(&a) + //~^ ERROR: mismatched types + //~| NOTE: expected `*const ()`, found `&{integer}` + //~| NOTE: arguments to this function are incorrect + //~| NOTE: expected raw pointer + //~| NOTE: function defined here +} + +fn foo() { //~ NOTE: this implicit `()` return type influences the call expression's return type + let a = 0; + return ptr::read(&a); + //~^ ERROR: mismatched types + //~| NOTE: expected `*const ()`, found `&{integer}` + //~| NOTE: arguments to this function are incorrect + //~| NOTE: expected raw pointer + //~| NOTE: function defined here +} diff --git a/tests/ui/mismatched_types/expectation-from-return-type.stderr b/tests/ui/mismatched_types/expectation-from-return-type.stderr new file mode 100644 index 0000000000000..3bd7a21f987fc --- /dev/null +++ b/tests/ui/mismatched_types/expectation-from-return-type.stderr @@ -0,0 +1,35 @@ +error[E0308]: mismatched types + --> $DIR/expectation-from-return-type.rs:5:15 + | +LL | fn main() { + | - this implicit `()` return type influences the call expression's return type +LL | let a = 0; +LL | ptr::read(&a) + | --------- ^^ expected `*const ()`, found `&{integer}` + | | + | arguments to this function are incorrect + | + = note: expected raw pointer `*const ()` + found reference `&{integer}` +note: function defined here + --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL + +error[E0308]: mismatched types + --> $DIR/expectation-from-return-type.rs:15:22 + | +LL | fn foo() { + | - this implicit `()` return type influences the call expression's return type +LL | let a = 0; +LL | return ptr::read(&a); + | --------- ^^ expected `*const ()`, found `&{integer}` + | | + | arguments to this function are incorrect + | + = note: expected raw pointer `*const ()` + found reference `&{integer}` +note: function defined here + --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/mismatched_types/transforming-option-ref-issue-127545.stderr b/tests/ui/mismatched_types/transforming-option-ref-issue-127545.stderr index 9a18798db2139..6243a9a729a2f 100644 --- a/tests/ui/mismatched_types/transforming-option-ref-issue-127545.stderr +++ b/tests/ui/mismatched_types/transforming-option-ref-issue-127545.stderr @@ -16,6 +16,8 @@ LL | arg.map(|v| &**v) error[E0308]: mismatched types --> $DIR/transforming-option-ref-issue-127545.rs:9:19 | +LL | pub fn bar(arg: Option<&Vec>) -> &[i32] { + | ------ this return type influences the call expression's return type LL | arg.unwrap_or(&[]) | --------- ^^^ expected `&Vec`, found `&[_; 0]` | | @@ -41,6 +43,8 @@ LL + arg.map_or(&[], |v| v) error[E0308]: mismatched types --> $DIR/transforming-option-ref-issue-127545.rs:13:19 | +LL | pub fn barzz<'a>(arg: Option<&'a Vec>, v: &'a [i32]) -> &'a [i32] { + | --------- this return type influences the call expression's return type LL | arg.unwrap_or(v) | --------- ^ expected `&Vec`, found `&[i32]` | | @@ -66,6 +70,8 @@ LL + arg.map_or(v, |v| v) error[E0308]: mismatched types --> $DIR/transforming-option-ref-issue-127545.rs:17:19 | +LL | pub fn convert_result(arg: Result<&Vec, ()>) -> &[i32] { + | ------ this return type influences the call expression's return type LL | arg.unwrap_or(&[]) | --------- ^^^ expected `&Vec`, found `&[_; 0]` | | diff --git a/tests/ui/type/wrong-call-return-type-due-to-generic-arg.stderr b/tests/ui/type/wrong-call-return-type-due-to-generic-arg.stderr index 53920bc9e02ec..fd07d5b09aeb0 100644 --- a/tests/ui/type/wrong-call-return-type-due-to-generic-arg.stderr +++ b/tests/ui/type/wrong-call-return-type-due-to-generic-arg.stderr @@ -112,6 +112,9 @@ LL + let x: u16 = (S {}).method(0u16); error[E0308]: arguments to this function are incorrect --> $DIR/wrong-call-return-type-due-to-generic-arg.rs:27:5 | +LL | fn main() { + | - this implicit `()` return type influences the call expression's return type +... LL | function(0u32, 8u8) | ^^^^^^^^ ---- --- expected `bool`, found `u8` | | From 1098a9d032d96d4509f2f9c3a20a5f1959f40440 Mon Sep 17 00:00:00 2001 From: Jynn Nelson Date: Wed, 18 Mar 2026 13:35:58 +0100 Subject: [PATCH 18/22] Support `--bless`-ing editor hashes --- src/bootstrap/src/core/build_steps/setup.rs | 23 ++-- .../src/core/build_steps/setup/hashes.json | 122 ++++++++++-------- .../src/core/build_steps/setup/tests.rs | 40 +++++- 3 files changed, 119 insertions(+), 66 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/setup.rs b/src/bootstrap/src/core/build_steps/setup.rs index 1854637fc93ba..85c23ac18e763 100644 --- a/src/bootstrap/src/core/build_steps/setup.rs +++ b/src/bootstrap/src/core/build_steps/setup.rs @@ -5,17 +5,17 @@ //! allows setting up things that cannot be simply captured inside the bootstrap.toml, in addition to //! leading people away from manually editing most of the bootstrap.toml values. +use std::collections::BTreeMap; use std::env::consts::EXE_SUFFIX; use std::fmt::Write as _; use std::fs::File; use std::io::Write; use std::path::{MAIN_SEPARATOR_STR, Path, PathBuf}; use std::str::FromStr; -use std::{fmt, fs, io}; -use std::collections::HashMap; use std::sync::LazyLock; +use std::{fmt, fs, io}; -use serde_derive::Deserialize; +use serde_derive::{Deserialize, Serialize}; use sha2::Digest; use crate::core::builder::{Builder, RunConfig, ShouldRun, Step}; @@ -532,7 +532,7 @@ undesirable, simply delete the `pre-push` file from .git/hooks." } /// Handles editor-specific setup differences -#[derive(Clone, Debug, Eq, PartialEq, Hash, Deserialize)] +#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)] #[serde(rename_all = "lowercase")] enum EditorKind { Emacs, @@ -542,6 +542,13 @@ enum EditorKind { Zed, } +static PARSED_HASHES: LazyLock>> = LazyLock::new(|| { + const ALL_HASHES: &str = include_str!("setup/hashes.json"); + let mut map: BTreeMap<_, Vec<_>> = serde_json::from_str(ALL_HASHES).unwrap(); + map.insert(EditorKind::Vim, map.get(&EditorKind::VsCode).unwrap().clone()); + map +}); + impl EditorKind { // Used in `./tests.rs`. #[cfg(test)] @@ -592,13 +599,7 @@ Select which editor you would like to set up [default: None]: "; /// New entries should be appended whenever this is updated so we can detect /// outdated vs. user-modified settings files. fn hashes(&self) -> &'static [&'static str] { - const ALL_HASHES: &str = include_str!("setup/hashes.json"); - static PARSED_HASHES: LazyLock>> = LazyLock::new(|| { - let mut map: HashMap<_, Vec<_>> = serde_json::from_str(ALL_HASHES).unwrap(); - map.insert(EditorKind::Vim, map.get(&EditorKind::VsCode).unwrap().clone()); - map - }); - &*PARSED_HASHES.get(self).unwrap() + PARSED_HASHES.get(self).unwrap() } fn settings_path(&self, config: &Config) -> PathBuf { diff --git a/src/bootstrap/src/core/build_steps/setup/hashes.json b/src/bootstrap/src/core/build_steps/setup/hashes.json index be657b5772002..067c8fffe0d50 100644 --- a/src/bootstrap/src/core/build_steps/setup/hashes.json +++ b/src/bootstrap/src/core/build_steps/setup/hashes.json @@ -1,53 +1,73 @@ { - "emacs": [ - "51068d4747a13732440d1a8b8f432603badb1864fa431d83d0fd4f8fa57039e0", - "d29af4d949bbe2371eac928a3c31cf9496b1701aa1c45f11cd6c759865ad5c45", - "b5dd299b93dca3ceeb9b335f929293cb3d4bf4977866fbe7ceeac2a8a9f99088", - "631c837b0e98ae35fd48b0e5f743b1ca60adadf2d0a2b23566ba25df372cf1a9", - "080955765db84bb6cbf178879f489c4e2369397626a6ecb3debedb94a9d0b3ce", - "f501475c6654187091c924ae26187fa5791d74d4a8ab3fb61fbbe4c0275aade1", - "54bc48fe1996177f5eef86d7231b33978e6d8b737cb0a899e622b7e975c95308", - "08d30e455ceec6e01d9bcef8b9449f2ddd14d278ca8627cdad90e02d9f44e938" - ], - "helix": [ - "2d3069b8cf1b977e5d4023965eb6199597755e6c96c185ed5f2854f98b83d233", - "6736d61409fbebba0933afd2e4c44ff2f97c1cb36cf0299a7f4a7819b8775040", - "f252dcc30ca85a193a699581e5e929d5bd6c19d40d7a7ade5e257a9517a124a5", - "198c195ed0c070d15907b279b8b4ea96198ca71b939f5376454f3d636ab54da5", - "1c43ead340b20792b91d02b08494ee68708e7e09f56b6766629b4b72079208f1", - "eec09a09452682060afd23dd5d3536ccac5615b3cdbf427366446901215fb9f6", - "cb653043852d9d5ff4a5be56407b859ff9928be055ad3f307eb309aad04765e6", - "e28b1930d16d3d8bbdeed7bd4a995613e648b49e08c9b6f5271880f520637fed" - ], - "vscode": [ - "ea67e259dedf60d4429b6c349a564ffcd1563cf41c920a856d1f5b16b4701ac8", - "56e7bf011c71c5d81e0bf42e84938111847a810eee69d906bba494ea90b51922", - "af1b5efe196aed007577899db9dae15d6dbc923d6fa42fa0934e68617ba9bbe0", - "3468fea433c25fff60be6b71e8a215a732a7b1268b6a83bf10d024344e140541", - "47d227f424bf889b0d899b9cc992d5695e1b78c406e183cd78eafefbe5488923", - "b526bd58d0262dd4dda2bff5bc5515b705fb668a46235ace3e057f807963a11a", - "828666b021d837a33e78d870b56d34c88a5e2c85de58b693607ec574f0c27000", - "811fb3b063c739d261fd8590dd30242e117908f5a095d594fa04585daa18ec4d", - "4eecb58a2168b252077369da446c30ed0e658301efe69691979d1ef0443928f4", - "c394386e6133bbf29ffd32c8af0bb3d4aac354cba9ee051f29612aa9350f8f8d", - "e53e9129ca5ee5dcbd6ec8b68c2d87376474eb154992deba3c6d9ab1703e0717", - "f954316090936c7e590c253ca9d524008375882fa13c5b41d7e2547a896ff893", - "701b73751efd7abd6487f2c79348dab698af7ac4427b79fa3d2087c867144b12", - "a61df796c0c007cb6512127330564e49e57d558dec715703916a928b072a1054", - "02a49ac2d31f00ef6e4531c44e00dac51cea895112e480553f1ba060b3942a47", - "0aa4748848de0d1cb7ece92a0123c8897fef6de2f58aff8fda1426f098b7a798", - "e5e357862e5d6d0d9da335e9823c07b8a7dc42bbf18d72cc5206ad1049cd8fcc", - "a68fd5828e75f3e921f265e29ce1e9efa554083c3773fdb4b8e1ab3b2d9dc6cd" - ], - "zed": [ - "bbce727c269d1bd0c98afef4d612eb4ce27aea3c3a8968c5f10b31affbc40b6c", - "a5380cf5dd9328731aecc5dfb240d16dac46ed272126b9728006151ef42f5909", - "2e96bf0d443852b12f016c8fc9840ab3d0a2b4fe0b0fb3a157e8d74d5e7e0e26", - "4fadd4c87389a601a27db0d3d74a142fa3a2e656ae78982e934dbe24bee32ad6", - "f0bb3d23ab1a49175ab0ef5c4071af95bb03d01d460776cdb716d91333443382", - "5ef83292111d9a8bb63b6afc3abf42d0bc78fe24985f0d2e039e73258b5dab8f", - "74420c13094b530a986b37c4f1d23cb58c0e8e2295f5858ded129fb1574e66f9", - "2d3b592c089b2ad2c528686a1e371af49922edad1c59accd5d5f31612a441568", - "0767a2398ccc253274b184adbb9e018ce931bd0ef45baad06dad19b652c52951" - ] + "emacs": [ + "51068d4747a13732440d1a8b8f432603badb1864fa431d83d0fd4f8fa57039e0", + "d29af4d949bbe2371eac928a3c31cf9496b1701aa1c45f11cd6c759865ad5c45", + "b5dd299b93dca3ceeb9b335f929293cb3d4bf4977866fbe7ceeac2a8a9f99088", + "631c837b0e98ae35fd48b0e5f743b1ca60adadf2d0a2b23566ba25df372cf1a9", + "080955765db84bb6cbf178879f489c4e2369397626a6ecb3debedb94a9d0b3ce", + "f501475c6654187091c924ae26187fa5791d74d4a8ab3fb61fbbe4c0275aade1", + "54bc48fe1996177f5eef86d7231b33978e6d8b737cb0a899e622b7e975c95308", + "08d30e455ceec6e01d9bcef8b9449f2ddd14d278ca8627cdad90e02d9f44e938" + ], + "helix": [ + "2d3069b8cf1b977e5d4023965eb6199597755e6c96c185ed5f2854f98b83d233", + "6736d61409fbebba0933afd2e4c44ff2f97c1cb36cf0299a7f4a7819b8775040", + "f252dcc30ca85a193a699581e5e929d5bd6c19d40d7a7ade5e257a9517a124a5", + "198c195ed0c070d15907b279b8b4ea96198ca71b939f5376454f3d636ab54da5", + "1c43ead340b20792b91d02b08494ee68708e7e09f56b6766629b4b72079208f1", + "eec09a09452682060afd23dd5d3536ccac5615b3cdbf427366446901215fb9f6", + "cb653043852d9d5ff4a5be56407b859ff9928be055ad3f307eb309aad04765e6", + "e28b1930d16d3d8bbdeed7bd4a995613e648b49e08c9b6f5271880f520637fed" + ], + "vim": [ + "ea67e259dedf60d4429b6c349a564ffcd1563cf41c920a856d1f5b16b4701ac8", + "56e7bf011c71c5d81e0bf42e84938111847a810eee69d906bba494ea90b51922", + "af1b5efe196aed007577899db9dae15d6dbc923d6fa42fa0934e68617ba9bbe0", + "3468fea433c25fff60be6b71e8a215a732a7b1268b6a83bf10d024344e140541", + "47d227f424bf889b0d899b9cc992d5695e1b78c406e183cd78eafefbe5488923", + "b526bd58d0262dd4dda2bff5bc5515b705fb668a46235ace3e057f807963a11a", + "828666b021d837a33e78d870b56d34c88a5e2c85de58b693607ec574f0c27000", + "811fb3b063c739d261fd8590dd30242e117908f5a095d594fa04585daa18ec4d", + "4eecb58a2168b252077369da446c30ed0e658301efe69691979d1ef0443928f4", + "c394386e6133bbf29ffd32c8af0bb3d4aac354cba9ee051f29612aa9350f8f8d", + "e53e9129ca5ee5dcbd6ec8b68c2d87376474eb154992deba3c6d9ab1703e0717", + "f954316090936c7e590c253ca9d524008375882fa13c5b41d7e2547a896ff893", + "701b73751efd7abd6487f2c79348dab698af7ac4427b79fa3d2087c867144b12", + "a61df796c0c007cb6512127330564e49e57d558dec715703916a928b072a1054", + "02a49ac2d31f00ef6e4531c44e00dac51cea895112e480553f1ba060b3942a47", + "0aa4748848de0d1cb7ece92a0123c8897fef6de2f58aff8fda1426f098b7a798", + "e5e357862e5d6d0d9da335e9823c07b8a7dc42bbf18d72cc5206ad1049cd8fcc", + "a68fd5828e75f3e921f265e29ce1e9efa554083c3773fdb4b8e1ab3b2d9dc6cd" + ], + "vscode": [ + "ea67e259dedf60d4429b6c349a564ffcd1563cf41c920a856d1f5b16b4701ac8", + "56e7bf011c71c5d81e0bf42e84938111847a810eee69d906bba494ea90b51922", + "af1b5efe196aed007577899db9dae15d6dbc923d6fa42fa0934e68617ba9bbe0", + "3468fea433c25fff60be6b71e8a215a732a7b1268b6a83bf10d024344e140541", + "47d227f424bf889b0d899b9cc992d5695e1b78c406e183cd78eafefbe5488923", + "b526bd58d0262dd4dda2bff5bc5515b705fb668a46235ace3e057f807963a11a", + "828666b021d837a33e78d870b56d34c88a5e2c85de58b693607ec574f0c27000", + "811fb3b063c739d261fd8590dd30242e117908f5a095d594fa04585daa18ec4d", + "4eecb58a2168b252077369da446c30ed0e658301efe69691979d1ef0443928f4", + "c394386e6133bbf29ffd32c8af0bb3d4aac354cba9ee051f29612aa9350f8f8d", + "e53e9129ca5ee5dcbd6ec8b68c2d87376474eb154992deba3c6d9ab1703e0717", + "f954316090936c7e590c253ca9d524008375882fa13c5b41d7e2547a896ff893", + "701b73751efd7abd6487f2c79348dab698af7ac4427b79fa3d2087c867144b12", + "a61df796c0c007cb6512127330564e49e57d558dec715703916a928b072a1054", + "02a49ac2d31f00ef6e4531c44e00dac51cea895112e480553f1ba060b3942a47", + "0aa4748848de0d1cb7ece92a0123c8897fef6de2f58aff8fda1426f098b7a798", + "e5e357862e5d6d0d9da335e9823c07b8a7dc42bbf18d72cc5206ad1049cd8fcc", + "a68fd5828e75f3e921f265e29ce1e9efa554083c3773fdb4b8e1ab3b2d9dc6cd" + ], + "zed": [ + "bbce727c269d1bd0c98afef4d612eb4ce27aea3c3a8968c5f10b31affbc40b6c", + "a5380cf5dd9328731aecc5dfb240d16dac46ed272126b9728006151ef42f5909", + "2e96bf0d443852b12f016c8fc9840ab3d0a2b4fe0b0fb3a157e8d74d5e7e0e26", + "4fadd4c87389a601a27db0d3d74a142fa3a2e656ae78982e934dbe24bee32ad6", + "f0bb3d23ab1a49175ab0ef5c4071af95bb03d01d460776cdb716d91333443382", + "5ef83292111d9a8bb63b6afc3abf42d0bc78fe24985f0d2e039e73258b5dab8f", + "74420c13094b530a986b37c4f1d23cb58c0e8e2295f5858ded129fb1574e66f9", + "2d3b592c089b2ad2c528686a1e371af49922edad1c59accd5d5f31612a441568", + "0767a2398ccc253274b184adbb9e018ce931bd0ef45baad06dad19b652c52951" + ] } diff --git a/src/bootstrap/src/core/build_steps/setup/tests.rs b/src/bootstrap/src/core/build_steps/setup/tests.rs index 6eafbb40b4674..57b5492866614 100644 --- a/src/bootstrap/src/core/build_steps/setup/tests.rs +++ b/src/bootstrap/src/core/build_steps/setup/tests.rs @@ -1,3 +1,8 @@ +use std::collections::BTreeMap; +use std::fs::File; +use std::io::Write; +use std::path::Path; + use sha2::Digest; use super::EditorKind; @@ -5,14 +10,41 @@ use crate::utils::helpers::hex_encode; #[test] fn check_matching_settings_hash() { + // Needs to be a btree so we serialize in a deterministic order. + let mut mismatched = BTreeMap::new(); + for editor in EditorKind::ALL { let mut hasher = sha2::Sha256::new(); hasher.update(&editor.settings_template()); let actual = hex_encode(hasher.finalize().as_slice()); let expected = *editor.hashes().last().unwrap(); - assert_eq!( - expected, actual, - "Update `setup/hashes.json` with the new hash of `{actual}` for `EditorKind::{editor:?}`", - ); + + if expected != actual { + mismatched.insert(editor, (expected, actual)); + } + } + + if mismatched.is_empty() { + return; + } + + if option_env!("INSTA_UPDATE").is_some_and(|s| s != "0") { + let mut updated = super::PARSED_HASHES.clone(); + for (editor, (_, actual)) in &mismatched { + *updated.get_mut(editor).unwrap().last_mut().unwrap() = actual; + } + let hash_path = + Path::new(env!("CARGO_MANIFEST_DIR")).join("src/core/build_steps/setup/hashes.json"); + let mut hash_file = File::create(hash_path).unwrap(); + serde_json::to_writer_pretty(&mut hash_file, &updated).unwrap(); + hash_file.write_all(b"\n").unwrap(); + } else { + for (editor, (expected, actual)) in &mismatched { + eprintln!("recorded hash did not match actual hash: {expected} != {actual}"); + eprintln!( + "Run `x test --bless -- hash`, or manually update `setup/hashes.json` with the new hash of `{actual}` for `EditorKind::{editor:?}`" + ); + } + panic!("mismatched hashes"); } } From ebb1f470caf9c364876618797040d6880df3fb2a Mon Sep 17 00:00:00 2001 From: Jacob Pratt Date: Thu, 19 Mar 2026 01:08:01 -0400 Subject: [PATCH 19/22] Optimize 128-bit integer formatting The compiler is unaware of the restricted range of the input, so it is unable to optimize out the final division and modulus. By doing this manually, we get a nontrivial performance gain. --- library/core/src/fmt/num.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/library/core/src/fmt/num.rs b/library/core/src/fmt/num.rs index d3d6495e75a2a..dfa27e32bc722 100644 --- a/library/core/src/fmt/num.rs +++ b/library/core/src/fmt/num.rs @@ -823,7 +823,7 @@ fn enc_16lsd(buf: &mut [MaybeUninit], n: u64) { let mut remain = n; // Format per four digits from the lookup table. - for quad_index in (0..4).rev() { + for quad_index in (1..4).rev() { // pull two pairs let quad = remain % 1_00_00; remain /= 1_00_00; @@ -834,6 +834,14 @@ fn enc_16lsd(buf: &mut [MaybeUninit], n: u64) { buf[quad_index * 4 + OFFSET + 2].write(DECIMAL_PAIRS[pair2 * 2 + 0]); buf[quad_index * 4 + OFFSET + 3].write(DECIMAL_PAIRS[pair2 * 2 + 1]); } + + // final two pairs + let pair1 = (remain / 100) as usize; + let pair2 = (remain % 100) as usize; + buf[OFFSET + 0].write(DECIMAL_PAIRS[pair1 * 2 + 0]); + buf[OFFSET + 1].write(DECIMAL_PAIRS[pair1 * 2 + 1]); + buf[OFFSET + 2].write(DECIMAL_PAIRS[pair2 * 2 + 0]); + buf[OFFSET + 3].write(DECIMAL_PAIRS[pair2 * 2 + 1]); } /// Euclidean division plus remainder with constant 1E16 basically consumes 16 From b2e8177455cad2c001a58d43a4dec6d896cea0ad Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 19 Mar 2026 15:59:16 +1100 Subject: [PATCH 20/22] Reorder `define_callbacks`. This is nitpicky, but the lack of a sensible order has been bugging me. - Within `mod $name`, put all the typedefs together. - After that: - First, types definitions and their impls. - Then the `TyCtxt*` impls, in a sensible order. - Likewise, put `TyCtxt::at` before the similar methods. - Also reflow some overly long lines. --- compiler/rustc_middle/src/query/plumbing.rs | 258 ++++++++++---------- 1 file changed, 133 insertions(+), 125 deletions(-) diff --git a/compiler/rustc_middle/src/query/plumbing.rs b/compiler/rustc_middle/src/query/plumbing.rs index d4e7bb52be974..f4e1ead7c5859 100644 --- a/compiler/rustc_middle/src/query/plumbing.rs +++ b/compiler/rustc_middle/src/query/plumbing.rs @@ -201,6 +201,13 @@ pub struct TyCtxtEnsureDone<'tcx> { } impl<'tcx> TyCtxt<'tcx> { + /// Returns a transparent wrapper for `TyCtxt` which uses + /// `span` as the location of queries performed through it. + #[inline(always)] + pub fn at(self, span: Span) -> TyCtxtAt<'tcx> { + TyCtxtAt { tcx: self, span } + } + /// FIXME: `ensure_ok`'s effects are subtle. Is this comment fully accurate? /// /// Wrapper that calls queries in a special "ensure OK" mode, for callers @@ -258,13 +265,6 @@ impl<'tcx> TyCtxt<'tcx> { pub fn ensure_done(self) -> TyCtxtEnsureDone<'tcx> { TyCtxtEnsureDone { tcx: self } } - - /// Returns a transparent wrapper for `TyCtxt` which uses - /// `span` as the location of queries performed through it. - #[inline(always)] - pub fn at(self, span: Span) -> TyCtxtAt<'tcx> { - TyCtxtAt { tcx: self, span } - } } macro_rules! query_helper_param_ty { @@ -323,6 +323,9 @@ macro_rules! define_callbacks { #[cfg(not($arena_cache))] pub type ProvidedValue<'tcx> = Value<'tcx>; + pub type Cache<'tcx> = + as $crate::query::QueryKey>::Cache>>; + /// 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 @@ -354,9 +357,6 @@ macro_rules! define_callbacks { erase::erase_val(value) } - pub type Cache<'tcx> = - as $crate::query::QueryKey>::Cache>>; - // Ensure that keys grow no larger than 88 bytes by accident. // Increase this limit if necessary, but do try to keep the size low if possible #[cfg(target_pointer_width = "64")] @@ -390,116 +390,8 @@ macro_rules! define_callbacks { } )* - /// Holds per-query arenas for queries with the `arena_cache` modifier. - #[derive(Default)] - pub struct QueryArenas<'tcx> { - $( - // Use the `ArenaCached` helper trait to determine the arena's value type. - #[cfg($arena_cache)] - pub $name: TypedArena< - <$V as $crate::query::arena_cached::ArenaCached<'tcx>>::Allocated, - >, - )* - } - - impl<'tcx> $crate::query::TyCtxtEnsureOk<'tcx> { - $( - $(#[$attr])* - #[inline(always)] - pub fn $name(self, key: query_helper_param_ty!($($K)*)) { - crate::query::inner::query_ensure_ok_or_done( - self.tcx, - &self.tcx.query_system.query_vtables.$name, - $crate::query::IntoQueryKey::into_query_key(key), - $crate::query::EnsureMode::Ok, - ) - } - )* - } - - // Only defined when the `ensure_result` modifier is present. - impl<'tcx> $crate::query::TyCtxtEnsureResult<'tcx> { - $( - #[cfg($returns_error_guaranteed)] - $(#[$attr])* - #[inline(always)] - pub fn $name( - self, - key: query_helper_param_ty!($($K)*), - ) -> Result<(), rustc_errors::ErrorGuaranteed> { - crate::query::inner::query_ensure_result( - self.tcx, - &self.tcx.query_system.query_vtables.$name, - $crate::query::IntoQueryKey::into_query_key(key), - ) - } - )* - } - - impl<'tcx> $crate::query::TyCtxtEnsureDone<'tcx> { - $( - $(#[$attr])* - #[inline(always)] - pub fn $name(self, key: query_helper_param_ty!($($K)*)) { - crate::query::inner::query_ensure_ok_or_done( - self.tcx, - &self.tcx.query_system.query_vtables.$name, - $crate::query::IntoQueryKey::into_query_key(key), - $crate::query::EnsureMode::Done, - ); - } - )* - } - - impl<'tcx> TyCtxt<'tcx> { - $( - $(#[$attr])* - #[inline(always)] - #[must_use] - pub fn $name(self, key: query_helper_param_ty!($($K)*)) -> $V { - self.at(DUMMY_SP).$name(key) - } - )* - } - - impl<'tcx> $crate::query::TyCtxtAt<'tcx> { - $( - $(#[$attr])* - #[inline(always)] - pub fn $name(self, key: query_helper_param_ty!($($K)*)) -> $V { - use $crate::query::{erase, inner}; - - erase::restore_val::<$V>(inner::query_get_at( - self.tcx, - self.span, - &self.tcx.query_system.query_vtables.$name, - $crate::query::IntoQueryKey::into_query_key(key), - )) - } - )* - } - - $( - #[cfg($feedable)] - impl<'tcx, K: $crate::query::IntoQueryKey<$name::Key<'tcx>> + Copy> - TyCtxtFeed<'tcx, K> - { - $(#[$attr])* - #[inline(always)] - pub fn $name(self, value: $name::ProvidedValue<'tcx>) { - let key = self.key().into_query_key(); - let erased_value = $name::provided_to_erased(self.tcx, value); - $crate::query::inner::query_feed( - self.tcx, - &self.tcx.query_system.query_vtables.$name, - key, - erased_value, - ); - } - } - )* - - /// Identifies a query by kind and key. This is in contrast to `QueryJobId` which is just a number. + /// Identifies a query by kind and key. This is in contrast to `QueryJobId` which is just a + /// number. #[allow(non_camel_case_types)] #[derive(Clone, Copy, Debug)] pub enum TaggedQueryKey<'tcx> { @@ -528,7 +420,8 @@ macro_rules! define_callbacks { pub fn description(&self, tcx: TyCtxt<'tcx>) -> String { let (name, description) = ty::print::with_no_queries!(match self { $( - TaggedQueryKey::$name(key) => (stringify!($name), _description_fns::$name(tcx, *key)), + TaggedQueryKey::$name(key) => + (stringify!($name), _description_fns::$name(tcx, *key)), )* }); if tcx.sess.verbose_internals() { @@ -550,7 +443,8 @@ macro_rules! define_callbacks { } match self { $( - TaggedQueryKey::$name(key) => crate::query::QueryKey::default_span(key, tcx), + TaggedQueryKey::$name(key) => + crate::query::QueryKey::default_span(key, tcx), )* } } @@ -558,8 +452,13 @@ macro_rules! define_callbacks { pub fn def_kind(&self, tcx: TyCtxt<'tcx>) -> Option { // This is used to reduce code generation as it // can be reused for queries with the same key type. - fn inner<'tcx>(key: &impl crate::query::QueryKey, tcx: TyCtxt<'tcx>) -> Option { - key.key_as_def_id().and_then(|def_id| def_id.as_local()).map(|def_id| tcx.def_kind(def_id)) + fn inner<'tcx>(key: &impl crate::query::QueryKey, tcx: TyCtxt<'tcx>) + -> Option + { + key + .key_as_def_id() + .and_then(|def_id| def_id.as_local()) + .map(|def_id| tcx.def_kind(def_id)) } if let TaggedQueryKey::def_kind(..) = self { @@ -577,7 +476,19 @@ macro_rules! define_callbacks { /// Holds a `QueryVTable` for each query. pub struct QueryVTables<'tcx> { $( - pub $name: crate::query::QueryVTable<'tcx, $name::Cache<'tcx>>, + pub $name: $crate::query::QueryVTable<'tcx, $name::Cache<'tcx>>, + )* + } + + /// Holds per-query arenas for queries with the `arena_cache` modifier. + #[derive(Default)] + pub struct QueryArenas<'tcx> { + $( + // Use the `ArenaCached` helper trait to determine the arena's value type. + #[cfg($arena_cache)] + pub $name: TypedArena< + <$V as $crate::query::arena_cached::ArenaCached<'tcx>>::Allocated, + >, )* } @@ -637,6 +548,103 @@ macro_rules! define_callbacks { impl Clone for ExternProviders { fn clone(&self) -> Self { *self } } + + impl<'tcx> TyCtxt<'tcx> { + $( + $(#[$attr])* + #[inline(always)] + #[must_use] + pub fn $name(self, key: query_helper_param_ty!($($K)*)) -> $V { + self.at(DUMMY_SP).$name(key) + } + )* + } + + impl<'tcx> $crate::query::TyCtxtAt<'tcx> { + $( + $(#[$attr])* + #[inline(always)] + pub fn $name(self, key: query_helper_param_ty!($($K)*)) -> $V { + use $crate::query::{erase, inner}; + + erase::restore_val::<$V>(inner::query_get_at( + self.tcx, + self.span, + &self.tcx.query_system.query_vtables.$name, + $crate::query::IntoQueryKey::into_query_key(key), + )) + } + )* + } + + impl<'tcx> $crate::query::TyCtxtEnsureOk<'tcx> { + $( + $(#[$attr])* + #[inline(always)] + pub fn $name(self, key: query_helper_param_ty!($($K)*)) { + crate::query::inner::query_ensure_ok_or_done( + self.tcx, + &self.tcx.query_system.query_vtables.$name, + $crate::query::IntoQueryKey::into_query_key(key), + $crate::query::EnsureMode::Ok, + ) + } + )* + } + + // Only defined when the `ensure_result` modifier is present. + impl<'tcx> $crate::query::TyCtxtEnsureResult<'tcx> { + $( + #[cfg($returns_error_guaranteed)] + $(#[$attr])* + #[inline(always)] + pub fn $name( + self, + key: query_helper_param_ty!($($K)*), + ) -> Result<(), rustc_errors::ErrorGuaranteed> { + crate::query::inner::query_ensure_result( + self.tcx, + &self.tcx.query_system.query_vtables.$name, + $crate::query::IntoQueryKey::into_query_key(key), + ) + } + )* + } + + impl<'tcx> $crate::query::TyCtxtEnsureDone<'tcx> { + $( + $(#[$attr])* + #[inline(always)] + pub fn $name(self, key: query_helper_param_ty!($($K)*)) { + crate::query::inner::query_ensure_ok_or_done( + self.tcx, + &self.tcx.query_system.query_vtables.$name, + $crate::query::IntoQueryKey::into_query_key(key), + $crate::query::EnsureMode::Done, + ); + } + )* + } + + $( + #[cfg($feedable)] + impl<'tcx, K: $crate::query::IntoQueryKey<$name::Key<'tcx>> + Copy> + TyCtxtFeed<'tcx, K> + { + $(#[$attr])* + #[inline(always)] + pub fn $name(self, value: $name::ProvidedValue<'tcx>) { + let key = self.key().into_query_key(); + let erased_value = $name::provided_to_erased(self.tcx, value); + $crate::query::inner::query_feed( + self.tcx, + &self.tcx.query_system.query_vtables.$name, + key, + erased_value, + ); + } + } + )* }; } From 091d000b93fefc229775bb2905ec63e35a8c1490 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 19 Mar 2026 16:23:37 +1100 Subject: [PATCH 21/22] Minor `define_callbacks` tweaks. - Use `$crate` more consistently. - Add a couple of useful comments. - Remove some unnecessary local variables. --- compiler/rustc_middle/src/query/plumbing.rs | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_middle/src/query/plumbing.rs b/compiler/rustc_middle/src/query/plumbing.rs index f4e1ead7c5859..56a8f5e974aea 100644 --- a/compiler/rustc_middle/src/query/plumbing.rs +++ b/compiler/rustc_middle/src/query/plumbing.rs @@ -444,7 +444,7 @@ macro_rules! define_callbacks { match self { $( TaggedQueryKey::$name(key) => - crate::query::QueryKey::default_span(key, tcx), + $crate::query::QueryKey::default_span(key, tcx), )* } } @@ -452,7 +452,7 @@ macro_rules! define_callbacks { pub fn def_kind(&self, tcx: TyCtxt<'tcx>) -> Option { // This is used to reduce code generation as it // can be reused for queries with the same key type. - fn inner<'tcx>(key: &impl crate::query::QueryKey, tcx: TyCtxt<'tcx>) + fn inner<'tcx>(key: &impl $crate::query::QueryKey, tcx: TyCtxt<'tcx>) -> Option { key @@ -465,6 +465,7 @@ macro_rules! define_callbacks { // Try to avoid infinite recursion. return None } + match self { $( TaggedQueryKey::$name(key) => inner(key, tcx), @@ -582,7 +583,7 @@ macro_rules! define_callbacks { $(#[$attr])* #[inline(always)] pub fn $name(self, key: query_helper_param_ty!($($K)*)) { - crate::query::inner::query_ensure_ok_or_done( + $crate::query::inner::query_ensure_ok_or_done( self.tcx, &self.tcx.query_system.query_vtables.$name, $crate::query::IntoQueryKey::into_query_key(key), @@ -592,7 +593,7 @@ macro_rules! define_callbacks { )* } - // Only defined when the `ensure_result` modifier is present. + // Only defined when the `returns_error_guaranteed` modifier is present. impl<'tcx> $crate::query::TyCtxtEnsureResult<'tcx> { $( #[cfg($returns_error_guaranteed)] @@ -602,7 +603,7 @@ macro_rules! define_callbacks { self, key: query_helper_param_ty!($($K)*), ) -> Result<(), rustc_errors::ErrorGuaranteed> { - crate::query::inner::query_ensure_result( + $crate::query::inner::query_ensure_result( self.tcx, &self.tcx.query_system.query_vtables.$name, $crate::query::IntoQueryKey::into_query_key(key), @@ -616,7 +617,7 @@ macro_rules! define_callbacks { $(#[$attr])* #[inline(always)] pub fn $name(self, key: query_helper_param_ty!($($K)*)) { - crate::query::inner::query_ensure_ok_or_done( + $crate::query::inner::query_ensure_ok_or_done( self.tcx, &self.tcx.query_system.query_vtables.$name, $crate::query::IntoQueryKey::into_query_key(key), @@ -627,6 +628,7 @@ macro_rules! define_callbacks { } $( + // Only defined when the `feedable` modifier is present. #[cfg($feedable)] impl<'tcx, K: $crate::query::IntoQueryKey<$name::Key<'tcx>> + Copy> TyCtxtFeed<'tcx, K> @@ -634,13 +636,11 @@ macro_rules! define_callbacks { $(#[$attr])* #[inline(always)] pub fn $name(self, value: $name::ProvidedValue<'tcx>) { - let key = self.key().into_query_key(); - let erased_value = $name::provided_to_erased(self.tcx, value); $crate::query::inner::query_feed( self.tcx, &self.tcx.query_system.query_vtables.$name, - key, - erased_value, + self.key().into_query_key(), + $name::provided_to_erased(self.tcx, value), ); } } From 7cec833020ed1a763a849ca1cd236412e0987e4f Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 19 Mar 2026 16:54:06 +1100 Subject: [PATCH 22/22] Rename `query_helper_param_ty`. As `maybe_into_query_key`. Partly to use `key` instead of `param`, and also to make the link to the trait more obvious. --- compiler/rustc_middle/src/queries.rs | 2 +- compiler/rustc_middle/src/query/plumbing.rs | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_middle/src/queries.rs b/compiler/rustc_middle/src/queries.rs index 4dd68db4f9135..b07b220865948 100644 --- a/compiler/rustc_middle/src/queries.rs +++ b/compiler/rustc_middle/src/queries.rs @@ -101,7 +101,7 @@ use crate::mir::mono::{ CodegenUnit, CollectionMode, MonoItem, MonoItemPartitions, NormalizationErrorInMono, }; use crate::query::describe_as_module; -use crate::query::plumbing::{define_callbacks, query_helper_param_ty}; +use crate::query::plumbing::{define_callbacks, maybe_into_query_key}; use crate::traits::query::{ CanonicalAliasGoal, CanonicalDropckOutlivesGoal, CanonicalImpliedOutlivesBoundsGoal, CanonicalMethodAutoderefStepsGoal, CanonicalPredicateGoal, CanonicalTypeOpAscribeUserTypeGoal, diff --git a/compiler/rustc_middle/src/query/plumbing.rs b/compiler/rustc_middle/src/query/plumbing.rs index 56a8f5e974aea..4ef1b0adf581d 100644 --- a/compiler/rustc_middle/src/query/plumbing.rs +++ b/compiler/rustc_middle/src/query/plumbing.rs @@ -267,7 +267,7 @@ impl<'tcx> TyCtxt<'tcx> { } } -macro_rules! query_helper_param_ty { +macro_rules! maybe_into_query_key { (DefId) => { impl $crate::query::IntoQueryKey }; (LocalDefId) => { impl $crate::query::IntoQueryKey }; ($K:ty) => { $K }; @@ -276,7 +276,7 @@ macro_rules! query_helper_param_ty { macro_rules! define_callbacks { ( // You might expect the key to be `$K:ty`, but it needs to be `$($K:tt)*` so that - // `query_helper_param_ty!` can match on specific type names. + // `maybe_into_query_key!` can match on specific type names. queries { $( $(#[$attr:meta])* @@ -555,7 +555,7 @@ macro_rules! define_callbacks { $(#[$attr])* #[inline(always)] #[must_use] - pub fn $name(self, key: query_helper_param_ty!($($K)*)) -> $V { + pub fn $name(self, key: maybe_into_query_key!($($K)*)) -> $V { self.at(DUMMY_SP).$name(key) } )* @@ -565,7 +565,7 @@ macro_rules! define_callbacks { $( $(#[$attr])* #[inline(always)] - pub fn $name(self, key: query_helper_param_ty!($($K)*)) -> $V { + pub fn $name(self, key: maybe_into_query_key!($($K)*)) -> $V { use $crate::query::{erase, inner}; erase::restore_val::<$V>(inner::query_get_at( @@ -582,7 +582,7 @@ macro_rules! define_callbacks { $( $(#[$attr])* #[inline(always)] - pub fn $name(self, key: query_helper_param_ty!($($K)*)) { + pub fn $name(self, key: maybe_into_query_key!($($K)*)) { $crate::query::inner::query_ensure_ok_or_done( self.tcx, &self.tcx.query_system.query_vtables.$name, @@ -601,7 +601,7 @@ macro_rules! define_callbacks { #[inline(always)] pub fn $name( self, - key: query_helper_param_ty!($($K)*), + key: maybe_into_query_key!($($K)*), ) -> Result<(), rustc_errors::ErrorGuaranteed> { $crate::query::inner::query_ensure_result( self.tcx, @@ -616,7 +616,7 @@ macro_rules! define_callbacks { $( $(#[$attr])* #[inline(always)] - pub fn $name(self, key: query_helper_param_ty!($($K)*)) { + pub fn $name(self, key: maybe_into_query_key!($($K)*)) { $crate::query::inner::query_ensure_ok_or_done( self.tcx, &self.tcx.query_system.query_vtables.$name, @@ -650,7 +650,7 @@ macro_rules! define_callbacks { // Re-export `macro_rules!` macros as normal items, so that they can be imported normally. pub(crate) use define_callbacks; -pub(crate) use query_helper_param_ty; +pub(crate) use maybe_into_query_key; #[cold] pub(crate) fn default_query(name: &str, key: &dyn std::fmt::Debug) -> ! {