From 7c96be4f2dd7c7a576ca28ae3b54fc464ab1a8ca Mon Sep 17 00:00:00 2001 From: Urgau Date: Sun, 2 Nov 2025 12:46:59 +0100 Subject: [PATCH 1/5] Add `#[rustc_must_not_call_on_interior_mutable_consts]` attribute --- .../src/attributes/lint_helpers.rs | 12 ++++++++++++ compiler/rustc_attr_parsing/src/context.rs | 2 ++ compiler/rustc_feature/src/builtin_attrs.rs | 5 +++++ compiler/rustc_hir/src/attrs/data_structures.rs | 3 +++ compiler/rustc_hir/src/attrs/encode_cross_crate.rs | 1 + compiler/rustc_passes/src/check_attr.rs | 1 + compiler/rustc_span/src/symbol.rs | 1 + 7 files changed, 25 insertions(+) diff --git a/compiler/rustc_attr_parsing/src/attributes/lint_helpers.rs b/compiler/rustc_attr_parsing/src/attributes/lint_helpers.rs index 63b0809d0d8c9..a76e6b04f9ec3 100644 --- a/compiler/rustc_attr_parsing/src/attributes/lint_helpers.rs +++ b/compiler/rustc_attr_parsing/src/attributes/lint_helpers.rs @@ -38,6 +38,18 @@ impl NoArgsAttributeParser for PassByValueParser { const CREATE: fn(Span) -> AttributeKind = AttributeKind::PassByValue; } +pub(crate) struct RustcMustNotCallOnInteriorMutableConsts; +impl NoArgsAttributeParser for RustcMustNotCallOnInteriorMutableConsts { + const PATH: &[Symbol] = &[sym::rustc_must_not_call_on_interior_mutable_consts]; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; + const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + Allow(Target::Method(MethodKind::Inherent)), + Allow(Target::Method(MethodKind::TraitImpl)), + ]); + const CREATE: fn(Span) -> AttributeKind = + AttributeKind::RustcMustNotCallOnInteriorMutableConsts; +} + pub(crate) struct AutomaticallyDerivedParser; impl NoArgsAttributeParser for AutomaticallyDerivedParser { const PATH: &[Symbol] = &[sym::automatically_derived]; diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index 15904fd7d3348..8e27937961331 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -38,6 +38,7 @@ use crate::attributes::link_attrs::{ }; use crate::attributes::lint_helpers::{ AsPtrParser, AutomaticallyDerivedParser, PassByValueParser, PubTransparentParser, + RustcMustNotCallOnInteriorMutableConsts, }; use crate::attributes::loop_match::{ConstContinueParser, LoopMatchParser}; use crate::attributes::macro_attrs::{ @@ -241,6 +242,7 @@ attribute_parsers!( Single>, Single>, Single>, + Single>, Single>, Single>, Single>, diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index 2c472801aa044..d34cb7ad68c99 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -1252,6 +1252,11 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ EncodeCrossCrate::Yes, "`#[rustc_as_ptr]` is used to mark functions returning pointers to their inner allocations." ), + rustc_attr!( + rustc_must_not_call_on_interior_mutable_consts, Normal, template!(Word), ErrorFollowing, + EncodeCrossCrate::Yes, + "`#[rustc_must_not_call_on_interior_mutable_consts]` is used to mark methods that don't make sense to be called on interior mutable consts." + ), rustc_attr!( rustc_pass_by_value, Normal, template!(Word), ErrorFollowing, EncodeCrossCrate::Yes, diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index 1bb87673d52d2..7d91ae6203828 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -676,6 +676,9 @@ pub enum AttributeKind { /// Represents `#[rustc_main]`. RustcMain, + /// Represents `#[rustc_must_not_call_on_interior_mutable_consts]` + RustcMustNotCallOnInteriorMutableConsts(Span), + /// Represents `#[rustc_object_lifetime_default]`. RustcObjectLifetimeDefault, diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs index 11c54b0ac1da0..5560c37f7f8e9 100644 --- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs +++ b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs @@ -90,6 +90,7 @@ impl AttributeKind { RustcLayoutScalarValidRangeEnd(..) => Yes, RustcLayoutScalarValidRangeStart(..) => Yes, RustcMain => No, + RustcMustNotCallOnInteriorMutableConsts(..) => Yes, RustcObjectLifetimeDefault => No, RustcSimdMonomorphizeLaneLimit(..) => Yes, // Affects layout computation, which needs to work cross-crate Sanitize { .. } => No, diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index c214104d60670..96bf7b00cad37 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -257,6 +257,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | AttributeKind::RustcLayoutScalarValidRangeStart(..) | AttributeKind::RustcLayoutScalarValidRangeEnd(..) | AttributeKind::RustcSimdMonomorphizeLaneLimit(..) + | AttributeKind::RustcMustNotCallOnInteriorMutableConsts(..) | AttributeKind::ExportStable | AttributeKind::FfiConst(..) | AttributeKind::UnstableFeatureBound(..) diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 9e8465d2da2e5..b6a570865314f 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1928,6 +1928,7 @@ symbols! { rustc_main, rustc_mir, rustc_must_implement_one_of, + rustc_must_not_call_on_interior_mutable_consts, rustc_never_returns_null_ptr, rustc_never_type_options, rustc_no_implicit_autorefs, From 20f59e0ddbb91c3f591cef0dcfb7ee8a6e79c402 Mon Sep 17 00:00:00 2001 From: Urgau Date: Sun, 2 Nov 2025 13:38:30 +0100 Subject: [PATCH 2/5] Add `#[rustc_must_not_call_on_interior_mutable_consts]` to std methods --- library/core/src/cell.rs | 17 +++++++++ library/core/src/cell/lazy.rs | 1 + library/core/src/cell/once.rs | 4 +++ library/core/src/sync/atomic.rs | 48 ++++++++++++++++++++++++++ library/std/src/sync/lazy_lock.rs | 2 ++ library/std/src/sync/once.rs | 4 +++ library/std/src/sync/once_lock.rs | 6 ++++ library/std/src/sync/poison/condvar.rs | 7 ++++ library/std/src/sync/poison/mutex.rs | 5 +++ library/std/src/sync/poison/rwlock.rs | 6 ++++ 10 files changed, 100 insertions(+) diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs index 988c50795e299..2f102bdd004f0 100644 --- a/library/core/src/cell.rs +++ b/library/core/src/cell.rs @@ -430,6 +430,7 @@ impl Cell { #[inline] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_unstable(feature = "const_cell_traits", issue = "147787")] + #[rustc_must_not_call_on_interior_mutable_consts] pub const fn set(&self, val: T) where T: [const] Destruct, @@ -461,6 +462,7 @@ impl Cell { /// ``` #[inline] #[stable(feature = "move_cell", since = "1.17.0")] + #[rustc_must_not_call_on_interior_mutable_consts] pub fn swap(&self, other: &Self) { // This function documents that it *will* panic, and intrinsics::is_nonoverlapping doesn't // do the check in const, so trying to use it here would be inviting unnecessary fragility. @@ -505,6 +507,7 @@ impl Cell { #[stable(feature = "move_cell", since = "1.17.0")] #[rustc_const_stable(feature = "const_cell", since = "1.88.0")] #[rustc_confusables("swap")] + #[rustc_must_not_call_on_interior_mutable_consts] pub const fn replace(&self, val: T) -> T { // SAFETY: This can cause data races if called from a separate thread, // but `Cell` is `!Sync` so this won't happen. @@ -546,6 +549,7 @@ impl Cell { #[inline] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_stable(feature = "const_cell", since = "1.88.0")] + #[rustc_must_not_call_on_interior_mutable_consts] pub const fn get(&self) -> T { // SAFETY: This can cause data races if called from a separate thread, // but `Cell` is `!Sync` so this won't happen. @@ -566,6 +570,7 @@ impl Cell { #[inline] #[stable(feature = "cell_update", since = "1.88.0")] #[rustc_const_unstable(feature = "const_cell_traits", issue = "147787")] + #[rustc_must_not_call_on_interior_mutable_consts] pub const fn update(&self, f: impl [const] FnOnce(T) -> T) where // FIXME(const-hack): `Copy` should imply `const Destruct` @@ -994,6 +999,7 @@ impl RefCell { #[track_caller] #[rustc_confusables("swap")] #[rustc_const_unstable(feature = "const_ref_cell", issue = "137844")] + #[rustc_must_not_call_on_interior_mutable_consts] pub const fn replace(&self, t: T) -> T { mem::replace(&mut self.borrow_mut(), t) } @@ -1017,6 +1023,7 @@ impl RefCell { #[inline] #[stable(feature = "refcell_replace_swap", since = "1.35.0")] #[track_caller] + #[rustc_must_not_call_on_interior_mutable_consts] pub fn replace_with T>(&self, f: F) -> T { let mut_borrow = &mut *self.borrow_mut(); let replacement = f(mut_borrow); @@ -1046,6 +1053,7 @@ impl RefCell { #[inline] #[stable(feature = "refcell_swap", since = "1.24.0")] #[rustc_const_unstable(feature = "const_ref_cell", issue = "137844")] + #[rustc_must_not_call_on_interior_mutable_consts] pub const fn swap(&self, other: &Self) { mem::swap(&mut *self.borrow_mut(), &mut *other.borrow_mut()) } @@ -1087,6 +1095,7 @@ impl RefCell { #[inline] #[track_caller] #[rustc_const_unstable(feature = "const_ref_cell", issue = "137844")] + #[rustc_must_not_call_on_interior_mutable_consts] pub const fn borrow(&self) -> Ref<'_, T> { match self.try_borrow() { Ok(b) => b, @@ -1123,6 +1132,7 @@ impl RefCell { #[inline] #[cfg_attr(feature = "debug_refcell", track_caller)] #[rustc_const_unstable(feature = "const_ref_cell", issue = "137844")] + #[rustc_must_not_call_on_interior_mutable_consts] pub const fn try_borrow(&self) -> Result, BorrowError> { match BorrowRef::new(&self.borrow) { Some(b) => { @@ -1185,6 +1195,7 @@ impl RefCell { #[inline] #[track_caller] #[rustc_const_unstable(feature = "const_ref_cell", issue = "137844")] + #[rustc_must_not_call_on_interior_mutable_consts] pub const fn borrow_mut(&self) -> RefMut<'_, T> { match self.try_borrow_mut() { Ok(b) => b, @@ -1218,6 +1229,7 @@ impl RefCell { #[inline] #[cfg_attr(feature = "debug_refcell", track_caller)] #[rustc_const_unstable(feature = "const_ref_cell", issue = "137844")] + #[rustc_must_not_call_on_interior_mutable_consts] pub const fn try_borrow_mut(&self) -> Result, BorrowMutError> { match BorrowRefMut::new(&self.borrow) { Some(b) => { @@ -2356,6 +2368,7 @@ impl UnsafeCell { /// ``` #[inline] #[unstable(feature = "unsafe_cell_access", issue = "136327")] + #[rustc_must_not_call_on_interior_mutable_consts] pub const unsafe fn replace(&self, value: T) -> T { // SAFETY: pointer comes from `&self` so naturally satisfies invariants. unsafe { ptr::replace(self.get(), value) } @@ -2404,6 +2417,7 @@ impl UnsafeCell { #[rustc_const_stable(feature = "const_unsafecell_get", since = "1.32.0")] #[rustc_as_ptr] #[rustc_never_returns_null_ptr] + #[rustc_must_not_call_on_interior_mutable_consts] pub const fn get(&self) -> *mut T { // We can just cast the pointer from `UnsafeCell` to `T` because of // #[repr(transparent)]. This exploits std's special status, there is @@ -2493,6 +2507,7 @@ impl UnsafeCell { /// ``` #[inline] #[unstable(feature = "unsafe_cell_access", issue = "136327")] + #[rustc_must_not_call_on_interior_mutable_consts] pub const unsafe fn as_ref_unchecked(&self) -> &T { // SAFETY: pointer comes from `&self` so naturally satisfies ptr-to-ref invariants. unsafe { self.get().as_ref_unchecked() } @@ -2521,6 +2536,7 @@ impl UnsafeCell { #[inline] #[unstable(feature = "unsafe_cell_access", issue = "136327")] #[allow(clippy::mut_from_ref)] + #[rustc_must_not_call_on_interior_mutable_consts] pub const unsafe fn as_mut_unchecked(&self) -> &mut T { // SAFETY: pointer comes from `&self` so naturally satisfies ptr-to-ref invariants. unsafe { self.get().as_mut_unchecked() } @@ -2608,6 +2624,7 @@ impl SyncUnsafeCell { #[inline] #[rustc_as_ptr] #[rustc_never_returns_null_ptr] + #[rustc_must_not_call_on_interior_mutable_consts] pub const fn get(&self) -> *mut T { self.value.get() } diff --git a/library/core/src/cell/lazy.rs b/library/core/src/cell/lazy.rs index a1bd4c8571706..ab6c80ca18252 100644 --- a/library/core/src/cell/lazy.rs +++ b/library/core/src/cell/lazy.rs @@ -134,6 +134,7 @@ impl T> LazyCell { /// ``` #[inline] #[stable(feature = "lazy_cell", since = "1.80.0")] + #[rustc_must_not_call_on_interior_mutable_consts] pub fn force(this: &LazyCell) -> &T { // SAFETY: // This invalidates any mutable references to the data. The resulting diff --git a/library/core/src/cell/once.rs b/library/core/src/cell/once.rs index 833be059d75f7..90417dad76943 100644 --- a/library/core/src/cell/once.rs +++ b/library/core/src/cell/once.rs @@ -88,6 +88,7 @@ impl OnceCell { /// ``` #[inline] #[stable(feature = "once_cell", since = "1.70.0")] + #[rustc_must_not_call_on_interior_mutable_consts] pub fn set(&self, value: T) -> Result<(), T> { match self.try_insert(value) { Ok(_) => Ok(()), @@ -120,6 +121,7 @@ impl OnceCell { /// ``` #[inline] #[unstable(feature = "once_cell_try_insert", issue = "116693")] + #[rustc_must_not_call_on_interior_mutable_consts] pub fn try_insert(&self, value: T) -> Result<&T, (&T, T)> { if let Some(old) = self.get() { return Err((old, value)); @@ -157,6 +159,7 @@ impl OnceCell { /// ``` #[inline] #[stable(feature = "once_cell", since = "1.70.0")] + #[rustc_must_not_call_on_interior_mutable_consts] pub fn get_or_init(&self, f: F) -> &T where F: FnOnce() -> T, @@ -231,6 +234,7 @@ impl OnceCell { /// assert_eq!(cell.get(), Some(&92)) /// ``` #[unstable(feature = "once_cell_try", issue = "109737")] + #[rustc_must_not_call_on_interior_mutable_consts] pub fn get_or_try_init(&self, f: F) -> Result<&T, E> where F: FnOnce() -> Result, diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs index 30a42d4eb5e64..4dccadb90db0f 100644 --- a/library/core/src/sync/atomic.rs +++ b/library/core/src/sync/atomic.rs @@ -721,6 +721,7 @@ impl AtomicBool { #[inline] #[stable(feature = "rust1", since = "1.0.0")] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[rustc_must_not_call_on_interior_mutable_consts] pub fn load(&self, order: Ordering) -> bool { // SAFETY: any data races are prevented by atomic intrinsics and the raw // pointer passed in is valid because we got it from a reference. @@ -749,6 +750,7 @@ impl AtomicBool { #[inline] #[stable(feature = "rust1", since = "1.0.0")] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[rustc_must_not_call_on_interior_mutable_consts] pub fn store(&self, val: bool, order: Ordering) { // SAFETY: any data races are prevented by atomic intrinsics and the raw // pointer passed in is valid because we got it from a reference. @@ -781,6 +783,7 @@ impl AtomicBool { #[stable(feature = "rust1", since = "1.0.0")] #[cfg(target_has_atomic = "8")] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[rustc_must_not_call_on_interior_mutable_consts] pub fn swap(&self, val: bool, order: Ordering) -> bool { if EMULATE_ATOMIC_BOOL { if val { self.fetch_or(true, order) } else { self.fetch_and(false, order) } @@ -848,6 +851,7 @@ impl AtomicBool { )] #[cfg(target_has_atomic = "8")] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[rustc_must_not_call_on_interior_mutable_consts] pub fn compare_and_swap(&self, current: bool, new: bool, order: Ordering) -> bool { match self.compare_exchange(current, new, order, strongest_failure_ordering(order)) { Ok(x) => x, @@ -909,6 +913,7 @@ impl AtomicBool { #[doc(alias = "compare_and_swap")] #[cfg(target_has_atomic = "8")] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[rustc_must_not_call_on_interior_mutable_consts] pub fn compare_exchange( &self, current: bool, @@ -1004,6 +1009,7 @@ impl AtomicBool { #[doc(alias = "compare_and_swap")] #[cfg(target_has_atomic = "8")] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[rustc_must_not_call_on_interior_mutable_consts] pub fn compare_exchange_weak( &self, current: bool, @@ -1060,6 +1066,7 @@ impl AtomicBool { #[stable(feature = "rust1", since = "1.0.0")] #[cfg(target_has_atomic = "8")] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[rustc_must_not_call_on_interior_mutable_consts] pub fn fetch_and(&self, val: bool, order: Ordering) -> bool { // SAFETY: data races are prevented by atomic intrinsics. unsafe { atomic_and(self.v.get(), val as u8, order) != 0 } @@ -1102,6 +1109,7 @@ impl AtomicBool { #[stable(feature = "rust1", since = "1.0.0")] #[cfg(target_has_atomic = "8")] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[rustc_must_not_call_on_interior_mutable_consts] pub fn fetch_nand(&self, val: bool, order: Ordering) -> bool { // We can't use atomic_nand here because it can result in a bool with // an invalid value. This happens because the atomic operation is done @@ -1154,6 +1162,7 @@ impl AtomicBool { #[stable(feature = "rust1", since = "1.0.0")] #[cfg(target_has_atomic = "8")] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[rustc_must_not_call_on_interior_mutable_consts] pub fn fetch_or(&self, val: bool, order: Ordering) -> bool { // SAFETY: data races are prevented by atomic intrinsics. unsafe { atomic_or(self.v.get(), val as u8, order) != 0 } @@ -1195,6 +1204,7 @@ impl AtomicBool { #[stable(feature = "rust1", since = "1.0.0")] #[cfg(target_has_atomic = "8")] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[rustc_must_not_call_on_interior_mutable_consts] pub fn fetch_xor(&self, val: bool, order: Ordering) -> bool { // SAFETY: data races are prevented by atomic intrinsics. unsafe { atomic_xor(self.v.get(), val as u8, order) != 0 } @@ -1232,6 +1242,7 @@ impl AtomicBool { #[stable(feature = "atomic_bool_fetch_not", since = "1.81.0")] #[cfg(target_has_atomic = "8")] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[rustc_must_not_call_on_interior_mutable_consts] pub fn fetch_not(&self, order: Ordering) -> bool { self.fetch_xor(true, order) } @@ -1270,6 +1281,7 @@ impl AtomicBool { #[stable(feature = "atomic_as_ptr", since = "1.70.0")] #[rustc_const_stable(feature = "atomic_as_ptr", since = "1.70.0")] #[rustc_never_returns_null_ptr] + #[rustc_must_not_call_on_interior_mutable_consts] pub const fn as_ptr(&self) -> *mut bool { self.v.get().cast() } @@ -1323,6 +1335,7 @@ impl AtomicBool { #[stable(feature = "atomic_fetch_update", since = "1.53.0")] #[cfg(target_has_atomic = "8")] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[rustc_must_not_call_on_interior_mutable_consts] pub fn fetch_update( &self, set_order: Ordering, @@ -1394,6 +1407,7 @@ impl AtomicBool { #[unstable(feature = "atomic_try_update", issue = "135894")] #[cfg(target_has_atomic = "8")] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[rustc_must_not_call_on_interior_mutable_consts] pub fn try_update( &self, set_order: Ordering, @@ -1452,6 +1466,7 @@ impl AtomicBool { #[unstable(feature = "atomic_try_update", issue = "135894")] #[cfg(target_has_atomic = "8")] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[rustc_must_not_call_on_interior_mutable_consts] pub fn update( &self, set_order: Ordering, @@ -1702,6 +1717,7 @@ impl AtomicPtr { #[inline] #[stable(feature = "rust1", since = "1.0.0")] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[rustc_must_not_call_on_interior_mutable_consts] pub fn load(&self, order: Ordering) -> *mut T { // SAFETY: data races are prevented by atomic intrinsics. unsafe { atomic_load(self.p.get(), order) } @@ -1731,6 +1747,7 @@ impl AtomicPtr { #[inline] #[stable(feature = "rust1", since = "1.0.0")] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[rustc_must_not_call_on_interior_mutable_consts] pub fn store(&self, ptr: *mut T, order: Ordering) { // SAFETY: data races are prevented by atomic intrinsics. unsafe { @@ -1764,6 +1781,7 @@ impl AtomicPtr { #[stable(feature = "rust1", since = "1.0.0")] #[cfg(target_has_atomic = "ptr")] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[rustc_must_not_call_on_interior_mutable_consts] pub fn swap(&self, ptr: *mut T, order: Ordering) -> *mut T { // SAFETY: data races are prevented by atomic intrinsics. unsafe { atomic_swap(self.p.get(), ptr, order) } @@ -1826,6 +1844,7 @@ impl AtomicPtr { )] #[cfg(target_has_atomic = "ptr")] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[rustc_must_not_call_on_interior_mutable_consts] pub fn compare_and_swap(&self, current: *mut T, new: *mut T, order: Ordering) -> *mut T { match self.compare_exchange(current, new, order, strongest_failure_ordering(order)) { Ok(x) => x, @@ -1880,6 +1899,7 @@ impl AtomicPtr { #[stable(feature = "extended_compare_and_swap", since = "1.10.0")] #[cfg(target_has_atomic = "ptr")] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[rustc_must_not_call_on_interior_mutable_consts] pub fn compare_exchange( &self, current: *mut T, @@ -1943,6 +1963,7 @@ impl AtomicPtr { #[stable(feature = "extended_compare_and_swap", since = "1.10.0")] #[cfg(target_has_atomic = "ptr")] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[rustc_must_not_call_on_interior_mutable_consts] pub fn compare_exchange_weak( &self, current: *mut T, @@ -2016,6 +2037,7 @@ impl AtomicPtr { #[stable(feature = "atomic_fetch_update", since = "1.53.0")] #[cfg(target_has_atomic = "ptr")] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[rustc_must_not_call_on_interior_mutable_consts] pub fn fetch_update( &self, set_order: Ordering, @@ -2096,6 +2118,7 @@ impl AtomicPtr { #[unstable(feature = "atomic_try_update", issue = "135894")] #[cfg(target_has_atomic = "ptr")] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[rustc_must_not_call_on_interior_mutable_consts] pub fn try_update( &self, set_order: Ordering, @@ -2159,6 +2182,7 @@ impl AtomicPtr { #[unstable(feature = "atomic_try_update", issue = "135894")] #[cfg(target_has_atomic = "8")] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[rustc_must_not_call_on_interior_mutable_consts] pub fn update( &self, set_order: Ordering, @@ -2210,6 +2234,7 @@ impl AtomicPtr { #[cfg(target_has_atomic = "ptr")] #[stable(feature = "strict_provenance_atomic_ptr", since = "1.91.0")] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[rustc_must_not_call_on_interior_mutable_consts] pub fn fetch_ptr_add(&self, val: usize, order: Ordering) -> *mut T { self.fetch_byte_add(val.wrapping_mul(size_of::()), order) } @@ -2254,6 +2279,7 @@ impl AtomicPtr { #[cfg(target_has_atomic = "ptr")] #[stable(feature = "strict_provenance_atomic_ptr", since = "1.91.0")] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[rustc_must_not_call_on_interior_mutable_consts] pub fn fetch_ptr_sub(&self, val: usize, order: Ordering) -> *mut T { self.fetch_byte_sub(val.wrapping_mul(size_of::()), order) } @@ -2288,6 +2314,7 @@ impl AtomicPtr { #[cfg(target_has_atomic = "ptr")] #[stable(feature = "strict_provenance_atomic_ptr", since = "1.91.0")] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[rustc_must_not_call_on_interior_mutable_consts] pub fn fetch_byte_add(&self, val: usize, order: Ordering) -> *mut T { // SAFETY: data races are prevented by atomic intrinsics. unsafe { atomic_add(self.p.get(), val, order).cast() } @@ -2323,6 +2350,7 @@ impl AtomicPtr { #[cfg(target_has_atomic = "ptr")] #[stable(feature = "strict_provenance_atomic_ptr", since = "1.91.0")] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[rustc_must_not_call_on_interior_mutable_consts] pub fn fetch_byte_sub(&self, val: usize, order: Ordering) -> *mut T { // SAFETY: data races are prevented by atomic intrinsics. unsafe { atomic_sub(self.p.get(), val, order).cast() } @@ -2373,6 +2401,7 @@ impl AtomicPtr { #[cfg(target_has_atomic = "ptr")] #[stable(feature = "strict_provenance_atomic_ptr", since = "1.91.0")] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[rustc_must_not_call_on_interior_mutable_consts] pub fn fetch_or(&self, val: usize, order: Ordering) -> *mut T { // SAFETY: data races are prevented by atomic intrinsics. unsafe { atomic_or(self.p.get(), val, order).cast() } @@ -2422,6 +2451,7 @@ impl AtomicPtr { #[cfg(target_has_atomic = "ptr")] #[stable(feature = "strict_provenance_atomic_ptr", since = "1.91.0")] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[rustc_must_not_call_on_interior_mutable_consts] pub fn fetch_and(&self, val: usize, order: Ordering) -> *mut T { // SAFETY: data races are prevented by atomic intrinsics. unsafe { atomic_and(self.p.get(), val, order).cast() } @@ -2469,6 +2499,7 @@ impl AtomicPtr { #[cfg(target_has_atomic = "ptr")] #[stable(feature = "strict_provenance_atomic_ptr", since = "1.91.0")] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[rustc_must_not_call_on_interior_mutable_consts] pub fn fetch_xor(&self, val: usize, order: Ordering) -> *mut T { // SAFETY: data races are prevented by atomic intrinsics. unsafe { atomic_xor(self.p.get(), val, order).cast() } @@ -2874,6 +2905,7 @@ macro_rules! atomic_int { #[inline] #[$stable] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[rustc_must_not_call_on_interior_mutable_consts] pub fn load(&self, order: Ordering) -> $int_type { // SAFETY: data races are prevented by atomic intrinsics. unsafe { atomic_load(self.v.get(), order) } @@ -2901,6 +2933,7 @@ macro_rules! atomic_int { #[inline] #[$stable] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[rustc_must_not_call_on_interior_mutable_consts] pub fn store(&self, val: $int_type, order: Ordering) { // SAFETY: data races are prevented by atomic intrinsics. unsafe { atomic_store(self.v.get(), val, order); } @@ -2929,6 +2962,7 @@ macro_rules! atomic_int { #[$stable] #[$cfg_cas] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[rustc_must_not_call_on_interior_mutable_consts] pub fn swap(&self, val: $int_type, order: Ordering) -> $int_type { // SAFETY: data races are prevented by atomic intrinsics. unsafe { atomic_swap(self.v.get(), val, order) } @@ -2993,6 +3027,7 @@ macro_rules! atomic_int { ] #[$cfg_cas] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[rustc_must_not_call_on_interior_mutable_consts] pub fn compare_and_swap(&self, current: $int_type, new: $int_type, @@ -3061,6 +3096,7 @@ macro_rules! atomic_int { #[$stable_cxchg] #[$cfg_cas] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[rustc_must_not_call_on_interior_mutable_consts] pub fn compare_exchange(&self, current: $int_type, new: $int_type, @@ -3124,6 +3160,7 @@ macro_rules! atomic_int { #[$stable_cxchg] #[$cfg_cas] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[rustc_must_not_call_on_interior_mutable_consts] pub fn compare_exchange_weak(&self, current: $int_type, new: $int_type, @@ -3160,6 +3197,7 @@ macro_rules! atomic_int { #[$stable] #[$cfg_cas] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[rustc_must_not_call_on_interior_mutable_consts] pub fn fetch_add(&self, val: $int_type, order: Ordering) -> $int_type { // SAFETY: data races are prevented by atomic intrinsics. unsafe { atomic_add(self.v.get(), val, order) } @@ -3190,6 +3228,7 @@ macro_rules! atomic_int { #[$stable] #[$cfg_cas] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[rustc_must_not_call_on_interior_mutable_consts] pub fn fetch_sub(&self, val: $int_type, order: Ordering) -> $int_type { // SAFETY: data races are prevented by atomic intrinsics. unsafe { atomic_sub(self.v.get(), val, order) } @@ -3223,6 +3262,7 @@ macro_rules! atomic_int { #[$stable] #[$cfg_cas] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[rustc_must_not_call_on_interior_mutable_consts] pub fn fetch_and(&self, val: $int_type, order: Ordering) -> $int_type { // SAFETY: data races are prevented by atomic intrinsics. unsafe { atomic_and(self.v.get(), val, order) } @@ -3256,6 +3296,7 @@ macro_rules! atomic_int { #[$stable_nand] #[$cfg_cas] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[rustc_must_not_call_on_interior_mutable_consts] pub fn fetch_nand(&self, val: $int_type, order: Ordering) -> $int_type { // SAFETY: data races are prevented by atomic intrinsics. unsafe { atomic_nand(self.v.get(), val, order) } @@ -3289,6 +3330,7 @@ macro_rules! atomic_int { #[$stable] #[$cfg_cas] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[rustc_must_not_call_on_interior_mutable_consts] pub fn fetch_or(&self, val: $int_type, order: Ordering) -> $int_type { // SAFETY: data races are prevented by atomic intrinsics. unsafe { atomic_or(self.v.get(), val, order) } @@ -3322,6 +3364,7 @@ macro_rules! atomic_int { #[$stable] #[$cfg_cas] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[rustc_must_not_call_on_interior_mutable_consts] pub fn fetch_xor(&self, val: $int_type, order: Ordering) -> $int_type { // SAFETY: data races are prevented by atomic intrinsics. unsafe { atomic_xor(self.v.get(), val, order) } @@ -3376,6 +3419,7 @@ macro_rules! atomic_int { #[stable(feature = "no_more_cas", since = "1.45.0")] #[$cfg_cas] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[rustc_must_not_call_on_interior_mutable_consts] pub fn fetch_update(&self, set_order: Ordering, fetch_order: Ordering, @@ -3443,6 +3487,7 @@ macro_rules! atomic_int { #[unstable(feature = "atomic_try_update", issue = "135894")] #[$cfg_cas] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[rustc_must_not_call_on_interior_mutable_consts] pub fn try_update( &self, set_order: Ordering, @@ -3504,6 +3549,7 @@ macro_rules! atomic_int { #[unstable(feature = "atomic_try_update", issue = "135894")] #[$cfg_cas] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[rustc_must_not_call_on_interior_mutable_consts] pub fn update( &self, set_order: Ordering, @@ -3558,6 +3604,7 @@ macro_rules! atomic_int { #[stable(feature = "atomic_min_max", since = "1.45.0")] #[$cfg_cas] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[rustc_must_not_call_on_interior_mutable_consts] pub fn fetch_max(&self, val: $int_type, order: Ordering) -> $int_type { // SAFETY: data races are prevented by atomic intrinsics. unsafe { $max_fn(self.v.get(), val, order) } @@ -3604,6 +3651,7 @@ macro_rules! atomic_int { #[stable(feature = "atomic_min_max", since = "1.45.0")] #[$cfg_cas] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[rustc_must_not_call_on_interior_mutable_consts] pub fn fetch_min(&self, val: $int_type, order: Ordering) -> $int_type { // SAFETY: data races are prevented by atomic intrinsics. unsafe { $min_fn(self.v.get(), val, order) } diff --git a/library/std/src/sync/lazy_lock.rs b/library/std/src/sync/lazy_lock.rs index f1cae4b207c9a..074d9fcbc3e9d 100644 --- a/library/std/src/sync/lazy_lock.rs +++ b/library/std/src/sync/lazy_lock.rs @@ -247,6 +247,7 @@ impl T> LazyLock { /// ``` #[inline] #[stable(feature = "lazy_cell", since = "1.80.0")] + #[rustc_must_not_call_on_interior_mutable_consts] pub fn force(this: &LazyLock) -> &T { this.once.call_once_force(|state| { if state.is_poisoned() { @@ -320,6 +321,7 @@ impl LazyLock { /// ``` #[inline] #[unstable(feature = "lazy_get", issue = "129333")] + #[rustc_must_not_call_on_interior_mutable_consts] pub fn get(this: &LazyLock) -> Option<&T> { if this.once.is_completed() { // SAFETY: diff --git a/library/std/src/sync/once.rs b/library/std/src/sync/once.rs index 12cc32f381d18..34ddab36470e8 100644 --- a/library/std/src/sync/once.rs +++ b/library/std/src/sync/once.rs @@ -145,6 +145,7 @@ impl Once { #[inline] #[stable(feature = "rust1", since = "1.0.0")] #[track_caller] + #[rustc_must_not_call_on_interior_mutable_consts] pub fn call_once(&self, f: F) where F: FnOnce(), @@ -204,6 +205,7 @@ impl Once { /// ``` #[inline] #[stable(feature = "once_poison", since = "1.51.0")] + #[rustc_must_not_call_on_interior_mutable_consts] pub fn call_once_force(&self, f: F) where F: FnOnce(&OnceState), @@ -288,6 +290,7 @@ impl Once { /// panicked, this method will also panic. Use [`wait_force`](Self::wait_force) /// if this behavior is not desired. #[stable(feature = "once_wait", since = "1.86.0")] + #[rustc_must_not_call_on_interior_mutable_consts] pub fn wait(&self) { if !self.inner.is_completed() { self.inner.wait(false); @@ -300,6 +303,7 @@ impl Once { /// If this [`Once`] has been poisoned, this function blocks until it /// becomes completed, unlike [`Once::wait()`], which panics in this case. #[stable(feature = "once_wait", since = "1.86.0")] + #[rustc_must_not_call_on_interior_mutable_consts] pub fn wait_force(&self) { if !self.inner.is_completed() { self.inner.wait(true); diff --git a/library/std/src/sync/once_lock.rs b/library/std/src/sync/once_lock.rs index b224044cbe09c..4f9d57e192edf 100644 --- a/library/std/src/sync/once_lock.rs +++ b/library/std/src/sync/once_lock.rs @@ -150,6 +150,7 @@ impl OnceLock { /// This method never blocks. #[inline] #[stable(feature = "once_cell", since = "1.70.0")] + #[rustc_must_not_call_on_interior_mutable_consts] pub fn get(&self) -> Option<&T> { if self.is_initialized() { // Safe b/c checked is_initialized @@ -197,6 +198,7 @@ impl OnceLock { /// ``` #[inline] #[stable(feature = "once_wait", since = "1.86.0")] + #[rustc_must_not_call_on_interior_mutable_consts] pub fn wait(&self) -> &T { self.once.wait_force(); @@ -231,6 +233,7 @@ impl OnceLock { /// ``` #[inline] #[stable(feature = "once_cell", since = "1.70.0")] + #[rustc_must_not_call_on_interior_mutable_consts] pub fn set(&self, value: T) -> Result<(), T> { match self.try_insert(value) { Ok(_) => Ok(()), @@ -270,6 +273,7 @@ impl OnceLock { /// ``` #[inline] #[unstable(feature = "once_cell_try_insert", issue = "116693")] + #[rustc_must_not_call_on_interior_mutable_consts] pub fn try_insert(&self, value: T) -> Result<&T, (&T, T)> { let mut value = Some(value); let res = self.get_or_init(|| value.take().unwrap()); @@ -308,6 +312,7 @@ impl OnceLock { /// ``` #[inline] #[stable(feature = "once_cell", since = "1.70.0")] + #[rustc_must_not_call_on_interior_mutable_consts] pub fn get_or_init(&self, f: F) -> &T where F: FnOnce() -> T, @@ -388,6 +393,7 @@ impl OnceLock { /// ``` #[inline] #[unstable(feature = "once_cell_try", issue = "109737")] + #[rustc_must_not_call_on_interior_mutable_consts] pub fn get_or_try_init(&self, f: F) -> Result<&T, E> where F: FnOnce() -> Result, diff --git a/library/std/src/sync/poison/condvar.rs b/library/std/src/sync/poison/condvar.rs index de625a6cc5f63..abbf7fd1cc175 100644 --- a/library/std/src/sync/poison/condvar.rs +++ b/library/std/src/sync/poison/condvar.rs @@ -121,6 +121,7 @@ impl Condvar { /// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_must_not_call_on_interior_mutable_consts] pub fn wait<'a, T>(&self, guard: MutexGuard<'a, T>) -> LockResult> { let poisoned = unsafe { let lock = mutex::guard_lock(&guard); @@ -177,6 +178,7 @@ impl Condvar { /// let _guard = cvar.wait_while(lock.lock().unwrap(), |pending| { *pending }).unwrap(); /// ``` #[stable(feature = "wait_until", since = "1.42.0")] + #[rustc_must_not_call_on_interior_mutable_consts] pub fn wait_while<'a, T, F>( &self, mut guard: MutexGuard<'a, T>, @@ -245,6 +247,7 @@ impl Condvar { /// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_must_not_call_on_interior_mutable_consts] #[deprecated(since = "1.6.0", note = "replaced by `std::sync::Condvar::wait_timeout`")] pub fn wait_timeout_ms<'a, T>( &self, @@ -316,6 +319,7 @@ impl Condvar { /// } /// ``` #[stable(feature = "wait_timeout", since = "1.5.0")] + #[rustc_must_not_call_on_interior_mutable_consts] pub fn wait_timeout<'a, T>( &self, guard: MutexGuard<'a, T>, @@ -382,6 +386,7 @@ impl Condvar { /// // access the locked mutex via result.0 /// ``` #[stable(feature = "wait_timeout_until", since = "1.42.0")] + #[rustc_must_not_call_on_interior_mutable_consts] pub fn wait_timeout_while<'a, T, F>( &self, mut guard: MutexGuard<'a, T>, @@ -442,6 +447,7 @@ impl Condvar { /// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_must_not_call_on_interior_mutable_consts] pub fn notify_one(&self) { self.inner.notify_one() } @@ -482,6 +488,7 @@ impl Condvar { /// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_must_not_call_on_interior_mutable_consts] pub fn notify_all(&self) { self.inner.notify_all() } diff --git a/library/std/src/sync/poison/mutex.rs b/library/std/src/sync/poison/mutex.rs index 6fdb4f6799ee5..81ff5592a7a3e 100644 --- a/library/std/src/sync/poison/mutex.rs +++ b/library/std/src/sync/poison/mutex.rs @@ -401,6 +401,7 @@ impl Mutex { /// assert_eq!(mutex.get_cloned().unwrap(), 11); /// ``` #[unstable(feature = "lock_value_accessors", issue = "133407")] + #[rustc_must_not_call_on_interior_mutable_consts] pub fn set(&self, value: T) -> Result<(), PoisonError> { if mem::needs_drop::() { // If the contained value has non-trivial destructor, we @@ -438,6 +439,7 @@ impl Mutex { /// assert_eq!(mutex.get_cloned().unwrap(), 11); /// ``` #[unstable(feature = "lock_value_accessors", issue = "133407")] + #[rustc_must_not_call_on_interior_mutable_consts] pub fn replace(&self, value: T) -> LockResult { match self.lock() { Ok(mut guard) => Ok(mem::replace(&mut *guard, value)), @@ -484,6 +486,7 @@ impl Mutex { /// assert_eq!(*mutex.lock().unwrap(), 10); /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_must_not_call_on_interior_mutable_consts] pub fn lock(&self) -> LockResult> { unsafe { self.inner.lock(); @@ -532,6 +535,7 @@ impl Mutex { /// assert_eq!(*mutex.lock().unwrap(), 10); /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_must_not_call_on_interior_mutable_consts] pub fn try_lock(&self) -> TryLockResult> { unsafe { if self.inner.try_lock() { @@ -602,6 +606,7 @@ impl Mutex { /// ``` #[inline] #[stable(feature = "mutex_unpoison", since = "1.77.0")] + #[rustc_must_not_call_on_interior_mutable_consts] pub fn clear_poison(&self) { self.poison.clear(); } diff --git a/library/std/src/sync/poison/rwlock.rs b/library/std/src/sync/poison/rwlock.rs index 10e45bc8c11a3..a6b38196212b5 100644 --- a/library/std/src/sync/poison/rwlock.rs +++ b/library/std/src/sync/poison/rwlock.rs @@ -299,6 +299,7 @@ impl RwLock { /// assert_eq!(lock.get_cloned().unwrap(), 11); /// ``` #[unstable(feature = "lock_value_accessors", issue = "133407")] + #[rustc_must_not_call_on_interior_mutable_consts] pub fn set(&self, value: T) -> Result<(), PoisonError> { if mem::needs_drop::() { // If the contained value has non-trivial destructor, we @@ -337,6 +338,7 @@ impl RwLock { /// assert_eq!(lock.get_cloned().unwrap(), 11); /// ``` #[unstable(feature = "lock_value_accessors", issue = "133407")] + #[rustc_must_not_call_on_interior_mutable_consts] pub fn replace(&self, value: T) -> LockResult { match self.write() { Ok(mut guard) => Ok(mem::replace(&mut *guard, value)), @@ -389,6 +391,7 @@ impl RwLock { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_must_not_call_on_interior_mutable_consts] pub fn read(&self) -> LockResult> { unsafe { self.inner.read(); @@ -435,6 +438,7 @@ impl RwLock { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_must_not_call_on_interior_mutable_consts] pub fn try_read(&self) -> TryLockResult> { unsafe { if self.inner.try_read() { @@ -479,6 +483,7 @@ impl RwLock { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_must_not_call_on_interior_mutable_consts] pub fn write(&self) -> LockResult> { unsafe { self.inner.write(); @@ -526,6 +531,7 @@ impl RwLock { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_must_not_call_on_interior_mutable_consts] pub fn try_write(&self) -> TryLockResult> { unsafe { if self.inner.try_write() { From a2f65c3973c9e403eed1ade7f0c3a678ca959b8c Mon Sep 17 00:00:00 2001 From: Urgau Date: Sun, 2 Nov 2025 15:19:33 +0100 Subject: [PATCH 3/5] Add `interior_mutable_const_item_mutations` lint --- compiler/rustc_lint/messages.ftl | 8 + .../rustc_lint/src/interior_mutable_consts.rs | 124 +++ compiler/rustc_lint/src/lib.rs | 3 + compiler/rustc_lint/src/lints.rs | 33 + ...e-const-item-mutations-const-atomics.fixed | 173 ++++ ...able-const-item-mutations-const-atomics.rs | 173 ++++ ...-const-item-mutations-const-atomics.stderr | 816 ++++++++++++++++++ ...mutable-const-item-mutations-const-cell.rs | 105 +++ ...ble-const-item-mutations-const-cell.stderr | 377 ++++++++ ...r-mutable-const-item-mutations-const.fixed | 139 +++ ...rior-mutable-const-item-mutations-const.rs | 139 +++ ...-mutable-const-item-mutations-const.stderr | 513 +++++++++++ 12 files changed, 2603 insertions(+) create mode 100644 compiler/rustc_lint/src/interior_mutable_consts.rs create mode 100644 tests/ui/lint/interior-mutable-const-item-mutations-const-atomics.fixed create mode 100644 tests/ui/lint/interior-mutable-const-item-mutations-const-atomics.rs create mode 100644 tests/ui/lint/interior-mutable-const-item-mutations-const-atomics.stderr create mode 100644 tests/ui/lint/interior-mutable-const-item-mutations-const-cell.rs create mode 100644 tests/ui/lint/interior-mutable-const-item-mutations-const-cell.stderr create mode 100644 tests/ui/lint/interior-mutable-const-item-mutations-const.fixed create mode 100644 tests/ui/lint/interior-mutable-const-item-mutations-const.rs create mode 100644 tests/ui/lint/interior-mutable-const-item-mutations-const.stderr diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl index 1f6a382175b7c..a179c47d7f653 100644 --- a/compiler/rustc_lint/messages.ftl +++ b/compiler/rustc_lint/messages.ftl @@ -403,6 +403,14 @@ lint_int_to_ptr_transmutes = transmuting an integer to a pointer creates a point .suggestion_with_exposed_provenance = use `std::ptr::with_exposed_provenance{$suffix}` instead to use a previously exposed provenance .suggestion_without_provenance_mut = if you truly mean to create a pointer without provenance, use `std::ptr::without_provenance_mut` +lint_interior_mutable_const_item_mutations = + mutation of an interior mutable `const` item with call to `{$method_name}` + .label = `{$const_name}` is a interior mutable `const` item of type `{$const_ty}` + .temporary = each usage of a `const` item creates a new temporary + .never_original = only the temporaries and never the original `const {$const_name}` will be modified + .suggestion_static = for a shared instance of `{$const_name}`, consider making it a `static` item instead + .help = for more details on interior mutability see + lint_invalid_asm_label_binary = avoid using labels containing only the digits `0` and `1` in inline assembly .label = use a different label that doesn't start with `0` or `1` .help = start numbering with `2` instead diff --git a/compiler/rustc_lint/src/interior_mutable_consts.rs b/compiler/rustc_lint/src/interior_mutable_consts.rs new file mode 100644 index 0000000000000..49fc8861fce08 --- /dev/null +++ b/compiler/rustc_lint/src/interior_mutable_consts.rs @@ -0,0 +1,124 @@ +use rustc_hir::attrs::AttributeKind; +use rustc_hir::def::{DefKind, Res}; +use rustc_hir::{Expr, ExprKind, ItemKind, Node, find_attr}; +use rustc_session::{declare_lint, declare_lint_pass}; + +use crate::lints::{ + InteriorMutableConstItemMutationsDiag, InteriorMutableConstItemMutationsSuggestionStatic, +}; +use crate::{LateContext, LateLintPass, LintContext}; + +declare_lint! { + /// The `interior_mutable_const_item_mutations` lint checks for calls which + /// mutates an interior mutable const-item. + /// + /// ### Example + /// + /// ```rust + /// use std::sync::Once; + /// + /// const INIT: Once = Once::new(); // using `INIT` will always create a temporary and + /// // never modify it-self on use, should be a `static` + /// // instead for shared use + /// + /// fn init() { + /// INIT.call_once(|| { + /// println!("Once::call_once first call"); + /// }); + /// INIT.call_once(|| { // this second will also print + /// println!("Once::call_once second call"); // as each call to `INIT` creates + /// }); // new temporary + /// } + /// ``` + /// + /// {{produces}} + /// + /// ### Explanation + /// + /// Calling a method which mutates an interior mutable type has no effect as const-item + /// are essentially inlined wherever they are used, meaning that they are copied + /// directly into the relevant context when used rendering modification through + /// interior mutability ineffective across usage of that const-item. + /// + /// The current implementation of this lint only warns on significant `std` and + /// `core` interior mutable types, like `Once`, `AtomicI32`, ... this is done out + /// of prudence to avoid false-positive and may be extended in the future. + pub INTERIOR_MUTABLE_CONST_ITEM_MUTATIONS, + Warn, + "checks for calls which mutates a interior mutable const-item" +} + +declare_lint_pass!(InteriorMutableConsts => [INTERIOR_MUTABLE_CONST_ITEM_MUTATIONS]); + +impl<'tcx> LateLintPass<'tcx> for InteriorMutableConsts { + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) { + let typeck = cx.typeck_results(); + + let (method_did, receiver) = match expr.kind { + // matching on `.method(..)` + ExprKind::MethodCall(_, receiver, _, _) => { + (typeck.type_dependent_def_id(expr.hir_id), receiver) + } + // matching on `function(&, ...)` + ExprKind::Call(path, [receiver, ..]) => match receiver.kind { + ExprKind::AddrOf(_, _, receiver) => match path.kind { + ExprKind::Path(ref qpath) => { + (cx.qpath_res(qpath, path.hir_id).opt_def_id(), receiver) + } + _ => return, + }, + _ => return, + }, + _ => return, + }; + + let Some(method_did) = method_did else { + return; + }; + + if let ExprKind::Path(qpath) = &receiver.kind + && let Res::Def(DefKind::Const | DefKind::AssocConst, const_did) = + typeck.qpath_res(qpath, receiver.hir_id) + // Let's do the attribute check after the other checks for perf reasons + && find_attr!( + cx.tcx.get_all_attrs(method_did), + AttributeKind::RustcMustNotCallOnInteriorMutableConsts(_) + ) + && let Some(method_name) = cx.tcx.opt_item_ident(method_did) + && let Some(const_name) = cx.tcx.opt_item_ident(const_did) + && let Some(const_ty) = typeck.node_type_opt(receiver.hir_id) + { + // Find the local `const`-item and create the suggestion to use `static` instead + let sugg_static = if let Some(Node::Item(const_item)) = + cx.tcx.hir_get_if_local(const_did) + && let ItemKind::Const(ident, _generics, _ty, _body_id) = const_item.kind + { + if let Some(vis_span) = const_item.vis_span.find_ancestor_inside(const_item.span) + && const_item.span.can_be_used_for_suggestions() + && vis_span.can_be_used_for_suggestions() + { + Some(InteriorMutableConstItemMutationsSuggestionStatic::Spanful { + const_: const_item.vis_span.between(ident.span), + before: if !vis_span.is_empty() { " " } else { "" }, + }) + } else { + Some(InteriorMutableConstItemMutationsSuggestionStatic::Spanless) + } + } else { + None + }; + + cx.emit_span_lint( + INTERIOR_MUTABLE_CONST_ITEM_MUTATIONS, + expr.span, + InteriorMutableConstItemMutationsDiag { + method_name, + const_name, + const_ty, + receiver_span: receiver.span, + sugg_static, + }, + ); + } + } +} diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index faaeb7706e399..384c332542de5 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -50,6 +50,7 @@ mod for_loops_over_fallibles; mod foreign_modules; mod if_let_rescope; mod impl_trait_overcaptures; +mod interior_mutable_consts; mod internal; mod invalid_from_utf8; mod late; @@ -94,6 +95,7 @@ use enum_intrinsics_non_enums::EnumIntrinsicsNonEnums; use for_loops_over_fallibles::*; use if_let_rescope::IfLetRescope; use impl_trait_overcaptures::ImplTraitOvercaptures; +use interior_mutable_consts::*; use internal::*; use invalid_from_utf8::*; use let_underscore::*; @@ -240,6 +242,7 @@ late_lint_methods!( AsyncClosureUsage: AsyncClosureUsage, AsyncFnInTrait: AsyncFnInTrait, NonLocalDefinitions: NonLocalDefinitions::default(), + InteriorMutableConsts: InteriorMutableConsts, ImplTraitOvercaptures: ImplTraitOvercaptures, IfLetRescope: IfLetRescope::default(), StaticMutRefs: StaticMutRefs, diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index c55f2b9dd6f24..50e7521ee4739 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -784,6 +784,39 @@ pub(crate) enum InvalidFromUtf8Diag { }, } +// interior_mutable_consts.rs +#[derive(LintDiagnostic)] +#[diag(lint_interior_mutable_const_item_mutations)] +#[note(lint_temporary)] +#[note(lint_never_original)] +#[help] +pub(crate) struct InteriorMutableConstItemMutationsDiag<'tcx> { + pub method_name: Ident, + pub const_name: Ident, + pub const_ty: Ty<'tcx>, + #[label] + pub receiver_span: Span, + #[subdiagnostic] + pub sugg_static: Option, +} + +#[derive(Subdiagnostic)] +pub(crate) enum InteriorMutableConstItemMutationsSuggestionStatic { + #[suggestion( + lint_suggestion_static, + code = "{before}static ", + style = "verbose", + applicability = "maybe-incorrect" + )] + Spanful { + #[primary_span] + const_: Span, + before: &'static str, + }, + #[help(lint_suggestion_static)] + Spanless, +} + // reference_casting.rs #[derive(LintDiagnostic)] pub(crate) enum InvalidReferenceCastingDiag<'tcx> { diff --git a/tests/ui/lint/interior-mutable-const-item-mutations-const-atomics.fixed b/tests/ui/lint/interior-mutable-const-item-mutations-const-atomics.fixed new file mode 100644 index 0000000000000..770f594a42c69 --- /dev/null +++ b/tests/ui/lint/interior-mutable-const-item-mutations-const-atomics.fixed @@ -0,0 +1,173 @@ +//@ check-pass +//@ run-rustfix + +#![allow(deprecated)] +#![allow(dead_code)] +#![feature(atomic_try_update)] + +use std::sync::atomic::{AtomicBool, AtomicPtr, AtomicU32, Ordering}; + +fn atomic_bool() { + static A: AtomicBool = AtomicBool::new(false); + + let _a = A.load(Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `load` + + let _a = A.store(true, Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `store` + + let _a = A.swap(true, Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `swap` + + let _a = A.compare_and_swap(false, true, Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `compare_and_swap` + + let _a = A.compare_exchange(false, true, Ordering::SeqCst, Ordering::Relaxed); + //~^ WARN mutation of an interior mutable `const` item with call to `compare_exchange` + + let _a = A.compare_exchange_weak(false, true, Ordering::SeqCst, Ordering::Relaxed); + //~^ WARN mutation of an interior mutable `const` item with call to `compare_exchange_weak` + + let _a = A.fetch_and(true, Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `fetch_and` + + let _a = A.fetch_nand(true, Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `fetch_nand` + + let _a = A.fetch_or(true, Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `fetch_or` + + let _a = A.fetch_xor(true, Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `fetch_xor` + + let _a = A.fetch_not(Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `fetch_not` + + let _a = A.fetch_update(Ordering::SeqCst, Ordering::Relaxed, |_| Some(true)); + //~^ WARN mutation of an interior mutable `const` item with call to `fetch_update` + + let _a = A.try_update(Ordering::SeqCst, Ordering::Relaxed, |_| Some(false)); + //~^ WARN mutation of an interior mutable `const` item with call to `try_update` + + let _a = A.update(Ordering::SeqCst, Ordering::Relaxed, |_| true); + //~^ WARN mutation of an interior mutable `const` item with call to `update` +} + +fn atomic_ptr() { + static A: AtomicPtr = AtomicPtr::new(std::ptr::null_mut()); + + let _a = A.load(Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `load` + + let _a = A.store(std::ptr::null_mut(), Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `store` + + let _a = A.swap(std::ptr::null_mut(), Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `swap` + + let _a = A.compare_and_swap(std::ptr::null_mut(), std::ptr::null_mut(), Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `compare_and_swap` + + let _a = A.compare_exchange( + //~^ WARN mutation of an interior mutable `const` item with call to `compare_exchange` + std::ptr::null_mut(), + std::ptr::null_mut(), + Ordering::SeqCst, + Ordering::Relaxed, + ); + + let _a = A.compare_exchange_weak( + //~^ WARN mutation of an interior mutable `const` item with call to `compare_exchange_weak` + std::ptr::null_mut(), + std::ptr::null_mut(), + Ordering::SeqCst, + Ordering::Relaxed, + ); + + let _a = A.fetch_update(Ordering::SeqCst, Ordering::Relaxed, |_| Some(std::ptr::null_mut())); + //~^ WARN mutation of an interior mutable `const` item with call to `fetch_update` + + let _a = A.try_update(Ordering::SeqCst, Ordering::Relaxed, |_| Some(std::ptr::null_mut())); + //~^ WARN mutation of an interior mutable `const` item with call to `try_update` + + let _a = A.update(Ordering::SeqCst, Ordering::Relaxed, |_| std::ptr::null_mut()); + //~^ WARN mutation of an interior mutable `const` item with call to `update` + + let _a = A.fetch_ptr_add(1, Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `fetch_ptr_add` + + let _a = A.fetch_ptr_sub(1, Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `fetch_ptr_sub` + + let _a = A.fetch_byte_add(1, Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `fetch_byte_add` + + let _a = A.fetch_byte_sub(1, Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `fetch_byte_sub` + + let _a = A.fetch_and(1, Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `fetch_and` + + let _a = A.fetch_or(1, Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `fetch_or` + + let _a = A.fetch_xor(1, Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `fetch_xor` +} + +fn atomic_u32() { + static A: AtomicU32 = AtomicU32::new(0); + + let _a = A.load(Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `load` + + let _a = A.store(1, Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `store` + + let _a = A.swap(2, Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `swap` + + let _a = A.compare_and_swap(2, 3, Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `compare_and_swap` + + let _a = A.compare_exchange(3, 4, Ordering::SeqCst, Ordering::Relaxed); + //~^ WARN mutation of an interior mutable `const` item with call to `compare_exchange` + + let _a = A.compare_exchange_weak(4, 5, Ordering::SeqCst, Ordering::Relaxed); + //~^ WARN mutation of an interior mutable `const` item with call to `compare_exchange_weak` + + let _a = A.fetch_add(1, Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `fetch_add` + + let _a = A.fetch_sub(1, Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `fetch_sub` + + let _a = A.fetch_add(2, Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `fetch_add` + + let _a = A.fetch_nand(1, Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `fetch_nand` + + let _a = A.fetch_or(1, Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `fetch_or` + + let _a = A.fetch_xor(1, Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `fetch_xor` + + let _a = A.fetch_update(Ordering::SeqCst, Ordering::Relaxed, |_| Some(10)); + //~^ WARN mutation of an interior mutable `const` item with call to `fetch_update` + + let _a = A.try_update(Ordering::SeqCst, Ordering::Relaxed, |_| Some(11)); + //~^ WARN mutation of an interior mutable `const` item with call to `try_update` + + let _a = A.update(Ordering::SeqCst, Ordering::Relaxed, |_| 12); + //~^ WARN mutation of an interior mutable `const` item with call to `update` + + let _a = A.fetch_max(20, Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `fetch_max` + + let _a = A.fetch_min(5, Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `fetch_min` +} + +fn main() {} diff --git a/tests/ui/lint/interior-mutable-const-item-mutations-const-atomics.rs b/tests/ui/lint/interior-mutable-const-item-mutations-const-atomics.rs new file mode 100644 index 0000000000000..cdccdc877f086 --- /dev/null +++ b/tests/ui/lint/interior-mutable-const-item-mutations-const-atomics.rs @@ -0,0 +1,173 @@ +//@ check-pass +//@ run-rustfix + +#![allow(deprecated)] +#![allow(dead_code)] +#![feature(atomic_try_update)] + +use std::sync::atomic::{AtomicBool, AtomicPtr, AtomicU32, Ordering}; + +fn atomic_bool() { + const A: AtomicBool = AtomicBool::new(false); + + let _a = A.load(Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `load` + + let _a = A.store(true, Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `store` + + let _a = A.swap(true, Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `swap` + + let _a = A.compare_and_swap(false, true, Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `compare_and_swap` + + let _a = A.compare_exchange(false, true, Ordering::SeqCst, Ordering::Relaxed); + //~^ WARN mutation of an interior mutable `const` item with call to `compare_exchange` + + let _a = A.compare_exchange_weak(false, true, Ordering::SeqCst, Ordering::Relaxed); + //~^ WARN mutation of an interior mutable `const` item with call to `compare_exchange_weak` + + let _a = A.fetch_and(true, Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `fetch_and` + + let _a = A.fetch_nand(true, Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `fetch_nand` + + let _a = A.fetch_or(true, Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `fetch_or` + + let _a = A.fetch_xor(true, Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `fetch_xor` + + let _a = A.fetch_not(Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `fetch_not` + + let _a = A.fetch_update(Ordering::SeqCst, Ordering::Relaxed, |_| Some(true)); + //~^ WARN mutation of an interior mutable `const` item with call to `fetch_update` + + let _a = A.try_update(Ordering::SeqCst, Ordering::Relaxed, |_| Some(false)); + //~^ WARN mutation of an interior mutable `const` item with call to `try_update` + + let _a = A.update(Ordering::SeqCst, Ordering::Relaxed, |_| true); + //~^ WARN mutation of an interior mutable `const` item with call to `update` +} + +fn atomic_ptr() { + const A: AtomicPtr = AtomicPtr::new(std::ptr::null_mut()); + + let _a = A.load(Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `load` + + let _a = A.store(std::ptr::null_mut(), Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `store` + + let _a = A.swap(std::ptr::null_mut(), Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `swap` + + let _a = A.compare_and_swap(std::ptr::null_mut(), std::ptr::null_mut(), Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `compare_and_swap` + + let _a = A.compare_exchange( + //~^ WARN mutation of an interior mutable `const` item with call to `compare_exchange` + std::ptr::null_mut(), + std::ptr::null_mut(), + Ordering::SeqCst, + Ordering::Relaxed, + ); + + let _a = A.compare_exchange_weak( + //~^ WARN mutation of an interior mutable `const` item with call to `compare_exchange_weak` + std::ptr::null_mut(), + std::ptr::null_mut(), + Ordering::SeqCst, + Ordering::Relaxed, + ); + + let _a = A.fetch_update(Ordering::SeqCst, Ordering::Relaxed, |_| Some(std::ptr::null_mut())); + //~^ WARN mutation of an interior mutable `const` item with call to `fetch_update` + + let _a = A.try_update(Ordering::SeqCst, Ordering::Relaxed, |_| Some(std::ptr::null_mut())); + //~^ WARN mutation of an interior mutable `const` item with call to `try_update` + + let _a = A.update(Ordering::SeqCst, Ordering::Relaxed, |_| std::ptr::null_mut()); + //~^ WARN mutation of an interior mutable `const` item with call to `update` + + let _a = A.fetch_ptr_add(1, Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `fetch_ptr_add` + + let _a = A.fetch_ptr_sub(1, Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `fetch_ptr_sub` + + let _a = A.fetch_byte_add(1, Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `fetch_byte_add` + + let _a = A.fetch_byte_sub(1, Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `fetch_byte_sub` + + let _a = A.fetch_and(1, Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `fetch_and` + + let _a = A.fetch_or(1, Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `fetch_or` + + let _a = A.fetch_xor(1, Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `fetch_xor` +} + +fn atomic_u32() { + const A: AtomicU32 = AtomicU32::new(0); + + let _a = A.load(Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `load` + + let _a = A.store(1, Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `store` + + let _a = A.swap(2, Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `swap` + + let _a = A.compare_and_swap(2, 3, Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `compare_and_swap` + + let _a = A.compare_exchange(3, 4, Ordering::SeqCst, Ordering::Relaxed); + //~^ WARN mutation of an interior mutable `const` item with call to `compare_exchange` + + let _a = A.compare_exchange_weak(4, 5, Ordering::SeqCst, Ordering::Relaxed); + //~^ WARN mutation of an interior mutable `const` item with call to `compare_exchange_weak` + + let _a = A.fetch_add(1, Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `fetch_add` + + let _a = A.fetch_sub(1, Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `fetch_sub` + + let _a = A.fetch_add(2, Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `fetch_add` + + let _a = A.fetch_nand(1, Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `fetch_nand` + + let _a = A.fetch_or(1, Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `fetch_or` + + let _a = A.fetch_xor(1, Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `fetch_xor` + + let _a = A.fetch_update(Ordering::SeqCst, Ordering::Relaxed, |_| Some(10)); + //~^ WARN mutation of an interior mutable `const` item with call to `fetch_update` + + let _a = A.try_update(Ordering::SeqCst, Ordering::Relaxed, |_| Some(11)); + //~^ WARN mutation of an interior mutable `const` item with call to `try_update` + + let _a = A.update(Ordering::SeqCst, Ordering::Relaxed, |_| 12); + //~^ WARN mutation of an interior mutable `const` item with call to `update` + + let _a = A.fetch_max(20, Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `fetch_max` + + let _a = A.fetch_min(5, Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `fetch_min` +} + +fn main() {} diff --git a/tests/ui/lint/interior-mutable-const-item-mutations-const-atomics.stderr b/tests/ui/lint/interior-mutable-const-item-mutations-const-atomics.stderr new file mode 100644 index 0000000000000..6689becb04783 --- /dev/null +++ b/tests/ui/lint/interior-mutable-const-item-mutations-const-atomics.stderr @@ -0,0 +1,816 @@ +warning: mutation of an interior mutable `const` item with call to `load` + --> $DIR/interior-mutable-const-item-mutations-const-atomics.rs:13:14 + | +LL | let _a = A.load(Ordering::SeqCst); + | -^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `AtomicBool` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see + = note: `#[warn(interior_mutable_const_item_mutations)]` on by default +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: AtomicBool = AtomicBool::new(false); +LL + static A: AtomicBool = AtomicBool::new(false); + | + +warning: mutation of an interior mutable `const` item with call to `store` + --> $DIR/interior-mutable-const-item-mutations-const-atomics.rs:16:14 + | +LL | let _a = A.store(true, Ordering::SeqCst); + | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `AtomicBool` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: AtomicBool = AtomicBool::new(false); +LL + static A: AtomicBool = AtomicBool::new(false); + | + +warning: mutation of an interior mutable `const` item with call to `swap` + --> $DIR/interior-mutable-const-item-mutations-const-atomics.rs:19:14 + | +LL | let _a = A.swap(true, Ordering::SeqCst); + | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `AtomicBool` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: AtomicBool = AtomicBool::new(false); +LL + static A: AtomicBool = AtomicBool::new(false); + | + +warning: mutation of an interior mutable `const` item with call to `compare_and_swap` + --> $DIR/interior-mutable-const-item-mutations-const-atomics.rs:22:14 + | +LL | let _a = A.compare_and_swap(false, true, Ordering::SeqCst); + | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `AtomicBool` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: AtomicBool = AtomicBool::new(false); +LL + static A: AtomicBool = AtomicBool::new(false); + | + +warning: mutation of an interior mutable `const` item with call to `compare_exchange` + --> $DIR/interior-mutable-const-item-mutations-const-atomics.rs:25:14 + | +LL | let _a = A.compare_exchange(false, true, Ordering::SeqCst, Ordering::Relaxed); + | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `AtomicBool` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: AtomicBool = AtomicBool::new(false); +LL + static A: AtomicBool = AtomicBool::new(false); + | + +warning: mutation of an interior mutable `const` item with call to `compare_exchange_weak` + --> $DIR/interior-mutable-const-item-mutations-const-atomics.rs:28:14 + | +LL | let _a = A.compare_exchange_weak(false, true, Ordering::SeqCst, Ordering::Relaxed); + | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `AtomicBool` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: AtomicBool = AtomicBool::new(false); +LL + static A: AtomicBool = AtomicBool::new(false); + | + +warning: mutation of an interior mutable `const` item with call to `fetch_and` + --> $DIR/interior-mutable-const-item-mutations-const-atomics.rs:31:14 + | +LL | let _a = A.fetch_and(true, Ordering::SeqCst); + | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `AtomicBool` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: AtomicBool = AtomicBool::new(false); +LL + static A: AtomicBool = AtomicBool::new(false); + | + +warning: mutation of an interior mutable `const` item with call to `fetch_nand` + --> $DIR/interior-mutable-const-item-mutations-const-atomics.rs:34:14 + | +LL | let _a = A.fetch_nand(true, Ordering::SeqCst); + | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `AtomicBool` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: AtomicBool = AtomicBool::new(false); +LL + static A: AtomicBool = AtomicBool::new(false); + | + +warning: mutation of an interior mutable `const` item with call to `fetch_or` + --> $DIR/interior-mutable-const-item-mutations-const-atomics.rs:37:14 + | +LL | let _a = A.fetch_or(true, Ordering::SeqCst); + | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `AtomicBool` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: AtomicBool = AtomicBool::new(false); +LL + static A: AtomicBool = AtomicBool::new(false); + | + +warning: mutation of an interior mutable `const` item with call to `fetch_xor` + --> $DIR/interior-mutable-const-item-mutations-const-atomics.rs:40:14 + | +LL | let _a = A.fetch_xor(true, Ordering::SeqCst); + | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `AtomicBool` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: AtomicBool = AtomicBool::new(false); +LL + static A: AtomicBool = AtomicBool::new(false); + | + +warning: mutation of an interior mutable `const` item with call to `fetch_not` + --> $DIR/interior-mutable-const-item-mutations-const-atomics.rs:43:14 + | +LL | let _a = A.fetch_not(Ordering::SeqCst); + | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `AtomicBool` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: AtomicBool = AtomicBool::new(false); +LL + static A: AtomicBool = AtomicBool::new(false); + | + +warning: mutation of an interior mutable `const` item with call to `fetch_update` + --> $DIR/interior-mutable-const-item-mutations-const-atomics.rs:46:14 + | +LL | let _a = A.fetch_update(Ordering::SeqCst, Ordering::Relaxed, |_| Some(true)); + | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `AtomicBool` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: AtomicBool = AtomicBool::new(false); +LL + static A: AtomicBool = AtomicBool::new(false); + | + +warning: mutation of an interior mutable `const` item with call to `try_update` + --> $DIR/interior-mutable-const-item-mutations-const-atomics.rs:49:14 + | +LL | let _a = A.try_update(Ordering::SeqCst, Ordering::Relaxed, |_| Some(false)); + | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `AtomicBool` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: AtomicBool = AtomicBool::new(false); +LL + static A: AtomicBool = AtomicBool::new(false); + | + +warning: mutation of an interior mutable `const` item with call to `update` + --> $DIR/interior-mutable-const-item-mutations-const-atomics.rs:52:14 + | +LL | let _a = A.update(Ordering::SeqCst, Ordering::Relaxed, |_| true); + | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `AtomicBool` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: AtomicBool = AtomicBool::new(false); +LL + static A: AtomicBool = AtomicBool::new(false); + | + +warning: mutation of an interior mutable `const` item with call to `load` + --> $DIR/interior-mutable-const-item-mutations-const-atomics.rs:59:14 + | +LL | let _a = A.load(Ordering::SeqCst); + | -^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `AtomicPtr` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: AtomicPtr = AtomicPtr::new(std::ptr::null_mut()); +LL + static A: AtomicPtr = AtomicPtr::new(std::ptr::null_mut()); + | + +warning: mutation of an interior mutable `const` item with call to `store` + --> $DIR/interior-mutable-const-item-mutations-const-atomics.rs:62:14 + | +LL | let _a = A.store(std::ptr::null_mut(), Ordering::SeqCst); + | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `AtomicPtr` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: AtomicPtr = AtomicPtr::new(std::ptr::null_mut()); +LL + static A: AtomicPtr = AtomicPtr::new(std::ptr::null_mut()); + | + +warning: mutation of an interior mutable `const` item with call to `swap` + --> $DIR/interior-mutable-const-item-mutations-const-atomics.rs:65:14 + | +LL | let _a = A.swap(std::ptr::null_mut(), Ordering::SeqCst); + | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `AtomicPtr` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: AtomicPtr = AtomicPtr::new(std::ptr::null_mut()); +LL + static A: AtomicPtr = AtomicPtr::new(std::ptr::null_mut()); + | + +warning: mutation of an interior mutable `const` item with call to `compare_and_swap` + --> $DIR/interior-mutable-const-item-mutations-const-atomics.rs:68:14 + | +LL | let _a = A.compare_and_swap(std::ptr::null_mut(), std::ptr::null_mut(), Ordering::SeqCst); + | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `AtomicPtr` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: AtomicPtr = AtomicPtr::new(std::ptr::null_mut()); +LL + static A: AtomicPtr = AtomicPtr::new(std::ptr::null_mut()); + | + +warning: mutation of an interior mutable `const` item with call to `compare_exchange` + --> $DIR/interior-mutable-const-item-mutations-const-atomics.rs:71:14 + | +LL | let _a = A.compare_exchange( + | ^ `A` is a interior mutable `const` item of type `AtomicPtr` + | ______________| + | | +LL | | +LL | | std::ptr::null_mut(), +LL | | std::ptr::null_mut(), +LL | | Ordering::SeqCst, +LL | | Ordering::Relaxed, +LL | | ); + | |_____^ + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: AtomicPtr = AtomicPtr::new(std::ptr::null_mut()); +LL + static A: AtomicPtr = AtomicPtr::new(std::ptr::null_mut()); + | + +warning: mutation of an interior mutable `const` item with call to `compare_exchange_weak` + --> $DIR/interior-mutable-const-item-mutations-const-atomics.rs:79:14 + | +LL | let _a = A.compare_exchange_weak( + | ^ `A` is a interior mutable `const` item of type `AtomicPtr` + | ______________| + | | +LL | | +LL | | std::ptr::null_mut(), +LL | | std::ptr::null_mut(), +LL | | Ordering::SeqCst, +LL | | Ordering::Relaxed, +LL | | ); + | |_____^ + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: AtomicPtr = AtomicPtr::new(std::ptr::null_mut()); +LL + static A: AtomicPtr = AtomicPtr::new(std::ptr::null_mut()); + | + +warning: mutation of an interior mutable `const` item with call to `fetch_update` + --> $DIR/interior-mutable-const-item-mutations-const-atomics.rs:87:14 + | +LL | let _a = A.fetch_update(Ordering::SeqCst, Ordering::Relaxed, |_| Some(std::ptr::null_mut())); + | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `AtomicPtr` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: AtomicPtr = AtomicPtr::new(std::ptr::null_mut()); +LL + static A: AtomicPtr = AtomicPtr::new(std::ptr::null_mut()); + | + +warning: mutation of an interior mutable `const` item with call to `try_update` + --> $DIR/interior-mutable-const-item-mutations-const-atomics.rs:90:14 + | +LL | let _a = A.try_update(Ordering::SeqCst, Ordering::Relaxed, |_| Some(std::ptr::null_mut())); + | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `AtomicPtr` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: AtomicPtr = AtomicPtr::new(std::ptr::null_mut()); +LL + static A: AtomicPtr = AtomicPtr::new(std::ptr::null_mut()); + | + +warning: mutation of an interior mutable `const` item with call to `update` + --> $DIR/interior-mutable-const-item-mutations-const-atomics.rs:93:14 + | +LL | let _a = A.update(Ordering::SeqCst, Ordering::Relaxed, |_| std::ptr::null_mut()); + | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `AtomicPtr` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: AtomicPtr = AtomicPtr::new(std::ptr::null_mut()); +LL + static A: AtomicPtr = AtomicPtr::new(std::ptr::null_mut()); + | + +warning: mutation of an interior mutable `const` item with call to `fetch_ptr_add` + --> $DIR/interior-mutable-const-item-mutations-const-atomics.rs:96:14 + | +LL | let _a = A.fetch_ptr_add(1, Ordering::SeqCst); + | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `AtomicPtr` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: AtomicPtr = AtomicPtr::new(std::ptr::null_mut()); +LL + static A: AtomicPtr = AtomicPtr::new(std::ptr::null_mut()); + | + +warning: mutation of an interior mutable `const` item with call to `fetch_ptr_sub` + --> $DIR/interior-mutable-const-item-mutations-const-atomics.rs:99:14 + | +LL | let _a = A.fetch_ptr_sub(1, Ordering::SeqCst); + | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `AtomicPtr` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: AtomicPtr = AtomicPtr::new(std::ptr::null_mut()); +LL + static A: AtomicPtr = AtomicPtr::new(std::ptr::null_mut()); + | + +warning: mutation of an interior mutable `const` item with call to `fetch_byte_add` + --> $DIR/interior-mutable-const-item-mutations-const-atomics.rs:102:14 + | +LL | let _a = A.fetch_byte_add(1, Ordering::SeqCst); + | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `AtomicPtr` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: AtomicPtr = AtomicPtr::new(std::ptr::null_mut()); +LL + static A: AtomicPtr = AtomicPtr::new(std::ptr::null_mut()); + | + +warning: mutation of an interior mutable `const` item with call to `fetch_byte_sub` + --> $DIR/interior-mutable-const-item-mutations-const-atomics.rs:105:14 + | +LL | let _a = A.fetch_byte_sub(1, Ordering::SeqCst); + | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `AtomicPtr` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: AtomicPtr = AtomicPtr::new(std::ptr::null_mut()); +LL + static A: AtomicPtr = AtomicPtr::new(std::ptr::null_mut()); + | + +warning: mutation of an interior mutable `const` item with call to `fetch_and` + --> $DIR/interior-mutable-const-item-mutations-const-atomics.rs:108:14 + | +LL | let _a = A.fetch_and(1, Ordering::SeqCst); + | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `AtomicPtr` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: AtomicPtr = AtomicPtr::new(std::ptr::null_mut()); +LL + static A: AtomicPtr = AtomicPtr::new(std::ptr::null_mut()); + | + +warning: mutation of an interior mutable `const` item with call to `fetch_or` + --> $DIR/interior-mutable-const-item-mutations-const-atomics.rs:111:14 + | +LL | let _a = A.fetch_or(1, Ordering::SeqCst); + | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `AtomicPtr` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: AtomicPtr = AtomicPtr::new(std::ptr::null_mut()); +LL + static A: AtomicPtr = AtomicPtr::new(std::ptr::null_mut()); + | + +warning: mutation of an interior mutable `const` item with call to `fetch_xor` + --> $DIR/interior-mutable-const-item-mutations-const-atomics.rs:114:14 + | +LL | let _a = A.fetch_xor(1, Ordering::SeqCst); + | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `AtomicPtr` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: AtomicPtr = AtomicPtr::new(std::ptr::null_mut()); +LL + static A: AtomicPtr = AtomicPtr::new(std::ptr::null_mut()); + | + +warning: mutation of an interior mutable `const` item with call to `load` + --> $DIR/interior-mutable-const-item-mutations-const-atomics.rs:121:14 + | +LL | let _a = A.load(Ordering::SeqCst); + | -^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `AtomicU32` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: AtomicU32 = AtomicU32::new(0); +LL + static A: AtomicU32 = AtomicU32::new(0); + | + +warning: mutation of an interior mutable `const` item with call to `store` + --> $DIR/interior-mutable-const-item-mutations-const-atomics.rs:124:14 + | +LL | let _a = A.store(1, Ordering::SeqCst); + | -^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `AtomicU32` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: AtomicU32 = AtomicU32::new(0); +LL + static A: AtomicU32 = AtomicU32::new(0); + | + +warning: mutation of an interior mutable `const` item with call to `swap` + --> $DIR/interior-mutable-const-item-mutations-const-atomics.rs:127:14 + | +LL | let _a = A.swap(2, Ordering::SeqCst); + | -^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `AtomicU32` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: AtomicU32 = AtomicU32::new(0); +LL + static A: AtomicU32 = AtomicU32::new(0); + | + +warning: mutation of an interior mutable `const` item with call to `compare_and_swap` + --> $DIR/interior-mutable-const-item-mutations-const-atomics.rs:130:14 + | +LL | let _a = A.compare_and_swap(2, 3, Ordering::SeqCst); + | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `AtomicU32` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: AtomicU32 = AtomicU32::new(0); +LL + static A: AtomicU32 = AtomicU32::new(0); + | + +warning: mutation of an interior mutable `const` item with call to `compare_exchange` + --> $DIR/interior-mutable-const-item-mutations-const-atomics.rs:133:14 + | +LL | let _a = A.compare_exchange(3, 4, Ordering::SeqCst, Ordering::Relaxed); + | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `AtomicU32` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: AtomicU32 = AtomicU32::new(0); +LL + static A: AtomicU32 = AtomicU32::new(0); + | + +warning: mutation of an interior mutable `const` item with call to `compare_exchange_weak` + --> $DIR/interior-mutable-const-item-mutations-const-atomics.rs:136:14 + | +LL | let _a = A.compare_exchange_weak(4, 5, Ordering::SeqCst, Ordering::Relaxed); + | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `AtomicU32` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: AtomicU32 = AtomicU32::new(0); +LL + static A: AtomicU32 = AtomicU32::new(0); + | + +warning: mutation of an interior mutable `const` item with call to `fetch_add` + --> $DIR/interior-mutable-const-item-mutations-const-atomics.rs:139:14 + | +LL | let _a = A.fetch_add(1, Ordering::SeqCst); + | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `AtomicU32` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: AtomicU32 = AtomicU32::new(0); +LL + static A: AtomicU32 = AtomicU32::new(0); + | + +warning: mutation of an interior mutable `const` item with call to `fetch_sub` + --> $DIR/interior-mutable-const-item-mutations-const-atomics.rs:142:14 + | +LL | let _a = A.fetch_sub(1, Ordering::SeqCst); + | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `AtomicU32` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: AtomicU32 = AtomicU32::new(0); +LL + static A: AtomicU32 = AtomicU32::new(0); + | + +warning: mutation of an interior mutable `const` item with call to `fetch_add` + --> $DIR/interior-mutable-const-item-mutations-const-atomics.rs:145:14 + | +LL | let _a = A.fetch_add(2, Ordering::SeqCst); + | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `AtomicU32` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: AtomicU32 = AtomicU32::new(0); +LL + static A: AtomicU32 = AtomicU32::new(0); + | + +warning: mutation of an interior mutable `const` item with call to `fetch_nand` + --> $DIR/interior-mutable-const-item-mutations-const-atomics.rs:148:14 + | +LL | let _a = A.fetch_nand(1, Ordering::SeqCst); + | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `AtomicU32` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: AtomicU32 = AtomicU32::new(0); +LL + static A: AtomicU32 = AtomicU32::new(0); + | + +warning: mutation of an interior mutable `const` item with call to `fetch_or` + --> $DIR/interior-mutable-const-item-mutations-const-atomics.rs:151:14 + | +LL | let _a = A.fetch_or(1, Ordering::SeqCst); + | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `AtomicU32` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: AtomicU32 = AtomicU32::new(0); +LL + static A: AtomicU32 = AtomicU32::new(0); + | + +warning: mutation of an interior mutable `const` item with call to `fetch_xor` + --> $DIR/interior-mutable-const-item-mutations-const-atomics.rs:154:14 + | +LL | let _a = A.fetch_xor(1, Ordering::SeqCst); + | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `AtomicU32` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: AtomicU32 = AtomicU32::new(0); +LL + static A: AtomicU32 = AtomicU32::new(0); + | + +warning: mutation of an interior mutable `const` item with call to `fetch_update` + --> $DIR/interior-mutable-const-item-mutations-const-atomics.rs:157:14 + | +LL | let _a = A.fetch_update(Ordering::SeqCst, Ordering::Relaxed, |_| Some(10)); + | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `AtomicU32` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: AtomicU32 = AtomicU32::new(0); +LL + static A: AtomicU32 = AtomicU32::new(0); + | + +warning: mutation of an interior mutable `const` item with call to `try_update` + --> $DIR/interior-mutable-const-item-mutations-const-atomics.rs:160:14 + | +LL | let _a = A.try_update(Ordering::SeqCst, Ordering::Relaxed, |_| Some(11)); + | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `AtomicU32` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: AtomicU32 = AtomicU32::new(0); +LL + static A: AtomicU32 = AtomicU32::new(0); + | + +warning: mutation of an interior mutable `const` item with call to `update` + --> $DIR/interior-mutable-const-item-mutations-const-atomics.rs:163:14 + | +LL | let _a = A.update(Ordering::SeqCst, Ordering::Relaxed, |_| 12); + | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `AtomicU32` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: AtomicU32 = AtomicU32::new(0); +LL + static A: AtomicU32 = AtomicU32::new(0); + | + +warning: mutation of an interior mutable `const` item with call to `fetch_max` + --> $DIR/interior-mutable-const-item-mutations-const-atomics.rs:166:14 + | +LL | let _a = A.fetch_max(20, Ordering::SeqCst); + | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `AtomicU32` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: AtomicU32 = AtomicU32::new(0); +LL + static A: AtomicU32 = AtomicU32::new(0); + | + +warning: mutation of an interior mutable `const` item with call to `fetch_min` + --> $DIR/interior-mutable-const-item-mutations-const-atomics.rs:169:14 + | +LL | let _a = A.fetch_min(5, Ordering::SeqCst); + | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `AtomicU32` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: AtomicU32 = AtomicU32::new(0); +LL + static A: AtomicU32 = AtomicU32::new(0); + | + +warning: 47 warnings emitted + diff --git a/tests/ui/lint/interior-mutable-const-item-mutations-const-cell.rs b/tests/ui/lint/interior-mutable-const-item-mutations-const-cell.rs new file mode 100644 index 0000000000000..b4a7f54c8e7a0 --- /dev/null +++ b/tests/ui/lint/interior-mutable-const-item-mutations-const-cell.rs @@ -0,0 +1,105 @@ +//@ check-pass + +#![feature(unsafe_cell_access)] +#![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}; +use std::ops::Deref; + +fn lazy_cell() { + const A: LazyCell = LazyCell::new(|| 0); + + let _ = LazyCell::force(&A); + //~^ WARN mutation of an interior mutable `const` item with call to `force` +} + +fn once_cell() { + const A: OnceCell = OnceCell::new(); + + let _ = A.set(10); + //~^ WARN mutation of an interior mutable `const` item with call to `set` + + let _ = A.try_insert(20); + //~^ WARN mutation of an interior mutable `const` item with call to `try_insert` + + let _ = A.get_or_init(|| 30); + //~^ WARN mutation of an interior mutable `const` item with call to `get_or_init` + + let _ = A.get_or_try_init(|| Ok::<_, ()>(40)); + //~^ WARN mutation of an interior mutable `const` item with call to `get_or_try_init` +} + +fn cell() { + const A: Cell = Cell::new(0); + + let _ = A.set(1); + //~^ WARN mutation of an interior mutable `const` item with call to `set` + + let _ = A.swap(&A); + //~^ WARN mutation of an interior mutable `const` item with call to `swap` + + let _ = A.replace(2); + //~^ WARN mutation of an interior mutable `const` item with call to `replace` + + let _ = A.get(); + //~^ WARN mutation of an interior mutable `const` item with call to `get` + + let _ = A.update(|x| x + 1); + //~^ WARN mutation of an interior mutable `const` item with call to `update` +} + +fn ref_cell() { + const A: RefCell = RefCell::new(0); + + let _ = A.replace(1); + //~^ WARN mutation of an interior mutable `const` item with call to `replace` + + let _ = A.replace_with(|x| *x + 2); + //~^ WARN mutation of an interior mutable `const` item with call to `replace_with` + + let _ = A.swap(&A); + //~^ WARN mutation of an interior mutable `const` item with call to `swap` + + let _ = A.borrow(); + //~^ WARN mutation of an interior mutable `const` item with call to `borrow` + + let _ = A.try_borrow(); + //~^ WARN mutation of an interior mutable `const` item with call to `try_borrow` + + let _ = A.borrow_mut(); + //~^ WARN mutation of an interior mutable `const` item with call to `borrow_mut` + + let _ = A.try_borrow_mut(); + //~^ WARN mutation of an interior mutable `const` item with call to `try_borrow_mut` +} + +fn unsafe_cell() { + const A: UnsafeCell = UnsafeCell::new(0); + + let _ = unsafe { A.replace(1) }; + //~^ WARN mutation of an interior mutable `const` item with call to `replace` + + let _ = A.get(); + //~^ WARN mutation of an interior mutable `const` item with call to `get` + + unsafe { + let _ = A.as_ref_unchecked(); + //~^ WARN mutation of an interior mutable `const` item with call to `as_ref_unchecked` + + let _ = A.as_mut_unchecked(); + //~^ WARN mutation of an interior mutable `const` item with call to `as_mut_unchecked` + } +} + +fn sync_unsafe_cell() { + const A: SyncUnsafeCell = SyncUnsafeCell::new(0); + + let _ = A.get(); + //~^ WARN mutation of an interior mutable `const` item with call to `get` +} + +fn main() {} diff --git a/tests/ui/lint/interior-mutable-const-item-mutations-const-cell.stderr b/tests/ui/lint/interior-mutable-const-item-mutations-const-cell.stderr new file mode 100644 index 0000000000000..fbd83eae0ed93 --- /dev/null +++ b/tests/ui/lint/interior-mutable-const-item-mutations-const-cell.stderr @@ -0,0 +1,377 @@ +warning: mutation of an interior mutable `const` item with call to `force` + --> $DIR/interior-mutable-const-item-mutations-const-cell.rs:16:13 + | +LL | let _ = LazyCell::force(&A); + | ^^^^^^^^^^^^^^^^^-^ + | | + | `A` is a interior mutable `const` item of type `LazyCell` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see + = note: `#[warn(interior_mutable_const_item_mutations)]` on by default +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: LazyCell = LazyCell::new(|| 0); +LL + static A: LazyCell = LazyCell::new(|| 0); + | + +warning: mutation of an interior mutable `const` item with call to `set` + --> $DIR/interior-mutable-const-item-mutations-const-cell.rs:23:13 + | +LL | let _ = A.set(10); + | -^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `OnceCell` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: OnceCell = OnceCell::new(); +LL + static A: OnceCell = OnceCell::new(); + | + +warning: mutation of an interior mutable `const` item with call to `try_insert` + --> $DIR/interior-mutable-const-item-mutations-const-cell.rs:26:13 + | +LL | let _ = A.try_insert(20); + | -^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `OnceCell` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: OnceCell = OnceCell::new(); +LL + static A: OnceCell = OnceCell::new(); + | + +warning: mutation of an interior mutable `const` item with call to `get_or_init` + --> $DIR/interior-mutable-const-item-mutations-const-cell.rs:29:13 + | +LL | let _ = A.get_or_init(|| 30); + | -^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `OnceCell` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: OnceCell = OnceCell::new(); +LL + static A: OnceCell = OnceCell::new(); + | + +warning: mutation of an interior mutable `const` item with call to `get_or_try_init` + --> $DIR/interior-mutable-const-item-mutations-const-cell.rs:32:13 + | +LL | let _ = A.get_or_try_init(|| Ok::<_, ()>(40)); + | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `OnceCell` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: OnceCell = OnceCell::new(); +LL + static A: OnceCell = OnceCell::new(); + | + +warning: mutation of an interior mutable `const` item with call to `set` + --> $DIR/interior-mutable-const-item-mutations-const-cell.rs:39:13 + | +LL | let _ = A.set(1); + | -^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `Cell` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: Cell = Cell::new(0); +LL + static A: Cell = Cell::new(0); + | + +warning: mutation of an interior mutable `const` item with call to `swap` + --> $DIR/interior-mutable-const-item-mutations-const-cell.rs:42:13 + | +LL | let _ = A.swap(&A); + | -^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `Cell` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: Cell = Cell::new(0); +LL + static A: Cell = Cell::new(0); + | + +warning: mutation of an interior mutable `const` item with call to `replace` + --> $DIR/interior-mutable-const-item-mutations-const-cell.rs:45:13 + | +LL | let _ = A.replace(2); + | -^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `Cell` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: Cell = Cell::new(0); +LL + static A: Cell = Cell::new(0); + | + +warning: mutation of an interior mutable `const` item with call to `get` + --> $DIR/interior-mutable-const-item-mutations-const-cell.rs:48:13 + | +LL | let _ = A.get(); + | -^^^^^^ + | | + | `A` is a interior mutable `const` item of type `Cell` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: Cell = Cell::new(0); +LL + static A: Cell = Cell::new(0); + | + +warning: mutation of an interior mutable `const` item with call to `update` + --> $DIR/interior-mutable-const-item-mutations-const-cell.rs:51:13 + | +LL | let _ = A.update(|x| x + 1); + | -^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `Cell` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: Cell = Cell::new(0); +LL + static A: Cell = Cell::new(0); + | + +warning: mutation of an interior mutable `const` item with call to `replace` + --> $DIR/interior-mutable-const-item-mutations-const-cell.rs:58:13 + | +LL | let _ = A.replace(1); + | -^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `RefCell` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: RefCell = RefCell::new(0); +LL + static A: RefCell = RefCell::new(0); + | + +warning: mutation of an interior mutable `const` item with call to `replace_with` + --> $DIR/interior-mutable-const-item-mutations-const-cell.rs:61:13 + | +LL | let _ = A.replace_with(|x| *x + 2); + | -^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `RefCell` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: RefCell = RefCell::new(0); +LL + static A: RefCell = RefCell::new(0); + | + +warning: mutation of an interior mutable `const` item with call to `swap` + --> $DIR/interior-mutable-const-item-mutations-const-cell.rs:64:13 + | +LL | let _ = A.swap(&A); + | -^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `RefCell` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: RefCell = RefCell::new(0); +LL + static A: RefCell = RefCell::new(0); + | + +warning: mutation of an interior mutable `const` item with call to `borrow` + --> $DIR/interior-mutable-const-item-mutations-const-cell.rs:67:13 + | +LL | let _ = A.borrow(); + | -^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `RefCell` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: RefCell = RefCell::new(0); +LL + static A: RefCell = RefCell::new(0); + | + +warning: mutation of an interior mutable `const` item with call to `try_borrow` + --> $DIR/interior-mutable-const-item-mutations-const-cell.rs:70:13 + | +LL | let _ = A.try_borrow(); + | -^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `RefCell` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: RefCell = RefCell::new(0); +LL + static A: RefCell = RefCell::new(0); + | + +warning: mutation of an interior mutable `const` item with call to `borrow_mut` + --> $DIR/interior-mutable-const-item-mutations-const-cell.rs:73:13 + | +LL | let _ = A.borrow_mut(); + | -^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `RefCell` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: RefCell = RefCell::new(0); +LL + static A: RefCell = RefCell::new(0); + | + +warning: mutation of an interior mutable `const` item with call to `try_borrow_mut` + --> $DIR/interior-mutable-const-item-mutations-const-cell.rs:76:13 + | +LL | let _ = A.try_borrow_mut(); + | -^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `RefCell` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: RefCell = RefCell::new(0); +LL + static A: RefCell = RefCell::new(0); + | + +warning: mutation of an interior mutable `const` item with call to `replace` + --> $DIR/interior-mutable-const-item-mutations-const-cell.rs:83:22 + | +LL | let _ = unsafe { A.replace(1) }; + | -^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `UnsafeCell` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: UnsafeCell = UnsafeCell::new(0); +LL + static A: UnsafeCell = UnsafeCell::new(0); + | + +warning: mutation of an interior mutable `const` item with call to `get` + --> $DIR/interior-mutable-const-item-mutations-const-cell.rs:86:13 + | +LL | let _ = A.get(); + | -^^^^^^ + | | + | `A` is a interior mutable `const` item of type `UnsafeCell` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: UnsafeCell = UnsafeCell::new(0); +LL + static A: UnsafeCell = UnsafeCell::new(0); + | + +warning: mutation of an interior mutable `const` item with call to `as_ref_unchecked` + --> $DIR/interior-mutable-const-item-mutations-const-cell.rs:90:17 + | +LL | let _ = A.as_ref_unchecked(); + | -^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `UnsafeCell` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: UnsafeCell = UnsafeCell::new(0); +LL + static A: UnsafeCell = UnsafeCell::new(0); + | + +warning: mutation of an interior mutable `const` item with call to `as_mut_unchecked` + --> $DIR/interior-mutable-const-item-mutations-const-cell.rs:93:17 + | +LL | let _ = A.as_mut_unchecked(); + | -^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `UnsafeCell` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: UnsafeCell = UnsafeCell::new(0); +LL + static A: UnsafeCell = UnsafeCell::new(0); + | + +warning: mutation of an interior mutable `const` item with call to `get` + --> $DIR/interior-mutable-const-item-mutations-const-cell.rs:101:13 + | +LL | let _ = A.get(); + | -^^^^^^ + | | + | `A` is a interior mutable `const` item of type `SyncUnsafeCell` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: SyncUnsafeCell = SyncUnsafeCell::new(0); +LL + static A: SyncUnsafeCell = SyncUnsafeCell::new(0); + | + +warning: 22 warnings emitted + diff --git a/tests/ui/lint/interior-mutable-const-item-mutations-const.fixed b/tests/ui/lint/interior-mutable-const-item-mutations-const.fixed new file mode 100644 index 0000000000000..82f3fdac43a3a --- /dev/null +++ b/tests/ui/lint/interior-mutable-const-item-mutations-const.fixed @@ -0,0 +1,139 @@ +//@ check-pass +//@ run-rustfix + +#![allow(deprecated)] +#![allow(dead_code)] +#![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; + +fn mutex() { + static A: Mutex = Mutex::new(0); + + let _a = A.set(1); + //~^ WARN mutation of an interior mutable `const` item with call to `set` + + let _a = A.replace(2); + //~^ WARN mutation of an interior mutable `const` item with call to `replace` + + drop(A.lock()); + //~^ WARN mutation of an interior mutable `const` item with call to `lock` + + drop(A.try_lock()); + //~^ WARN mutation of an interior mutable `const` item with call to `try_lock` + + let _a = A.clear_poison(); + //~^ WARN mutation of an interior mutable `const` item with call to `clear_poison` +} + +fn once() { + static A: Once = Once::new(); + + let _a = A.call_once(|| {}); + //~^ WARN mutation of an interior mutable `const` item with call to `call_once` + + let _a = A.call_once_force(|_| {}); + //~^ WARN mutation of an interior mutable `const` item with call to `call_once_force` + + let _a = A.wait(); + //~^ WARN mutation of an interior mutable `const` item with call to `wait` + + let _a = A.wait_force(); + //~^ WARN mutation of an interior mutable `const` item with call to `wait_force` +} + +fn rwlock() { + static A: RwLock = RwLock::new(0); + + let _a = A.set(1); + //~^ WARN mutation of an interior mutable `const` item with call to `set` + + let _a = A.replace(2); + //~^ WARN mutation of an interior mutable `const` item with call to `replace` + + drop(A.read()); + //~^ WARN mutation of an interior mutable `const` item with call to `read` + + drop(A.try_read()); + //~^ WARN mutation of an interior mutable `const` item with call to `try_read` + + drop(A.write()); + //~^ WARN mutation of an interior mutable `const` item with call to `write` + + drop(A.try_write()); + //~^ WARN mutation of an interior mutable `const` item with call to `try_write` +} + +fn lazy_lock() { + static A: LazyLock = LazyLock::new(|| 0); + + let _a = LazyLock::force(&A); + //~^ WARN mutation of an interior mutable `const` item with call to `force` + + let _a = LazyLock::get(&A); + //~^ WARN mutation of an interior mutable `const` item with call to `get` +} + +fn once_lock() { + static A: OnceLock = OnceLock::new(); + + let _a = A.get(); + //~^ WARN mutation of an interior mutable `const` item with call to `get` + + let _a = A.wait(); + //~^ WARN mutation of an interior mutable `const` item with call to `wait` + + let _a = A.set(10); + //~^ WARN mutation of an interior mutable `const` item with call to `set` + + let _a = A.try_insert(20); + //~^ WARN mutation of an interior mutable `const` item with call to `try_insert` + + let _a = A.get_or_init(|| 30); + //~^ WARN mutation of an interior mutable `const` item with call to `get_or_init` + + let _a = A.get_or_try_init(|| Ok::<_, ()>(40)); + //~^ WARN mutation of an interior mutable `const` item with call to `get_or_try_init` +} + +fn condvar() { + static A: Condvar = Condvar::new(); + + let mutex = Mutex::new(0); + let guard = mutex.lock().unwrap(); + + let _a = A.wait(guard); + //~^ WARN mutation of an interior mutable `const` item with call to `wait` + + let mutex = Mutex::new(0); + let guard = mutex.lock().unwrap(); + let _a = A.wait_while(guard, |x| *x == 0); + //~^ WARN mutation of an interior mutable `const` item with call to `wait_while` + + let mutex = Mutex::new(0); + let guard = mutex.lock().unwrap(); + let _a = A.wait_timeout_ms(guard, 10); + //~^ WARN mutation of an interior mutable `const` item with call to `wait_timeout_ms` + + let mutex = Mutex::new(0); + let guard = mutex.lock().unwrap(); + let _a = A.wait_timeout(guard, Duration::from_millis(10)); + //~^ WARN mutation of an interior mutable `const` item with call to `wait_timeout` + + let mutex = Mutex::new(0); + let guard = mutex.lock().unwrap(); + let _a = A.wait_timeout_while(guard, Duration::from_millis(10), |x| *x == 0); + //~^ WARN mutation of an interior mutable `const` item with call to `wait_timeout_while` + + let _a = A.notify_one(); + //~^ WARN mutation of an interior mutable `const` item with call to `notify_one` + + let _a = A.notify_all(); + //~^ WARN mutation of an interior mutable `const` item with call to `notify_all` +} + +fn main() {} diff --git a/tests/ui/lint/interior-mutable-const-item-mutations-const.rs b/tests/ui/lint/interior-mutable-const-item-mutations-const.rs new file mode 100644 index 0000000000000..5dbbfd8ca32f2 --- /dev/null +++ b/tests/ui/lint/interior-mutable-const-item-mutations-const.rs @@ -0,0 +1,139 @@ +//@ check-pass +//@ run-rustfix + +#![allow(deprecated)] +#![allow(dead_code)] +#![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; + +fn mutex() { + const A: Mutex = Mutex::new(0); + + let _a = A.set(1); + //~^ WARN mutation of an interior mutable `const` item with call to `set` + + let _a = A.replace(2); + //~^ WARN mutation of an interior mutable `const` item with call to `replace` + + drop(A.lock()); + //~^ WARN mutation of an interior mutable `const` item with call to `lock` + + drop(A.try_lock()); + //~^ WARN mutation of an interior mutable `const` item with call to `try_lock` + + let _a = A.clear_poison(); + //~^ WARN mutation of an interior mutable `const` item with call to `clear_poison` +} + +fn once() { + const A: Once = Once::new(); + + let _a = A.call_once(|| {}); + //~^ WARN mutation of an interior mutable `const` item with call to `call_once` + + let _a = A.call_once_force(|_| {}); + //~^ WARN mutation of an interior mutable `const` item with call to `call_once_force` + + let _a = A.wait(); + //~^ WARN mutation of an interior mutable `const` item with call to `wait` + + let _a = A.wait_force(); + //~^ WARN mutation of an interior mutable `const` item with call to `wait_force` +} + +fn rwlock() { + const A: RwLock = RwLock::new(0); + + let _a = A.set(1); + //~^ WARN mutation of an interior mutable `const` item with call to `set` + + let _a = A.replace(2); + //~^ WARN mutation of an interior mutable `const` item with call to `replace` + + drop(A.read()); + //~^ WARN mutation of an interior mutable `const` item with call to `read` + + drop(A.try_read()); + //~^ WARN mutation of an interior mutable `const` item with call to `try_read` + + drop(A.write()); + //~^ WARN mutation of an interior mutable `const` item with call to `write` + + drop(A.try_write()); + //~^ WARN mutation of an interior mutable `const` item with call to `try_write` +} + +fn lazy_lock() { + const A: LazyLock = LazyLock::new(|| 0); + + let _a = LazyLock::force(&A); + //~^ WARN mutation of an interior mutable `const` item with call to `force` + + let _a = LazyLock::get(&A); + //~^ WARN mutation of an interior mutable `const` item with call to `get` +} + +fn once_lock() { + const A: OnceLock = OnceLock::new(); + + let _a = A.get(); + //~^ WARN mutation of an interior mutable `const` item with call to `get` + + let _a = A.wait(); + //~^ WARN mutation of an interior mutable `const` item with call to `wait` + + let _a = A.set(10); + //~^ WARN mutation of an interior mutable `const` item with call to `set` + + let _a = A.try_insert(20); + //~^ WARN mutation of an interior mutable `const` item with call to `try_insert` + + let _a = A.get_or_init(|| 30); + //~^ WARN mutation of an interior mutable `const` item with call to `get_or_init` + + let _a = A.get_or_try_init(|| Ok::<_, ()>(40)); + //~^ WARN mutation of an interior mutable `const` item with call to `get_or_try_init` +} + +fn condvar() { + const A: Condvar = Condvar::new(); + + let mutex = Mutex::new(0); + let guard = mutex.lock().unwrap(); + + let _a = A.wait(guard); + //~^ WARN mutation of an interior mutable `const` item with call to `wait` + + let mutex = Mutex::new(0); + let guard = mutex.lock().unwrap(); + let _a = A.wait_while(guard, |x| *x == 0); + //~^ WARN mutation of an interior mutable `const` item with call to `wait_while` + + let mutex = Mutex::new(0); + let guard = mutex.lock().unwrap(); + let _a = A.wait_timeout_ms(guard, 10); + //~^ WARN mutation of an interior mutable `const` item with call to `wait_timeout_ms` + + let mutex = Mutex::new(0); + let guard = mutex.lock().unwrap(); + let _a = A.wait_timeout(guard, Duration::from_millis(10)); + //~^ WARN mutation of an interior mutable `const` item with call to `wait_timeout` + + let mutex = Mutex::new(0); + let guard = mutex.lock().unwrap(); + let _a = A.wait_timeout_while(guard, Duration::from_millis(10), |x| *x == 0); + //~^ WARN mutation of an interior mutable `const` item with call to `wait_timeout_while` + + let _a = A.notify_one(); + //~^ WARN mutation of an interior mutable `const` item with call to `notify_one` + + let _a = A.notify_all(); + //~^ WARN mutation of an interior mutable `const` item with call to `notify_all` +} + +fn main() {} diff --git a/tests/ui/lint/interior-mutable-const-item-mutations-const.stderr b/tests/ui/lint/interior-mutable-const-item-mutations-const.stderr new file mode 100644 index 0000000000000..be64bdca6df24 --- /dev/null +++ b/tests/ui/lint/interior-mutable-const-item-mutations-const.stderr @@ -0,0 +1,513 @@ +warning: mutation of an interior mutable `const` item with call to `set` + --> $DIR/interior-mutable-const-item-mutations-const.rs:17:14 + | +LL | let _a = A.set(1); + | -^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `std::sync::Mutex` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see + = note: `#[warn(interior_mutable_const_item_mutations)]` on by default +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: Mutex = Mutex::new(0); +LL + static A: Mutex = Mutex::new(0); + | + +warning: mutation of an interior mutable `const` item with call to `replace` + --> $DIR/interior-mutable-const-item-mutations-const.rs:20:14 + | +LL | let _a = A.replace(2); + | -^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `std::sync::Mutex` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: Mutex = Mutex::new(0); +LL + static A: Mutex = Mutex::new(0); + | + +warning: mutation of an interior mutable `const` item with call to `lock` + --> $DIR/interior-mutable-const-item-mutations-const.rs:23:10 + | +LL | drop(A.lock()); + | -^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `std::sync::Mutex` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: Mutex = Mutex::new(0); +LL + static A: Mutex = Mutex::new(0); + | + +warning: mutation of an interior mutable `const` item with call to `try_lock` + --> $DIR/interior-mutable-const-item-mutations-const.rs:26:10 + | +LL | drop(A.try_lock()); + | -^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `std::sync::Mutex` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: Mutex = Mutex::new(0); +LL + static A: Mutex = Mutex::new(0); + | + +warning: mutation of an interior mutable `const` item with call to `clear_poison` + --> $DIR/interior-mutable-const-item-mutations-const.rs:29:14 + | +LL | let _a = A.clear_poison(); + | -^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `std::sync::Mutex` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: Mutex = Mutex::new(0); +LL + static A: Mutex = Mutex::new(0); + | + +warning: mutation of an interior mutable `const` item with call to `call_once` + --> $DIR/interior-mutable-const-item-mutations-const.rs:36:14 + | +LL | let _a = A.call_once(|| {}); + | -^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `std::sync::Once` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: Once = Once::new(); +LL + static A: Once = Once::new(); + | + +warning: mutation of an interior mutable `const` item with call to `call_once_force` + --> $DIR/interior-mutable-const-item-mutations-const.rs:39:14 + | +LL | let _a = A.call_once_force(|_| {}); + | -^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `std::sync::Once` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: Once = Once::new(); +LL + static A: Once = Once::new(); + | + +warning: mutation of an interior mutable `const` item with call to `wait` + --> $DIR/interior-mutable-const-item-mutations-const.rs:42:14 + | +LL | let _a = A.wait(); + | -^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `std::sync::Once` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: Once = Once::new(); +LL + static A: Once = Once::new(); + | + +warning: mutation of an interior mutable `const` item with call to `wait_force` + --> $DIR/interior-mutable-const-item-mutations-const.rs:45:14 + | +LL | let _a = A.wait_force(); + | -^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `std::sync::Once` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: Once = Once::new(); +LL + static A: Once = Once::new(); + | + +warning: mutation of an interior mutable `const` item with call to `set` + --> $DIR/interior-mutable-const-item-mutations-const.rs:52:14 + | +LL | let _a = A.set(1); + | -^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `std::sync::RwLock` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: RwLock = RwLock::new(0); +LL + static A: RwLock = RwLock::new(0); + | + +warning: mutation of an interior mutable `const` item with call to `replace` + --> $DIR/interior-mutable-const-item-mutations-const.rs:55:14 + | +LL | let _a = A.replace(2); + | -^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `std::sync::RwLock` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: RwLock = RwLock::new(0); +LL + static A: RwLock = RwLock::new(0); + | + +warning: mutation of an interior mutable `const` item with call to `read` + --> $DIR/interior-mutable-const-item-mutations-const.rs:58:10 + | +LL | drop(A.read()); + | -^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `std::sync::RwLock` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: RwLock = RwLock::new(0); +LL + static A: RwLock = RwLock::new(0); + | + +warning: mutation of an interior mutable `const` item with call to `try_read` + --> $DIR/interior-mutable-const-item-mutations-const.rs:61:10 + | +LL | drop(A.try_read()); + | -^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `std::sync::RwLock` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: RwLock = RwLock::new(0); +LL + static A: RwLock = RwLock::new(0); + | + +warning: mutation of an interior mutable `const` item with call to `write` + --> $DIR/interior-mutable-const-item-mutations-const.rs:64:10 + | +LL | drop(A.write()); + | -^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `std::sync::RwLock` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: RwLock = RwLock::new(0); +LL + static A: RwLock = RwLock::new(0); + | + +warning: mutation of an interior mutable `const` item with call to `try_write` + --> $DIR/interior-mutable-const-item-mutations-const.rs:67:10 + | +LL | drop(A.try_write()); + | -^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `std::sync::RwLock` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: RwLock = RwLock::new(0); +LL + static A: RwLock = RwLock::new(0); + | + +warning: mutation of an interior mutable `const` item with call to `force` + --> $DIR/interior-mutable-const-item-mutations-const.rs:74:14 + | +LL | let _a = LazyLock::force(&A); + | ^^^^^^^^^^^^^^^^^-^ + | | + | `A` is a interior mutable `const` item of type `LazyLock` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: LazyLock = LazyLock::new(|| 0); +LL + static A: LazyLock = LazyLock::new(|| 0); + | + +warning: mutation of an interior mutable `const` item with call to `get` + --> $DIR/interior-mutable-const-item-mutations-const.rs:77:14 + | +LL | let _a = LazyLock::get(&A); + | ^^^^^^^^^^^^^^^-^ + | | + | `A` is a interior mutable `const` item of type `LazyLock` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: LazyLock = LazyLock::new(|| 0); +LL + static A: LazyLock = LazyLock::new(|| 0); + | + +warning: mutation of an interior mutable `const` item with call to `get` + --> $DIR/interior-mutable-const-item-mutations-const.rs:84:14 + | +LL | let _a = A.get(); + | -^^^^^^ + | | + | `A` is a interior mutable `const` item of type `OnceLock` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: OnceLock = OnceLock::new(); +LL + static A: OnceLock = OnceLock::new(); + | + +warning: mutation of an interior mutable `const` item with call to `wait` + --> $DIR/interior-mutable-const-item-mutations-const.rs:87:14 + | +LL | let _a = A.wait(); + | -^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `OnceLock` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: OnceLock = OnceLock::new(); +LL + static A: OnceLock = OnceLock::new(); + | + +warning: mutation of an interior mutable `const` item with call to `set` + --> $DIR/interior-mutable-const-item-mutations-const.rs:90:14 + | +LL | let _a = A.set(10); + | -^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `OnceLock` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: OnceLock = OnceLock::new(); +LL + static A: OnceLock = OnceLock::new(); + | + +warning: mutation of an interior mutable `const` item with call to `try_insert` + --> $DIR/interior-mutable-const-item-mutations-const.rs:93:14 + | +LL | let _a = A.try_insert(20); + | -^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `OnceLock` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: OnceLock = OnceLock::new(); +LL + static A: OnceLock = OnceLock::new(); + | + +warning: mutation of an interior mutable `const` item with call to `get_or_init` + --> $DIR/interior-mutable-const-item-mutations-const.rs:96:14 + | +LL | let _a = A.get_or_init(|| 30); + | -^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `OnceLock` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: OnceLock = OnceLock::new(); +LL + static A: OnceLock = OnceLock::new(); + | + +warning: mutation of an interior mutable `const` item with call to `get_or_try_init` + --> $DIR/interior-mutable-const-item-mutations-const.rs:99:14 + | +LL | let _a = A.get_or_try_init(|| Ok::<_, ()>(40)); + | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `OnceLock` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: OnceLock = OnceLock::new(); +LL + static A: OnceLock = OnceLock::new(); + | + +warning: mutation of an interior mutable `const` item with call to `wait` + --> $DIR/interior-mutable-const-item-mutations-const.rs:109:14 + | +LL | let _a = A.wait(guard); + | -^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `std::sync::Condvar` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: Condvar = Condvar::new(); +LL + static A: Condvar = Condvar::new(); + | + +warning: mutation of an interior mutable `const` item with call to `wait_while` + --> $DIR/interior-mutable-const-item-mutations-const.rs:114:14 + | +LL | let _a = A.wait_while(guard, |x| *x == 0); + | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `std::sync::Condvar` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: Condvar = Condvar::new(); +LL + static A: Condvar = Condvar::new(); + | + +warning: mutation of an interior mutable `const` item with call to `wait_timeout_ms` + --> $DIR/interior-mutable-const-item-mutations-const.rs:119:14 + | +LL | let _a = A.wait_timeout_ms(guard, 10); + | -^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `std::sync::Condvar` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: Condvar = Condvar::new(); +LL + static A: Condvar = Condvar::new(); + | + +warning: mutation of an interior mutable `const` item with call to `wait_timeout` + --> $DIR/interior-mutable-const-item-mutations-const.rs:124:14 + | +LL | let _a = A.wait_timeout(guard, Duration::from_millis(10)); + | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `std::sync::Condvar` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: Condvar = Condvar::new(); +LL + static A: Condvar = Condvar::new(); + | + +warning: mutation of an interior mutable `const` item with call to `wait_timeout_while` + --> $DIR/interior-mutable-const-item-mutations-const.rs:129:14 + | +LL | let _a = A.wait_timeout_while(guard, Duration::from_millis(10), |x| *x == 0); + | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `std::sync::Condvar` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: Condvar = Condvar::new(); +LL + static A: Condvar = Condvar::new(); + | + +warning: mutation of an interior mutable `const` item with call to `notify_one` + --> $DIR/interior-mutable-const-item-mutations-const.rs:132:14 + | +LL | let _a = A.notify_one(); + | -^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `std::sync::Condvar` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: Condvar = Condvar::new(); +LL + static A: Condvar = Condvar::new(); + | + +warning: mutation of an interior mutable `const` item with call to `notify_all` + --> $DIR/interior-mutable-const-item-mutations-const.rs:135:14 + | +LL | let _a = A.notify_all(); + | -^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `std::sync::Condvar` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: Condvar = Condvar::new(); +LL + static A: Condvar = Condvar::new(); + | + +warning: 30 warnings emitted + From f80c10cf58229a76066104d3e0310dd9da9a5c2d Mon Sep 17 00:00:00 2001 From: Urgau Date: Sun, 2 Nov 2025 16:57:29 +0100 Subject: [PATCH 4/5] Allow `interior_mutable_const_item_mutations` in Clippy tests --- .../tests/ui/borrow_interior_mutable_const.rs | 1 + .../ui/borrow_interior_mutable_const.stderr | 58 +++++++++---------- 2 files changed, 30 insertions(+), 29 deletions(-) diff --git a/src/tools/clippy/tests/ui/borrow_interior_mutable_const.rs b/src/tools/clippy/tests/ui/borrow_interior_mutable_const.rs index 674450a73ad23..66c5801046ceb 100644 --- a/src/tools/clippy/tests/ui/borrow_interior_mutable_const.rs +++ b/src/tools/clippy/tests/ui/borrow_interior_mutable_const.rs @@ -4,6 +4,7 @@ #![allow( clippy::declare_interior_mutable_const, clippy::out_of_bounds_indexing, + interior_mutable_const_item_mutations, const_item_mutation, unconditional_panic )] diff --git a/src/tools/clippy/tests/ui/borrow_interior_mutable_const.stderr b/src/tools/clippy/tests/ui/borrow_interior_mutable_const.stderr index e7c3f879b05b0..b3b1eb858e475 100644 --- a/src/tools/clippy/tests/ui/borrow_interior_mutable_const.stderr +++ b/src/tools/clippy/tests/ui/borrow_interior_mutable_const.stderr @@ -1,5 +1,5 @@ error: borrow of a named constant with interior mutability - --> tests/ui/borrow_interior_mutable_const.rs:35:17 + --> tests/ui/borrow_interior_mutable_const.rs:36:17 | LL | let _ = &C; | ^^ @@ -12,7 +12,7 @@ LL | #![deny(clippy::borrow_interior_mutable_const)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: borrow of a named constant with interior mutability - --> tests/ui/borrow_interior_mutable_const.rs:37:17 + --> tests/ui/borrow_interior_mutable_const.rs:38:17 | LL | let _ = C.get(); | ^ @@ -21,7 +21,7 @@ LL | let _ = C.get(); = help: this lint can be silenced by assigning the value to a local variable before borrowing error: borrow of a named constant with interior mutability - --> tests/ui/borrow_interior_mutable_const.rs:42:17 + --> tests/ui/borrow_interior_mutable_const.rs:43:17 | LL | let _ = &C; | ^^ @@ -29,7 +29,7 @@ LL | let _ = &C; = help: this lint can be silenced by assigning the value to a local variable before borrowing error: borrow of a named constant with interior mutability - --> tests/ui/borrow_interior_mutable_const.rs:43:17 + --> tests/ui/borrow_interior_mutable_const.rs:44:17 | LL | let _ = &mut C; | ^^^^^^ @@ -37,7 +37,7 @@ LL | let _ = &mut C; = help: this lint can be silenced by assigning the value to a local variable before borrowing error: borrow of a named constant with interior mutability - --> tests/ui/borrow_interior_mutable_const.rs:47:9 + --> tests/ui/borrow_interior_mutable_const.rs:48:9 | LL | C.swap(&local) | ^ @@ -46,7 +46,7 @@ LL | C.swap(&local) = help: this lint can be silenced by assigning the value to a local variable before borrowing error: borrow of a named constant with interior mutability - --> tests/ui/borrow_interior_mutable_const.rs:52:17 + --> tests/ui/borrow_interior_mutable_const.rs:53:17 | LL | let _ = &C; | ^^ @@ -54,7 +54,7 @@ LL | let _ = &C; = help: this lint can be silenced by assigning the value to a local variable before borrowing error: borrow of a named constant with interior mutability - --> tests/ui/borrow_interior_mutable_const.rs:53:17 + --> tests/ui/borrow_interior_mutable_const.rs:54:17 | LL | let _ = &C[0]; | ^^^^^ @@ -62,7 +62,7 @@ LL | let _ = &C[0]; = help: this lint can be silenced by assigning the value to a local variable before borrowing error: borrow of a named constant with interior mutability - --> tests/ui/borrow_interior_mutable_const.rs:54:17 + --> tests/ui/borrow_interior_mutable_const.rs:55:17 | LL | let _ = &C[0].0; | ^^^^^^^ @@ -70,7 +70,7 @@ LL | let _ = &C[0].0; = help: this lint can be silenced by assigning the value to a local variable before borrowing error: borrow of a named constant with interior mutability - --> tests/ui/borrow_interior_mutable_const.rs:55:9 + --> tests/ui/borrow_interior_mutable_const.rs:56:9 | LL | C[0].0.set(1); | ^^^^^^ @@ -79,7 +79,7 @@ LL | C[0].0.set(1); = help: this lint can be silenced by assigning the value to a local variable before borrowing error: borrow of a named constant with interior mutability - --> tests/ui/borrow_interior_mutable_const.rs:70:17 + --> tests/ui/borrow_interior_mutable_const.rs:71:17 | LL | let _ = &S::C; | ^^^^^ @@ -87,7 +87,7 @@ LL | let _ = &S::C; = help: this lint can be silenced by assigning the value to a local variable before borrowing error: borrow of a named constant with interior mutability - --> tests/ui/borrow_interior_mutable_const.rs:71:17 + --> tests/ui/borrow_interior_mutable_const.rs:72:17 | LL | let _ = &S::C.0; | ^^^^^^^ @@ -95,7 +95,7 @@ LL | let _ = &S::C.0; = help: this lint can be silenced by assigning the value to a local variable before borrowing error: borrow of a named constant with interior mutability - --> tests/ui/borrow_interior_mutable_const.rs:72:9 + --> tests/ui/borrow_interior_mutable_const.rs:73:9 | LL | S::C.set(1); | ^^^^ @@ -104,7 +104,7 @@ LL | S::C.set(1); = help: this lint can be silenced by assigning the value to a local variable before borrowing error: borrow of a named constant with interior mutability - --> tests/ui/borrow_interior_mutable_const.rs:73:18 + --> tests/ui/borrow_interior_mutable_const.rs:74:18 | LL | let _ = &*S::C; | ^^^^^ @@ -113,7 +113,7 @@ LL | let _ = &*S::C; = help: this lint can be silenced by assigning the value to a local variable before borrowing error: borrow of a named constant with interior mutability - --> tests/ui/borrow_interior_mutable_const.rs:74:9 + --> tests/ui/borrow_interior_mutable_const.rs:75:9 | LL | (*S::C).set(1); | ^^^^^^^ @@ -122,7 +122,7 @@ LL | (*S::C).set(1); = help: this lint can be silenced by assigning the value to a local variable before borrowing error: borrow of a named constant with interior mutability - --> tests/ui/borrow_interior_mutable_const.rs:85:17 + --> tests/ui/borrow_interior_mutable_const.rs:86:17 | LL | let _ = &CELL; | ^^^^^ @@ -130,7 +130,7 @@ LL | let _ = &CELL; = help: this lint can be silenced by assigning the value to a local variable before borrowing error: borrow of a named constant with interior mutability - --> tests/ui/borrow_interior_mutable_const.rs:109:25 + --> tests/ui/borrow_interior_mutable_const.rs:110:25 | LL | let _ = &Self::C; | ^^^^^^^^ @@ -138,7 +138,7 @@ LL | let _ = &Self::C; = help: this lint can be silenced by assigning the value to a local variable before borrowing error: borrow of a named constant with interior mutability - --> tests/ui/borrow_interior_mutable_const.rs:112:25 + --> tests/ui/borrow_interior_mutable_const.rs:113:25 | LL | let _ = &Self::C.cell; | ^^^^^^^^^^^^^ @@ -146,7 +146,7 @@ LL | let _ = &Self::C.cell; = help: this lint can be silenced by assigning the value to a local variable before borrowing error: borrow of a named constant with interior mutability - --> tests/ui/borrow_interior_mutable_const.rs:113:25 + --> tests/ui/borrow_interior_mutable_const.rs:114:25 | LL | let _ = &Self::C.cell.0; | ^^^^^^^^^^^^^^^ @@ -154,7 +154,7 @@ LL | let _ = &Self::C.cell.0; = help: this lint can be silenced by assigning the value to a local variable before borrowing error: borrow of a named constant with interior mutability - --> tests/ui/borrow_interior_mutable_const.rs:114:17 + --> tests/ui/borrow_interior_mutable_const.rs:115:17 | LL | Self::C.cell.0.set(T::DEFAULT); | ^^^^^^^^^^^^^^ @@ -163,7 +163,7 @@ LL | Self::C.cell.0.set(T::DEFAULT); = help: this lint can be silenced by assigning the value to a local variable before borrowing error: borrow of a named constant with interior mutability - --> tests/ui/borrow_interior_mutable_const.rs:128:17 + --> tests/ui/borrow_interior_mutable_const.rs:129:17 | LL | let _ = &u32::VALUE; | ^^^^^^^^^^^ @@ -171,7 +171,7 @@ LL | let _ = &u32::VALUE; = help: this lint can be silenced by assigning the value to a local variable before borrowing error: borrow of a named constant with interior mutability - --> tests/ui/borrow_interior_mutable_const.rs:145:21 + --> tests/ui/borrow_interior_mutable_const.rs:146:21 | LL | let _ = &>::VALUE; | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -179,7 +179,7 @@ LL | let _ = &>::VALUE; = help: this lint can be silenced by assigning the value to a local variable before borrowing error: borrow of a named constant with interior mutability - --> tests/ui/borrow_interior_mutable_const.rs:172:17 + --> tests/ui/borrow_interior_mutable_const.rs:173:17 | LL | let _ = &C; | ^^ @@ -187,7 +187,7 @@ LL | let _ = &C; = help: this lint can be silenced by assigning the value to a local variable before borrowing error: borrow of a named constant with interior mutability - --> tests/ui/borrow_interior_mutable_const.rs:173:18 + --> tests/ui/borrow_interior_mutable_const.rs:174:18 | LL | let _ = &C[0]; | ^^^^ @@ -196,7 +196,7 @@ LL | let _ = &C[0]; = help: this lint can be silenced by assigning the value to a local variable before borrowing error: borrow of a named constant with interior mutability - --> tests/ui/borrow_interior_mutable_const.rs:174:17 + --> tests/ui/borrow_interior_mutable_const.rs:175:17 | LL | let _ = &C.0[0]; | ^^^^^^^ @@ -204,7 +204,7 @@ LL | let _ = &C.0[0]; = help: this lint can be silenced by assigning the value to a local variable before borrowing error: borrow of a named constant with interior mutability - --> tests/ui/borrow_interior_mutable_const.rs:190:17 + --> tests/ui/borrow_interior_mutable_const.rs:191:17 | LL | let _ = &C[1]; | ^^^^^ @@ -212,7 +212,7 @@ LL | let _ = &C[1]; = help: this lint can be silenced by assigning the value to a local variable before borrowing error: borrow of a named constant with interior mutability - --> tests/ui/borrow_interior_mutable_const.rs:194:21 + --> tests/ui/borrow_interior_mutable_const.rs:195:21 | LL | let _ = &C[i]; | ^^^^^ @@ -220,7 +220,7 @@ LL | let _ = &C[i]; = help: this lint can be silenced by assigning the value to a local variable before borrowing error: borrow of a named constant with interior mutability - --> tests/ui/borrow_interior_mutable_const.rs:198:17 + --> tests/ui/borrow_interior_mutable_const.rs:199:17 | LL | let _ = &interior_mutable_const::WRAPPED_PRIVATE_UNFROZEN_VARIANT; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -228,7 +228,7 @@ LL | let _ = &interior_mutable_const::WRAPPED_PRIVATE_UNFROZEN_VARIANT; = help: this lint can be silenced by assigning the value to a local variable before borrowing error: borrow of a named constant with interior mutability - --> tests/ui/borrow_interior_mutable_const.rs:216:17 + --> tests/ui/borrow_interior_mutable_const.rs:217:17 | LL | let _ = &S::VALUE; | ^^^^^^^^^ @@ -236,7 +236,7 @@ LL | let _ = &S::VALUE; = help: this lint can be silenced by assigning the value to a local variable before borrowing error: borrow of a named constant with interior mutability - --> tests/ui/borrow_interior_mutable_const.rs:218:17 + --> tests/ui/borrow_interior_mutable_const.rs:219:17 | LL | let _ = &S::VALUE.1; | ^^^^^^^^^^^ From 630020b206a619aa8a6e4fb007b243f1e46f958b Mon Sep 17 00:00:00 2001 From: Urgau Date: Sun, 2 Nov 2025 18:13:14 +0100 Subject: [PATCH 5/5] Allow `interior_mutable_const_item_mutations` in tests --- tests/ui/consts/issue-17718.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/ui/consts/issue-17718.rs b/tests/ui/consts/issue-17718.rs index b6c676886c10d..7fdf2643ccabb 100644 --- a/tests/ui/consts/issue-17718.rs +++ b/tests/ui/consts/issue-17718.rs @@ -1,7 +1,9 @@ //@ run-pass -#![allow(dead_code)] //@ aux-build:issue-17718-aux.rs +#![allow(dead_code)] +#![allow(interior_mutable_const_item_mutations)] + extern crate issue_17718_aux as other; use std::sync::atomic::{AtomicUsize, Ordering};