From 141342c34f3b3a623a132e08cbfcc883d3e97017 Mon Sep 17 00:00:00 2001 From: usamoi Date: Mon, 15 Dec 2025 18:57:33 +0800 Subject: [PATCH 1/3] stabilize lazy_get --- library/core/src/cell/lazy.rs | 11 +--- library/core/src/lib.rs | 1 - library/coretests/tests/lib.rs | 1 - library/std/src/lib.rs | 1 - library/std/src/sync/lazy_lock.rs | 11 +--- library/std/tests/sync/lib.rs | 1 - ...onst-item-interior-mutations-const-cell.rs | 1 - ...-item-interior-mutations-const-cell.stderr | 44 +++++++------- .../const-item-interior-mutations-const.fixed | 1 - .../const-item-interior-mutations-const.rs | 1 - ...const-item-interior-mutations-const.stderr | 60 +++++++++---------- 11 files changed, 58 insertions(+), 75 deletions(-) diff --git a/library/core/src/cell/lazy.rs b/library/core/src/cell/lazy.rs index 3dae6c64200c1..8ffa9b3def519 100644 --- a/library/core/src/cell/lazy.rs +++ b/library/core/src/cell/lazy.rs @@ -165,7 +165,6 @@ impl T> LazyCell { /// # Examples /// /// ``` - /// #![feature(lazy_get)] /// use std::cell::LazyCell; /// /// let mut lazy = LazyCell::new(|| 92); @@ -176,7 +175,7 @@ impl T> LazyCell { /// assert_eq!(*lazy, 44); /// ``` #[inline] - #[unstable(feature = "lazy_get", issue = "129333")] + #[stable(feature = "lazy_get", since = "CURRENT_RUSTC_VERSION")] pub fn force_mut(this: &mut LazyCell) -> &mut T { #[cold] /// # Safety @@ -264,8 +263,6 @@ impl LazyCell { /// # Examples /// /// ``` - /// #![feature(lazy_get)] - /// /// use std::cell::LazyCell; /// /// let mut lazy = LazyCell::new(|| 92); @@ -276,7 +273,7 @@ impl LazyCell { /// assert_eq!(*lazy, 44); /// ``` #[inline] - #[unstable(feature = "lazy_get", issue = "129333")] + #[stable(feature = "lazy_get", since = "CURRENT_RUSTC_VERSION")] pub fn get_mut(this: &mut LazyCell) -> Option<&mut T> { let state = this.state.get_mut(); match state { @@ -291,8 +288,6 @@ impl LazyCell { /// # Examples /// /// ``` - /// #![feature(lazy_get)] - /// /// use std::cell::LazyCell; /// /// let lazy = LazyCell::new(|| 92); @@ -302,7 +297,7 @@ impl LazyCell { /// assert_eq!(LazyCell::get(&lazy), Some(&92)); /// ``` #[inline] - #[unstable(feature = "lazy_get", issue = "129333")] + #[stable(feature = "lazy_get", since = "CURRENT_RUSTC_VERSION")] pub fn get(this: &LazyCell) -> Option<&T> { // SAFETY: // This is sound for the same reason as in `force`: once the state is diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 9ecc2365e69b7..962b0cea4a4f1 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -113,7 +113,6 @@ #![feature(internal_impls_macro)] #![feature(ip)] #![feature(is_ascii_octdigit)] -#![feature(lazy_get)] #![feature(link_cfg)] #![feature(offset_of_enum)] #![feature(panic_internals)] diff --git a/library/coretests/tests/lib.rs b/library/coretests/tests/lib.rs index 0387b442562db..b28e7338859c4 100644 --- a/library/coretests/tests/lib.rs +++ b/library/coretests/tests/lib.rs @@ -79,7 +79,6 @@ #![feature(iterator_try_collect)] #![feature(iterator_try_reduce)] #![feature(layout_for_ptr)] -#![feature(lazy_get)] #![feature(maybe_uninit_fill)] #![feature(maybe_uninit_uninit_array_transpose)] #![feature(min_specialization)] diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 8fb1b1b05d20c..1a1746c91edda 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -343,7 +343,6 @@ #![feature(hint_must_use)] #![feature(int_from_ascii)] #![feature(ip)] -#![feature(lazy_get)] #![feature(maybe_uninit_array_assume_init)] #![feature(panic_can_unwind)] #![feature(panic_internals)] diff --git a/library/std/src/sync/lazy_lock.rs b/library/std/src/sync/lazy_lock.rs index ef58b64d4967e..ef5c949e471f3 100644 --- a/library/std/src/sync/lazy_lock.rs +++ b/library/std/src/sync/lazy_lock.rs @@ -172,7 +172,6 @@ impl T> LazyLock { /// # Examples /// /// ``` - /// #![feature(lazy_get)] /// use std::sync::LazyLock; /// /// let mut lazy = LazyLock::new(|| 92); @@ -183,7 +182,7 @@ impl T> LazyLock { /// assert_eq!(*lazy, 44); /// ``` #[inline] - #[unstable(feature = "lazy_get", issue = "129333")] + #[stable(feature = "lazy_get", since = "CURRENT_RUSTC_VERSION")] pub fn force_mut(this: &mut LazyLock) -> &mut T { #[cold] /// # Safety @@ -279,8 +278,6 @@ impl LazyLock { /// # Examples /// /// ``` - /// #![feature(lazy_get)] - /// /// use std::sync::LazyLock; /// /// let mut lazy = LazyLock::new(|| 92); @@ -291,7 +288,7 @@ impl LazyLock { /// assert_eq!(*lazy, 44); /// ``` #[inline] - #[unstable(feature = "lazy_get", issue = "129333")] + #[stable(feature = "lazy_get", since = "CURRENT_RUSTC_VERSION")] pub fn get_mut(this: &mut LazyLock) -> Option<&mut T> { // `state()` does not perform an atomic load, so prefer it over `is_complete()`. let state = this.once.state(); @@ -309,8 +306,6 @@ impl LazyLock { /// # Examples /// /// ``` - /// #![feature(lazy_get)] - /// /// use std::sync::LazyLock; /// /// let lazy = LazyLock::new(|| 92); @@ -320,7 +315,7 @@ impl LazyLock { /// assert_eq!(LazyLock::get(&lazy), Some(&92)); /// ``` #[inline] - #[unstable(feature = "lazy_get", issue = "129333")] + #[stable(feature = "lazy_get", since = "CURRENT_RUSTC_VERSION")] #[rustc_should_not_be_called_on_const_items] pub fn get(this: &LazyLock) -> Option<&T> { if this.once.is_completed() { diff --git a/library/std/tests/sync/lib.rs b/library/std/tests/sync/lib.rs index 20e34c9aa6bdf..7ade9f623147b 100644 --- a/library/std/tests/sync/lib.rs +++ b/library/std/tests/sync/lib.rs @@ -1,4 +1,3 @@ -#![feature(lazy_get)] #![feature(mapped_lock_guards)] #![feature(mpmc_channel)] #![feature(once_cell_try)] diff --git a/tests/ui/lint/const-item-interior-mutations-const-cell.rs b/tests/ui/lint/const-item-interior-mutations-const-cell.rs index b4a7f54c8e7a0..22b465fa0a951 100644 --- a/tests/ui/lint/const-item-interior-mutations-const-cell.rs +++ b/tests/ui/lint/const-item-interior-mutations-const-cell.rs @@ -4,7 +4,6 @@ #![feature(sync_unsafe_cell)] #![feature(once_cell_try_insert)] #![feature(once_cell_try)] -#![feature(lazy_get)] use std::cell::{Cell, RefCell, SyncUnsafeCell, UnsafeCell}; use std::cell::{LazyCell, OnceCell}; diff --git a/tests/ui/lint/const-item-interior-mutations-const-cell.stderr b/tests/ui/lint/const-item-interior-mutations-const-cell.stderr index d9f19c61fa773..ec3a5f4e38eed 100644 --- a/tests/ui/lint/const-item-interior-mutations-const-cell.stderr +++ b/tests/ui/lint/const-item-interior-mutations-const-cell.stderr @@ -1,5 +1,5 @@ warning: mutation of an interior mutable `const` item with call to `force` - --> $DIR/const-item-interior-mutations-const-cell.rs:16:13 + --> $DIR/const-item-interior-mutations-const-cell.rs:15:13 | LL | let _ = LazyCell::force(&A); | ^^^^^^^^^^^^^^^^^-^ @@ -17,7 +17,7 @@ LL + static A: LazyCell = LazyCell::new(|| 0); | warning: mutation of an interior mutable `const` item with call to `set` - --> $DIR/const-item-interior-mutations-const-cell.rs:23:13 + --> $DIR/const-item-interior-mutations-const-cell.rs:22:13 | LL | let _ = A.set(10); | -^^^^^^^^ @@ -34,7 +34,7 @@ LL + static A: OnceCell = OnceCell::new(); | warning: mutation of an interior mutable `const` item with call to `try_insert` - --> $DIR/const-item-interior-mutations-const-cell.rs:26:13 + --> $DIR/const-item-interior-mutations-const-cell.rs:25:13 | LL | let _ = A.try_insert(20); | -^^^^^^^^^^^^^^^ @@ -51,7 +51,7 @@ LL + static A: OnceCell = OnceCell::new(); | warning: mutation of an interior mutable `const` item with call to `get_or_init` - --> $DIR/const-item-interior-mutations-const-cell.rs:29:13 + --> $DIR/const-item-interior-mutations-const-cell.rs:28:13 | LL | let _ = A.get_or_init(|| 30); | -^^^^^^^^^^^^^^^^^^^ @@ -68,7 +68,7 @@ LL + static A: OnceCell = OnceCell::new(); | warning: mutation of an interior mutable `const` item with call to `get_or_try_init` - --> $DIR/const-item-interior-mutations-const-cell.rs:32:13 + --> $DIR/const-item-interior-mutations-const-cell.rs:31:13 | LL | let _ = A.get_or_try_init(|| Ok::<_, ()>(40)); | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -85,7 +85,7 @@ LL + static A: OnceCell = OnceCell::new(); | warning: mutation of an interior mutable `const` item with call to `set` - --> $DIR/const-item-interior-mutations-const-cell.rs:39:13 + --> $DIR/const-item-interior-mutations-const-cell.rs:38:13 | LL | let _ = A.set(1); | -^^^^^^^ @@ -102,7 +102,7 @@ LL + static A: Cell = Cell::new(0); | warning: mutation of an interior mutable `const` item with call to `swap` - --> $DIR/const-item-interior-mutations-const-cell.rs:42:13 + --> $DIR/const-item-interior-mutations-const-cell.rs:41:13 | LL | let _ = A.swap(&A); | -^^^^^^^^^ @@ -119,7 +119,7 @@ LL + static A: Cell = Cell::new(0); | warning: mutation of an interior mutable `const` item with call to `replace` - --> $DIR/const-item-interior-mutations-const-cell.rs:45:13 + --> $DIR/const-item-interior-mutations-const-cell.rs:44:13 | LL | let _ = A.replace(2); | -^^^^^^^^^^^ @@ -136,7 +136,7 @@ LL + static A: Cell = Cell::new(0); | warning: mutation of an interior mutable `const` item with call to `get` - --> $DIR/const-item-interior-mutations-const-cell.rs:48:13 + --> $DIR/const-item-interior-mutations-const-cell.rs:47:13 | LL | let _ = A.get(); | -^^^^^^ @@ -153,7 +153,7 @@ LL + static A: Cell = Cell::new(0); | warning: mutation of an interior mutable `const` item with call to `update` - --> $DIR/const-item-interior-mutations-const-cell.rs:51:13 + --> $DIR/const-item-interior-mutations-const-cell.rs:50:13 | LL | let _ = A.update(|x| x + 1); | -^^^^^^^^^^^^^^^^^^ @@ -170,7 +170,7 @@ LL + static A: Cell = Cell::new(0); | warning: mutation of an interior mutable `const` item with call to `replace` - --> $DIR/const-item-interior-mutations-const-cell.rs:58:13 + --> $DIR/const-item-interior-mutations-const-cell.rs:57:13 | LL | let _ = A.replace(1); | -^^^^^^^^^^^ @@ -187,7 +187,7 @@ LL + static A: RefCell = RefCell::new(0); | warning: mutation of an interior mutable `const` item with call to `replace_with` - --> $DIR/const-item-interior-mutations-const-cell.rs:61:13 + --> $DIR/const-item-interior-mutations-const-cell.rs:60:13 | LL | let _ = A.replace_with(|x| *x + 2); | -^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -204,7 +204,7 @@ LL + static A: RefCell = RefCell::new(0); | warning: mutation of an interior mutable `const` item with call to `swap` - --> $DIR/const-item-interior-mutations-const-cell.rs:64:13 + --> $DIR/const-item-interior-mutations-const-cell.rs:63:13 | LL | let _ = A.swap(&A); | -^^^^^^^^^ @@ -221,7 +221,7 @@ LL + static A: RefCell = RefCell::new(0); | warning: mutation of an interior mutable `const` item with call to `borrow` - --> $DIR/const-item-interior-mutations-const-cell.rs:67:13 + --> $DIR/const-item-interior-mutations-const-cell.rs:66:13 | LL | let _ = A.borrow(); | -^^^^^^^^^ @@ -238,7 +238,7 @@ LL + static A: RefCell = RefCell::new(0); | warning: mutation of an interior mutable `const` item with call to `try_borrow` - --> $DIR/const-item-interior-mutations-const-cell.rs:70:13 + --> $DIR/const-item-interior-mutations-const-cell.rs:69:13 | LL | let _ = A.try_borrow(); | -^^^^^^^^^^^^^ @@ -255,7 +255,7 @@ LL + static A: RefCell = RefCell::new(0); | warning: mutation of an interior mutable `const` item with call to `borrow_mut` - --> $DIR/const-item-interior-mutations-const-cell.rs:73:13 + --> $DIR/const-item-interior-mutations-const-cell.rs:72:13 | LL | let _ = A.borrow_mut(); | -^^^^^^^^^^^^^ @@ -272,7 +272,7 @@ LL + static A: RefCell = RefCell::new(0); | warning: mutation of an interior mutable `const` item with call to `try_borrow_mut` - --> $DIR/const-item-interior-mutations-const-cell.rs:76:13 + --> $DIR/const-item-interior-mutations-const-cell.rs:75:13 | LL | let _ = A.try_borrow_mut(); | -^^^^^^^^^^^^^^^^^ @@ -289,7 +289,7 @@ LL + static A: RefCell = RefCell::new(0); | warning: mutation of an interior mutable `const` item with call to `replace` - --> $DIR/const-item-interior-mutations-const-cell.rs:83:22 + --> $DIR/const-item-interior-mutations-const-cell.rs:82:22 | LL | let _ = unsafe { A.replace(1) }; | -^^^^^^^^^^^ @@ -306,7 +306,7 @@ LL + static A: UnsafeCell = UnsafeCell::new(0); | warning: mutation of an interior mutable `const` item with call to `get` - --> $DIR/const-item-interior-mutations-const-cell.rs:86:13 + --> $DIR/const-item-interior-mutations-const-cell.rs:85:13 | LL | let _ = A.get(); | -^^^^^^ @@ -323,7 +323,7 @@ LL + static A: UnsafeCell = UnsafeCell::new(0); | warning: mutation of an interior mutable `const` item with call to `as_ref_unchecked` - --> $DIR/const-item-interior-mutations-const-cell.rs:90:17 + --> $DIR/const-item-interior-mutations-const-cell.rs:89:17 | LL | let _ = A.as_ref_unchecked(); | -^^^^^^^^^^^^^^^^^^^ @@ -340,7 +340,7 @@ LL + static A: UnsafeCell = UnsafeCell::new(0); | warning: mutation of an interior mutable `const` item with call to `as_mut_unchecked` - --> $DIR/const-item-interior-mutations-const-cell.rs:93:17 + --> $DIR/const-item-interior-mutations-const-cell.rs:92:17 | LL | let _ = A.as_mut_unchecked(); | -^^^^^^^^^^^^^^^^^^^ @@ -357,7 +357,7 @@ LL + static A: UnsafeCell = UnsafeCell::new(0); | warning: mutation of an interior mutable `const` item with call to `get` - --> $DIR/const-item-interior-mutations-const-cell.rs:101:13 + --> $DIR/const-item-interior-mutations-const-cell.rs:100:13 | LL | let _ = A.get(); | -^^^^^^ diff --git a/tests/ui/lint/const-item-interior-mutations-const.fixed b/tests/ui/lint/const-item-interior-mutations-const.fixed index 82f3fdac43a3a..97091ab10af8b 100644 --- a/tests/ui/lint/const-item-interior-mutations-const.fixed +++ b/tests/ui/lint/const-item-interior-mutations-const.fixed @@ -6,7 +6,6 @@ #![feature(lock_value_accessors)] #![feature(once_cell_try_insert)] #![feature(once_cell_try)] -#![feature(lazy_get)] use std::sync::{Condvar, LazyLock, Mutex, Once, OnceLock, RwLock}; use std::time::Duration; diff --git a/tests/ui/lint/const-item-interior-mutations-const.rs b/tests/ui/lint/const-item-interior-mutations-const.rs index 5dbbfd8ca32f2..40565118ca797 100644 --- a/tests/ui/lint/const-item-interior-mutations-const.rs +++ b/tests/ui/lint/const-item-interior-mutations-const.rs @@ -6,7 +6,6 @@ #![feature(lock_value_accessors)] #![feature(once_cell_try_insert)] #![feature(once_cell_try)] -#![feature(lazy_get)] use std::sync::{Condvar, LazyLock, Mutex, Once, OnceLock, RwLock}; use std::time::Duration; diff --git a/tests/ui/lint/const-item-interior-mutations-const.stderr b/tests/ui/lint/const-item-interior-mutations-const.stderr index 7d3e7bee7fbb0..2fe8f190dbed8 100644 --- a/tests/ui/lint/const-item-interior-mutations-const.stderr +++ b/tests/ui/lint/const-item-interior-mutations-const.stderr @@ -1,5 +1,5 @@ warning: mutation of an interior mutable `const` item with call to `set` - --> $DIR/const-item-interior-mutations-const.rs:17:14 + --> $DIR/const-item-interior-mutations-const.rs:16:14 | LL | let _a = A.set(1); | -^^^^^^^ @@ -17,7 +17,7 @@ LL + static A: Mutex = Mutex::new(0); | warning: mutation of an interior mutable `const` item with call to `replace` - --> $DIR/const-item-interior-mutations-const.rs:20:14 + --> $DIR/const-item-interior-mutations-const.rs:19:14 | LL | let _a = A.replace(2); | -^^^^^^^^^^^ @@ -34,7 +34,7 @@ LL + static A: Mutex = Mutex::new(0); | warning: mutation of an interior mutable `const` item with call to `lock` - --> $DIR/const-item-interior-mutations-const.rs:23:10 + --> $DIR/const-item-interior-mutations-const.rs:22:10 | LL | drop(A.lock()); | -^^^^^^^ @@ -51,7 +51,7 @@ LL + static A: Mutex = Mutex::new(0); | warning: mutation of an interior mutable `const` item with call to `try_lock` - --> $DIR/const-item-interior-mutations-const.rs:26:10 + --> $DIR/const-item-interior-mutations-const.rs:25:10 | LL | drop(A.try_lock()); | -^^^^^^^^^^^ @@ -68,7 +68,7 @@ LL + static A: Mutex = Mutex::new(0); | warning: mutation of an interior mutable `const` item with call to `clear_poison` - --> $DIR/const-item-interior-mutations-const.rs:29:14 + --> $DIR/const-item-interior-mutations-const.rs:28:14 | LL | let _a = A.clear_poison(); | -^^^^^^^^^^^^^^^ @@ -85,7 +85,7 @@ LL + static A: Mutex = Mutex::new(0); | warning: mutation of an interior mutable `const` item with call to `call_once` - --> $DIR/const-item-interior-mutations-const.rs:36:14 + --> $DIR/const-item-interior-mutations-const.rs:35:14 | LL | let _a = A.call_once(|| {}); | -^^^^^^^^^^^^^^^^^ @@ -102,7 +102,7 @@ LL + static A: Once = Once::new(); | warning: mutation of an interior mutable `const` item with call to `call_once_force` - --> $DIR/const-item-interior-mutations-const.rs:39:14 + --> $DIR/const-item-interior-mutations-const.rs:38:14 | LL | let _a = A.call_once_force(|_| {}); | -^^^^^^^^^^^^^^^^^^^^^^^^ @@ -119,7 +119,7 @@ LL + static A: Once = Once::new(); | warning: mutation of an interior mutable `const` item with call to `wait` - --> $DIR/const-item-interior-mutations-const.rs:42:14 + --> $DIR/const-item-interior-mutations-const.rs:41:14 | LL | let _a = A.wait(); | -^^^^^^^ @@ -136,7 +136,7 @@ LL + static A: Once = Once::new(); | warning: mutation of an interior mutable `const` item with call to `wait_force` - --> $DIR/const-item-interior-mutations-const.rs:45:14 + --> $DIR/const-item-interior-mutations-const.rs:44:14 | LL | let _a = A.wait_force(); | -^^^^^^^^^^^^^ @@ -153,7 +153,7 @@ LL + static A: Once = Once::new(); | warning: mutation of an interior mutable `const` item with call to `set` - --> $DIR/const-item-interior-mutations-const.rs:52:14 + --> $DIR/const-item-interior-mutations-const.rs:51:14 | LL | let _a = A.set(1); | -^^^^^^^ @@ -170,7 +170,7 @@ LL + static A: RwLock = RwLock::new(0); | warning: mutation of an interior mutable `const` item with call to `replace` - --> $DIR/const-item-interior-mutations-const.rs:55:14 + --> $DIR/const-item-interior-mutations-const.rs:54:14 | LL | let _a = A.replace(2); | -^^^^^^^^^^^ @@ -187,7 +187,7 @@ LL + static A: RwLock = RwLock::new(0); | warning: mutation of an interior mutable `const` item with call to `read` - --> $DIR/const-item-interior-mutations-const.rs:58:10 + --> $DIR/const-item-interior-mutations-const.rs:57:10 | LL | drop(A.read()); | -^^^^^^^ @@ -204,7 +204,7 @@ LL + static A: RwLock = RwLock::new(0); | warning: mutation of an interior mutable `const` item with call to `try_read` - --> $DIR/const-item-interior-mutations-const.rs:61:10 + --> $DIR/const-item-interior-mutations-const.rs:60:10 | LL | drop(A.try_read()); | -^^^^^^^^^^^ @@ -221,7 +221,7 @@ LL + static A: RwLock = RwLock::new(0); | warning: mutation of an interior mutable `const` item with call to `write` - --> $DIR/const-item-interior-mutations-const.rs:64:10 + --> $DIR/const-item-interior-mutations-const.rs:63:10 | LL | drop(A.write()); | -^^^^^^^^ @@ -238,7 +238,7 @@ LL + static A: RwLock = RwLock::new(0); | warning: mutation of an interior mutable `const` item with call to `try_write` - --> $DIR/const-item-interior-mutations-const.rs:67:10 + --> $DIR/const-item-interior-mutations-const.rs:66:10 | LL | drop(A.try_write()); | -^^^^^^^^^^^^ @@ -255,7 +255,7 @@ LL + static A: RwLock = RwLock::new(0); | warning: mutation of an interior mutable `const` item with call to `force` - --> $DIR/const-item-interior-mutations-const.rs:74:14 + --> $DIR/const-item-interior-mutations-const.rs:73:14 | LL | let _a = LazyLock::force(&A); | ^^^^^^^^^^^^^^^^^-^ @@ -272,7 +272,7 @@ LL + static A: LazyLock = LazyLock::new(|| 0); | warning: mutation of an interior mutable `const` item with call to `get` - --> $DIR/const-item-interior-mutations-const.rs:77:14 + --> $DIR/const-item-interior-mutations-const.rs:76:14 | LL | let _a = LazyLock::get(&A); | ^^^^^^^^^^^^^^^-^ @@ -289,7 +289,7 @@ LL + static A: LazyLock = LazyLock::new(|| 0); | warning: mutation of an interior mutable `const` item with call to `get` - --> $DIR/const-item-interior-mutations-const.rs:84:14 + --> $DIR/const-item-interior-mutations-const.rs:83:14 | LL | let _a = A.get(); | -^^^^^^ @@ -306,7 +306,7 @@ LL + static A: OnceLock = OnceLock::new(); | warning: mutation of an interior mutable `const` item with call to `wait` - --> $DIR/const-item-interior-mutations-const.rs:87:14 + --> $DIR/const-item-interior-mutations-const.rs:86:14 | LL | let _a = A.wait(); | -^^^^^^^ @@ -323,7 +323,7 @@ LL + static A: OnceLock = OnceLock::new(); | warning: mutation of an interior mutable `const` item with call to `set` - --> $DIR/const-item-interior-mutations-const.rs:90:14 + --> $DIR/const-item-interior-mutations-const.rs:89:14 | LL | let _a = A.set(10); | -^^^^^^^^ @@ -340,7 +340,7 @@ LL + static A: OnceLock = OnceLock::new(); | warning: mutation of an interior mutable `const` item with call to `try_insert` - --> $DIR/const-item-interior-mutations-const.rs:93:14 + --> $DIR/const-item-interior-mutations-const.rs:92:14 | LL | let _a = A.try_insert(20); | -^^^^^^^^^^^^^^^ @@ -357,7 +357,7 @@ LL + static A: OnceLock = OnceLock::new(); | warning: mutation of an interior mutable `const` item with call to `get_or_init` - --> $DIR/const-item-interior-mutations-const.rs:96:14 + --> $DIR/const-item-interior-mutations-const.rs:95:14 | LL | let _a = A.get_or_init(|| 30); | -^^^^^^^^^^^^^^^^^^^ @@ -374,7 +374,7 @@ LL + static A: OnceLock = OnceLock::new(); | warning: mutation of an interior mutable `const` item with call to `get_or_try_init` - --> $DIR/const-item-interior-mutations-const.rs:99:14 + --> $DIR/const-item-interior-mutations-const.rs:98:14 | LL | let _a = A.get_or_try_init(|| Ok::<_, ()>(40)); | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -391,7 +391,7 @@ LL + static A: OnceLock = OnceLock::new(); | warning: mutation of an interior mutable `const` item with call to `wait` - --> $DIR/const-item-interior-mutations-const.rs:109:14 + --> $DIR/const-item-interior-mutations-const.rs:108:14 | LL | let _a = A.wait(guard); | -^^^^^^^^^^^^ @@ -408,7 +408,7 @@ LL + static A: Condvar = Condvar::new(); | warning: mutation of an interior mutable `const` item with call to `wait_while` - --> $DIR/const-item-interior-mutations-const.rs:114:14 + --> $DIR/const-item-interior-mutations-const.rs:113:14 | LL | let _a = A.wait_while(guard, |x| *x == 0); | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -425,7 +425,7 @@ LL + static A: Condvar = Condvar::new(); | warning: mutation of an interior mutable `const` item with call to `wait_timeout_ms` - --> $DIR/const-item-interior-mutations-const.rs:119:14 + --> $DIR/const-item-interior-mutations-const.rs:118:14 | LL | let _a = A.wait_timeout_ms(guard, 10); | -^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -442,7 +442,7 @@ LL + static A: Condvar = Condvar::new(); | warning: mutation of an interior mutable `const` item with call to `wait_timeout` - --> $DIR/const-item-interior-mutations-const.rs:124:14 + --> $DIR/const-item-interior-mutations-const.rs:123:14 | LL | let _a = A.wait_timeout(guard, Duration::from_millis(10)); | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -459,7 +459,7 @@ LL + static A: Condvar = Condvar::new(); | warning: mutation of an interior mutable `const` item with call to `wait_timeout_while` - --> $DIR/const-item-interior-mutations-const.rs:129:14 + --> $DIR/const-item-interior-mutations-const.rs:128:14 | LL | let _a = A.wait_timeout_while(guard, Duration::from_millis(10), |x| *x == 0); | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -476,7 +476,7 @@ LL + static A: Condvar = Condvar::new(); | warning: mutation of an interior mutable `const` item with call to `notify_one` - --> $DIR/const-item-interior-mutations-const.rs:132:14 + --> $DIR/const-item-interior-mutations-const.rs:131:14 | LL | let _a = A.notify_one(); | -^^^^^^^^^^^^^ @@ -493,7 +493,7 @@ LL + static A: Condvar = Condvar::new(); | warning: mutation of an interior mutable `const` item with call to `notify_all` - --> $DIR/const-item-interior-mutations-const.rs:135:14 + --> $DIR/const-item-interior-mutations-const.rs:134:14 | LL | let _a = A.notify_all(); | -^^^^^^^^^^^^^ From b7729998d25a158a6925f737f4c164ec0572ff10 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Sat, 20 Dec 2025 14:08:21 +1100 Subject: [PATCH 2/3] Classify `TestableCase::Constant` into multiple sub-kinds --- .../src/builder/matches/buckets.rs | 21 ++++++++------- .../src/builder/matches/match_pair.rs | 26 +++++++++++++++++-- .../src/builder/matches/mod.rs | 21 ++++++++++++++- .../src/builder/matches/test.rs | 15 +++++------ 4 files changed, 61 insertions(+), 22 deletions(-) diff --git a/compiler/rustc_mir_build/src/builder/matches/buckets.rs b/compiler/rustc_mir_build/src/builder/matches/buckets.rs index 8cbbb8e14095a..5275a1bb620ed 100644 --- a/compiler/rustc_mir_build/src/builder/matches/buckets.rs +++ b/compiler/rustc_mir_build/src/builder/matches/buckets.rs @@ -6,8 +6,7 @@ use rustc_middle::span_bug; use tracing::debug; use crate::builder::Builder; -use crate::builder::matches::test::is_switch_ty; -use crate::builder::matches::{Candidate, Test, TestBranch, TestKind, TestableCase}; +use crate::builder::matches::{Candidate, PatConstKind, Test, TestBranch, TestKind, TestableCase}; /// Output of [`Builder::partition_candidates_into_buckets`]. pub(crate) struct PartitionedCandidates<'tcx, 'b, 'c> { @@ -157,11 +156,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // // FIXME(#29623) we could use PatKind::Range to rule // things out here, in some cases. - // - // FIXME(Zalathar): Is the `is_switch_ty` test unnecessary? - (TestKind::SwitchInt, &TestableCase::Constant { value }) - if is_switch_ty(match_pair.pattern_ty) => - { + ( + TestKind::SwitchInt, + &TestableCase::Constant { value, kind: PatConstKind::IntOrChar }, + ) => { // An important invariant of candidate bucketing is that a candidate // must not match in multiple branches. For `SwitchInt` tests, adding // a new value might invalidate that property for range patterns that @@ -206,7 +204,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { }) } - (TestKind::If, TestableCase::Constant { value }) => { + (TestKind::If, TestableCase::Constant { value, kind: PatConstKind::Bool }) => { fully_matched = true; let value = value.try_to_bool().unwrap_or_else(|| { span_bug!(test.span, "expected boolean value but got {value:?}") @@ -291,7 +289,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { if !test.overlaps(pat, self.tcx)? { Some(TestBranch::Failure) } else { None } } } - (TestKind::Range(range), &TestableCase::Constant { value }) => { + (TestKind::Range(range), &TestableCase::Constant { value, kind: _ }) => { fully_matched = false; if !range.contains(value, self.tcx)? { // `value` is not contained in the testing range, @@ -302,7 +300,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } } - (TestKind::Eq { value: test_val, .. }, TestableCase::Constant { value: case_val }) => { + ( + TestKind::Eq { value: test_val, .. }, + TestableCase::Constant { value: case_val, kind: _ }, + ) => { if test_val == case_val { fully_matched = true; Some(TestBranch::Success) diff --git a/compiler/rustc_mir_build/src/builder/matches/match_pair.rs b/compiler/rustc_mir_build/src/builder/matches/match_pair.rs index 9b9ee18369564..c8e3628ae3466 100644 --- a/compiler/rustc_mir_build/src/builder/matches/match_pair.rs +++ b/compiler/rustc_mir_build/src/builder/matches/match_pair.rs @@ -7,7 +7,9 @@ use rustc_middle::ty::{self, Ty, TypeVisitableExt}; use crate::builder::Builder; use crate::builder::expr::as_place::{PlaceBase, PlaceBuilder}; -use crate::builder::matches::{FlatPat, MatchPairTree, PatternExtraData, TestableCase}; +use crate::builder::matches::{ + FlatPat, MatchPairTree, PatConstKind, PatternExtraData, TestableCase, +}; impl<'a, 'tcx> Builder<'a, 'tcx> { /// Builds and pushes [`MatchPairTree`] subtrees, one for each pattern in @@ -156,7 +158,27 @@ impl<'tcx> MatchPairTree<'tcx> { } } - PatKind::Constant { value } => Some(TestableCase::Constant { value }), + PatKind::Constant { value } => { + // CAUTION: The type of the pattern node (`pattern.ty`) is + // _often_ the same as the type of the const value (`value.ty`), + // but there are some cases where those types differ + // (e.g. when `deref!(..)` patterns interact with `String`). + + // Classify the constant-pattern into further kinds, to + // reduce the number of ad-hoc type tests needed later on. + let pat_ty = pattern.ty; + let const_kind = if pat_ty.is_bool() { + PatConstKind::Bool + } else if pat_ty.is_integral() || pat_ty.is_char() { + PatConstKind::IntOrChar + } else { + // FIXME(Zalathar): This still covers several different + // categories (e.g. raw pointer, string, pattern-type) + // which could be split out into their own kinds. + PatConstKind::Other + }; + Some(TestableCase::Constant { value, kind: const_kind }) + } PatKind::AscribeUserType { ascription: Ascription { ref annotation, variance }, diff --git a/compiler/rustc_mir_build/src/builder/matches/mod.rs b/compiler/rustc_mir_build/src/builder/matches/mod.rs index 8897ca7c72107..04722bf690c46 100644 --- a/compiler/rustc_mir_build/src/builder/matches/mod.rs +++ b/compiler/rustc_mir_build/src/builder/matches/mod.rs @@ -1262,7 +1262,7 @@ struct Ascription<'tcx> { #[derive(Debug, Clone)] enum TestableCase<'tcx> { Variant { adt_def: ty::AdtDef<'tcx>, variant_index: VariantIdx }, - Constant { value: ty::Value<'tcx> }, + Constant { value: ty::Value<'tcx>, kind: PatConstKind }, Range(Arc>), Slice { len: u64, variable_length: bool }, Deref { temp: Place<'tcx>, mutability: Mutability }, @@ -1276,6 +1276,25 @@ impl<'tcx> TestableCase<'tcx> { } } +/// Sub-classification of [`TestableCase::Constant`], which helps to avoid +/// some redundant ad-hoc checks when preparing and lowering tests. +#[derive(Debug, Clone)] +enum PatConstKind { + /// The primitive `bool` type, which is like an integer but simpler, + /// having only two values. + Bool, + /// Primitive unsigned/signed integer types, plus `char`. + /// These types interact nicely with `SwitchInt`. + IntOrChar, + /// Any other constant-pattern is usually tested via some kind of equality + /// check. Types that might be encountered here include: + /// - `&str` + /// - floating-point primitives, e.g. `f32`, `f64` + /// - raw pointers derived from integer values + /// - pattern types, e.g. `pattern_type!(u32 is 1..)` + Other, +} + /// Node in a tree of "match pairs", where each pair consists of a place to be /// tested, and a test to perform on that place. /// diff --git a/compiler/rustc_mir_build/src/builder/matches/test.rs b/compiler/rustc_mir_build/src/builder/matches/test.rs index 402587bff7e86..bc4966404cedc 100644 --- a/compiler/rustc_mir_build/src/builder/matches/test.rs +++ b/compiler/rustc_mir_build/src/builder/matches/test.rs @@ -19,7 +19,9 @@ use rustc_span::{DUMMY_SP, Span, Symbol, sym}; use tracing::{debug, instrument}; use crate::builder::Builder; -use crate::builder::matches::{MatchPairTree, Test, TestBranch, TestKind, TestableCase}; +use crate::builder::matches::{ + MatchPairTree, PatConstKind, Test, TestBranch, TestKind, TestableCase, +}; impl<'a, 'tcx> Builder<'a, 'tcx> { /// Identifies what test is needed to decide if `match_pair` is applicable. @@ -32,11 +34,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let kind = match match_pair.testable_case { TestableCase::Variant { adt_def, variant_index: _ } => TestKind::Switch { adt_def }, - TestableCase::Constant { .. } if match_pair.pattern_ty.is_bool() => TestKind::If, - TestableCase::Constant { .. } if is_switch_ty(match_pair.pattern_ty) => { + TestableCase::Constant { value: _, kind: PatConstKind::Bool } => TestKind::If, + TestableCase::Constant { value: _, kind: PatConstKind::IntOrChar } => { TestKind::SwitchInt } - TestableCase::Constant { value } => { + TestableCase::Constant { value, kind: PatConstKind::Other } => { TestKind::Eq { value, cast_ty: match_pair.pattern_ty } } @@ -491,11 +493,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } } -/// Returns true if this type be used with [`TestKind::SwitchInt`]. -pub(crate) fn is_switch_ty(ty: Ty<'_>) -> bool { - ty.is_integral() || ty.is_char() -} - fn trait_method<'tcx>( tcx: TyCtxt<'tcx>, trait_def_id: DefId, From 1296925d1b71fa9dbf636aa540bd7cced80c3054 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Wed, 24 Dec 2025 13:38:07 +1100 Subject: [PATCH 3/3] Split out a separate `PatConstKind::Float` Unlike the other types covered by `PatConstKind::Other`, const-float patterns can also interact with range patterns. --- .../rustc_mir_build/src/builder/matches/buckets.rs | 13 +++++++++++-- .../src/builder/matches/match_pair.rs | 2 ++ compiler/rustc_mir_build/src/builder/matches/mod.rs | 5 ++++- .../rustc_mir_build/src/builder/matches/test.rs | 3 +++ 4 files changed, 20 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_mir_build/src/builder/matches/buckets.rs b/compiler/rustc_mir_build/src/builder/matches/buckets.rs index 5275a1bb620ed..f8af50ee52fee 100644 --- a/compiler/rustc_mir_build/src/builder/matches/buckets.rs +++ b/compiler/rustc_mir_build/src/builder/matches/buckets.rs @@ -289,7 +289,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { if !test.overlaps(pat, self.tcx)? { Some(TestBranch::Failure) } else { None } } } - (TestKind::Range(range), &TestableCase::Constant { value, kind: _ }) => { + ( + TestKind::Range(range), + &TestableCase::Constant { + value, + kind: PatConstKind::Bool | PatConstKind::IntOrChar | PatConstKind::Float, + }, + ) => { fully_matched = false; if !range.contains(value, self.tcx)? { // `value` is not contained in the testing range, @@ -302,7 +308,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { ( TestKind::Eq { value: test_val, .. }, - TestableCase::Constant { value: case_val, kind: _ }, + TestableCase::Constant { + value: case_val, + kind: PatConstKind::Float | PatConstKind::Other, + }, ) => { if test_val == case_val { fully_matched = true; diff --git a/compiler/rustc_mir_build/src/builder/matches/match_pair.rs b/compiler/rustc_mir_build/src/builder/matches/match_pair.rs index c8e3628ae3466..798110c8b0902 100644 --- a/compiler/rustc_mir_build/src/builder/matches/match_pair.rs +++ b/compiler/rustc_mir_build/src/builder/matches/match_pair.rs @@ -171,6 +171,8 @@ impl<'tcx> MatchPairTree<'tcx> { PatConstKind::Bool } else if pat_ty.is_integral() || pat_ty.is_char() { PatConstKind::IntOrChar + } else if pat_ty.is_floating_point() { + PatConstKind::Float } else { // FIXME(Zalathar): This still covers several different // categories (e.g. raw pointer, string, pattern-type) diff --git a/compiler/rustc_mir_build/src/builder/matches/mod.rs b/compiler/rustc_mir_build/src/builder/matches/mod.rs index 04722bf690c46..8128ea946f08b 100644 --- a/compiler/rustc_mir_build/src/builder/matches/mod.rs +++ b/compiler/rustc_mir_build/src/builder/matches/mod.rs @@ -1286,10 +1286,13 @@ enum PatConstKind { /// Primitive unsigned/signed integer types, plus `char`. /// These types interact nicely with `SwitchInt`. IntOrChar, + /// Floating-point primitives, e.g. `f32`, `f64`. + /// These types don't support `SwitchInt` and require an equality test, + /// but can also interact with range pattern tests. + Float, /// Any other constant-pattern is usually tested via some kind of equality /// check. Types that might be encountered here include: /// - `&str` - /// - floating-point primitives, e.g. `f32`, `f64` /// - raw pointers derived from integer values /// - pattern types, e.g. `pattern_type!(u32 is 1..)` Other, diff --git a/compiler/rustc_mir_build/src/builder/matches/test.rs b/compiler/rustc_mir_build/src/builder/matches/test.rs index bc4966404cedc..f292a8e79d9df 100644 --- a/compiler/rustc_mir_build/src/builder/matches/test.rs +++ b/compiler/rustc_mir_build/src/builder/matches/test.rs @@ -38,6 +38,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { TestableCase::Constant { value: _, kind: PatConstKind::IntOrChar } => { TestKind::SwitchInt } + TestableCase::Constant { value, kind: PatConstKind::Float } => { + TestKind::Eq { value, cast_ty: match_pair.pattern_ty } + } TestableCase::Constant { value, kind: PatConstKind::Other } => { TestKind::Eq { value, cast_ty: match_pair.pattern_ty } }