diff --git a/compiler/rustc_codegen_cranelift/patches/0027-stdlib-128bit-atomic-operations.patch b/compiler/rustc_codegen_cranelift/patches/0027-stdlib-128bit-atomic-operations.patch index d7e3b11127c42..8247542f66768 100644 --- a/compiler/rustc_codegen_cranelift/patches/0027-stdlib-128bit-atomic-operations.patch +++ b/compiler/rustc_codegen_cranelift/patches/0027-stdlib-128bit-atomic-operations.patch @@ -37,7 +37,7 @@ diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs index bf2b6d59f88..d5ccce03bbf 100644 --- a/library/core/src/sync/atomic.rs +++ b/library/core/src/sync/atomic.rs -@@ -3585,44 +3585,6 @@ pub const fn as_ptr(&self) -> *mut $int_type { +@@ -3585,46 +3585,6 @@ pub const fn as_ptr(&self) -> *mut $int_type { 8, u64 AtomicU64 } @@ -54,6 +54,7 @@ index bf2b6d59f88..d5ccce03bbf 100644 - rustc_const_unstable(feature = "integer_atomics", issue = "99069"), - rustc_const_unstable(feature = "integer_atomics", issue = "99069"), - rustc_diagnostic_item = "AtomicI128", +- cfg_attr(not(bootstrap), rustc_significant_interior_mutable_type), - "i128", - "#![feature(integer_atomics)]\n\n", - atomic_min, atomic_max, @@ -73,6 +74,7 @@ index bf2b6d59f88..d5ccce03bbf 100644 - rustc_const_unstable(feature = "integer_atomics", issue = "99069"), - rustc_const_unstable(feature = "integer_atomics", issue = "99069"), - rustc_diagnostic_item = "AtomicU128", +- cfg_attr(not(bootstrap), rustc_significant_interior_mutable_type), - "u128", - "#![feature(integer_atomics)]\n\n", - atomic_umin, atomic_umax, diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index 40857e0066ee5..2cb4880027ede 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -896,6 +896,11 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ EncodeCrossCrate::Yes, "#[rustc_never_returns_null_ptr] is used to mark functions returning non-null pointers." ), + rustc_attr!( + rustc_significant_interior_mutable_type, Normal, template!(Word), ErrorFollowing, + EncodeCrossCrate::Yes, + "#[rustc_significant_interior_mutable_type] is used to mark type that are significant interior mutable types." + ), rustc_attr!( rustc_coherence_is_core, AttributeType::CrateLevel, template!(Word), ErrorFollowing, EncodeCrossCrate::No, "#![rustc_coherence_is_core] allows inherent methods on builtin types, only intended to be used in `core`." diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl index d51865810b9a8..acb8783b3433f 100644 --- a/compiler/rustc_lint/messages.ftl +++ b/compiler/rustc_lint/messages.ftl @@ -426,6 +426,14 @@ lint_incomplete_include = lint_inner_macro_attribute_unstable = inner macro attributes are unstable +lint_interior_mutable_consts = interior mutability in `const` item have no effect to the `const` item itself + .label = `{$ty_name}` is an interior mutable type + .temporary = each usage of a `const` item creates a new temporary + .never_original = only the temporaries and never the original `const` item `{$const_name}` will be modified + .suggestion_inline_const = for use as an initializer, consider using an inline-const `const {"{"} /* ... */ {"}"}` at the usage site instead + .suggestion_static = for a shared instance of `{$const_name}`, consider using a `static` item instead + .suggestion_allow = alternatively consider allowing the lint + 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/lints.rs b/compiler/rustc_lint/src/lints.rs index 0058630957291..d01832e9c43c7 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -1874,6 +1874,55 @@ pub(crate) enum UnpredictableFunctionPointerComparisonsSuggestion<'a, 'tcx> { }, } +#[derive(LintDiagnostic)] +#[diag(lint_interior_mutable_consts)] +#[note(lint_temporary)] +#[note(lint_never_original)] +#[help(lint_suggestion_inline_const)] +pub(crate) struct InteriorMutableConstsDiag { + pub ty_name: Ident, + pub const_name: Ident, + #[label] + pub ty_span: Span, + #[subdiagnostic] + pub sugg_static: InteriorMutableConstsSuggestionStatic, + #[subdiagnostic] + pub sugg_allow: InteriorMutableConstsSuggestionAllow, +} + +#[derive(Subdiagnostic)] +pub(crate) enum InteriorMutableConstsSuggestionStatic { + #[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, +} + +#[derive(Subdiagnostic)] +pub(crate) enum InteriorMutableConstsSuggestionAllow { + #[suggestion( + lint_suggestion_allow, + code = "#[allow(interior_mutable_consts)] ", + style = "verbose", + applicability = "maybe-incorrect" + )] + Spanful { + #[primary_span] + span: Span, + }, + #[help(lint_suggestion_allow)] + Spanless, +} + pub(crate) struct ImproperCTypes<'a> { pub ty: Ty<'a>, pub desc: &'a str, diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs index 7be48a769fe33..b7e2852c44aa2 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -23,10 +23,11 @@ mod improper_ctypes; use crate::lints::{ AmbiguousWidePointerComparisons, AmbiguousWidePointerComparisonsAddrMetadataSuggestion, AmbiguousWidePointerComparisonsAddrSuggestion, AtomicOrderingFence, AtomicOrderingLoad, - AtomicOrderingStore, ImproperCTypes, InvalidAtomicOrderingDiag, InvalidNanComparisons, - InvalidNanComparisonsSuggestion, UnpredictableFunctionPointerComparisons, - UnpredictableFunctionPointerComparisonsSuggestion, UnusedComparisons, UsesPowerAlignment, - VariantSizeDifferencesDiag, + AtomicOrderingStore, ImproperCTypes, InteriorMutableConstsDiag, + InteriorMutableConstsSuggestionAllow, InteriorMutableConstsSuggestionStatic, + InvalidAtomicOrderingDiag, InvalidNanComparisons, InvalidNanComparisonsSuggestion, + UnpredictableFunctionPointerComparisons, UnpredictableFunctionPointerComparisonsSuggestion, + UnusedComparisons, UsesPowerAlignment, VariantSizeDifferencesDiag, }; use crate::{LateContext, LateLintPass, LintContext, fluent_generated as fluent}; @@ -198,6 +199,47 @@ declare_lint! { "detects unpredictable function pointer comparisons" } +declare_lint! { + /// The `interior_mutable_consts` lint detects instance where + /// const-items have a interior mutable type, which silently does nothing. + /// + /// ### Example + /// + /// ```rust + /// use std::sync::Once; + /// + /// // SAFETY: should only be call once + /// unsafe extern "C" fn ffi_init() { /* ... */ } + /// + /// const A: Once = Once::new(); // using `B` will always creates temporaries and + /// // never modify it-self on use, should be a + /// // static-item instead + /// + /// fn init() { + /// A.call_once(|| unsafe { + /// ffi_init(); // unsound, as the `call_once` is on a temporary + /// // and not on a shared variable + /// }) + /// } + /// ``` + /// + /// {{produces}} + /// + /// ### Explanation + /// + /// Using a const-item with 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 and may be extended in the future. + INTERIOR_MUTABLE_CONSTS, + Warn, + "detects const items with interior mutable type", +} + #[derive(Copy, Clone, Default)] pub(crate) struct TypeLimits { /// Id of the last visited negated expression @@ -211,7 +253,8 @@ impl_lint_pass!(TypeLimits => [ OVERFLOWING_LITERALS, INVALID_NAN_COMPARISONS, AMBIGUOUS_WIDE_POINTER_COMPARISONS, - UNPREDICTABLE_FUNCTION_POINTER_COMPARISONS + UNPREDICTABLE_FUNCTION_POINTER_COMPARISONS, + INTERIOR_MUTABLE_CONSTS, ]); impl TypeLimits { @@ -687,6 +730,48 @@ impl<'tcx> LateLintPass<'tcx> for TypeLimits { }) } } + + fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'tcx>) { + if let hir::ItemKind::Const(ty, _generics, _body_id) = item.kind + && let hir::TyKind::Path(ref qpath) = ty.kind + && let Some(def_id) = cx.qpath_res(qpath, ty.hir_id).opt_def_id() + && cx.tcx.has_attr(def_id, sym::rustc_significant_interior_mutable_type) + && let Some(ty_name) = cx.tcx.opt_item_ident(def_id) + { + let (sugg_static, sugg_allow) = if let Some(vis_span) = + item.vis_span.find_ancestor_inside(item.span) + && item.span.can_be_used_for_suggestions() + && vis_span.can_be_used_for_suggestions() + { + ( + InteriorMutableConstsSuggestionStatic::Spanful { + const_: item.vis_span.between(item.ident.span), + before: if !vis_span.is_empty() { " " } else { "" }, + }, + InteriorMutableConstsSuggestionAllow::Spanful { + span: item.span.shrink_to_lo(), + }, + ) + } else { + ( + InteriorMutableConstsSuggestionStatic::Spanless, + InteriorMutableConstsSuggestionAllow::Spanless, + ) + }; + + cx.emit_span_lint( + INTERIOR_MUTABLE_CONSTS, + item.span, + InteriorMutableConstsDiag { + ty_name, + ty_span: ty.span, + const_name: item.ident, + sugg_static, + sugg_allow, + }, + ); + } + } } declare_lint! { diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index ece5a53aaa9c4..6c67d6a02c301 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -179,6 +179,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> { [sym::rustc_as_ptr, ..] => { self.check_applied_to_fn_or_method(hir_id, attr, span, target) } + [sym::rustc_significant_interior_mutable_type, ..] => { + self.check_rustc_significant_interior_mutable_type(attr, span, target) + } [sym::rustc_never_returns_null_ptr, ..] => { self.check_applied_to_fn_or_method(hir_id, attr, span, target) } @@ -1766,6 +1769,24 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } } + /// Checks if `#[rustc_significant_interior_mutable_type]` is applied to a struct, enum, union, or trait. + fn check_rustc_significant_interior_mutable_type( + &self, + attr: &Attribute, + span: Span, + target: Target, + ) { + match target { + Target::Struct | Target::Enum | Target::Union => {} + _ => { + self.dcx().emit_err(errors::AttrShouldBeAppliedToStructEnum { + attr_span: attr.span(), + span, + }); + } + } + } + /// Checks that the `#[rustc_lint_opt_ty]` attribute is only applied to a struct. fn check_rustc_lint_opt_ty(&self, attr: &Attribute, span: Span, target: Target) { match target { diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index b8359c27e538f..865435518504c 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -108,6 +108,15 @@ pub(crate) struct AttrShouldBeAppliedToFn { pub on_crate: bool, } +#[derive(Diagnostic)] +#[diag(passes_should_be_applied_to_struct_enum)] +pub(crate) struct AttrShouldBeAppliedToStructEnum { + #[primary_span] + pub attr_span: Span, + #[label] + pub span: Span, +} + #[derive(Diagnostic)] #[diag(passes_should_be_applied_to_fn, code = E0739)] pub(crate) struct TrackedCallerWrongLocation { diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 8a8bec35d8194..957b68626054a 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1822,6 +1822,7 @@ symbols! { rustc_regions, rustc_reservation_impl, rustc_serialize, + rustc_significant_interior_mutable_type, rustc_skip_during_method_dispatch, rustc_specialization_trait, rustc_std_internal_symbol, diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs index 1a320b316a41a..06947dda29cac 100644 --- a/library/core/src/cell.rs +++ b/library/core/src/cell.rs @@ -308,6 +308,7 @@ pub use once::OnceCell; #[stable(feature = "rust1", since = "1.0.0")] #[repr(transparent)] #[rustc_pub_transparent] +#[cfg_attr(not(bootstrap), rustc_significant_interior_mutable_type)] pub struct Cell { value: UnsafeCell, } @@ -727,6 +728,7 @@ impl Cell<[T; N]> { /// See the [module-level documentation](self) for more. #[rustc_diagnostic_item = "RefCell"] #[stable(feature = "rust1", since = "1.0.0")] +#[cfg_attr(not(bootstrap), rustc_significant_interior_mutable_type)] pub struct RefCell { borrow: Cell, // Stores the location of the earliest currently active borrow. @@ -2072,6 +2074,7 @@ impl fmt::Display for RefMut<'_, T> { #[stable(feature = "rust1", since = "1.0.0")] #[repr(transparent)] #[rustc_pub_transparent] +#[cfg_attr(not(bootstrap), rustc_significant_interior_mutable_type)] pub struct UnsafeCell { value: T, } diff --git a/library/core/src/cell/lazy.rs b/library/core/src/cell/lazy.rs index 84cbbc71f40ae..0f9fda33cdd13 100644 --- a/library/core/src/cell/lazy.rs +++ b/library/core/src/cell/lazy.rs @@ -35,6 +35,7 @@ enum State { /// // 92 /// ``` #[stable(feature = "lazy_cell", since = "1.80.0")] +#[cfg_attr(not(bootstrap), rustc_significant_interior_mutable_type)] pub struct LazyCell T> { state: UnsafeCell>, } diff --git a/library/core/src/cell/once.rs b/library/core/src/cell/once.rs index c6c96571d33c9..b8ba33e8d6120 100644 --- a/library/core/src/cell/once.rs +++ b/library/core/src/cell/once.rs @@ -32,6 +32,7 @@ use crate::{fmt, mem}; /// assert!(cell.get().is_some()); /// ``` #[stable(feature = "once_cell", since = "1.70.0")] +#[cfg_attr(not(bootstrap), rustc_significant_interior_mutable_type)] pub struct OnceCell { // Invariant: written to at most once. inner: UnsafeCell>, diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs index 88bee62203101..bc63ed0dcd78e 100644 --- a/library/core/src/sync/atomic.rs +++ b/library/core/src/sync/atomic.rs @@ -267,6 +267,7 @@ const EMULATE_ATOMIC_BOOL: bool = #[cfg(target_has_atomic_load_store = "8")] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_diagnostic_item = "AtomicBool"] +#[cfg_attr(not(bootstrap), rustc_significant_interior_mutable_type)] #[repr(C, align(1))] pub struct AtomicBool { v: UnsafeCell, @@ -296,6 +297,7 @@ unsafe impl Sync for AtomicBool {} #[cfg(target_has_atomic_load_store = "ptr")] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_diagnostic_item = "AtomicPtr"] +#[cfg_attr(not(bootstrap), rustc_significant_interior_mutable_type)] #[cfg_attr(target_pointer_width = "16", repr(C, align(2)))] #[cfg_attr(target_pointer_width = "32", repr(C, align(4)))] #[cfg_attr(target_pointer_width = "64", repr(C, align(8)))] @@ -408,6 +410,7 @@ pub enum Ordering { note = "the `new` function is now preferred", suggestion = "AtomicBool::new(false)" )] +#[cfg_attr(not(bootstrap), expect(interior_mutable_consts))] pub const ATOMIC_BOOL_INIT: AtomicBool = AtomicBool::new(false); #[cfg(target_has_atomic_load_store = "8")] @@ -2388,6 +2391,7 @@ macro_rules! atomic_int { $const_stable_new:meta, $const_stable_into_inner:meta, $diagnostic_item:meta, + $interior_mut_item:meta, $s_int_type:literal, $extra_feature:expr, $min_fn:ident, $max_fn:ident, @@ -2425,6 +2429,7 @@ macro_rules! atomic_int { /// [module-level documentation]: crate::sync::atomic #[$stable] #[$diagnostic_item] + #[$interior_mut_item] #[repr(C, align($align))] pub struct $atomic_type { v: UnsafeCell<$int_type>, @@ -3447,6 +3452,7 @@ atomic_int! { rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"), rustc_const_stable(feature = "const_atomic_into_inner", since = "1.79.0"), rustc_diagnostic_item = "AtomicI8", + cfg_attr(not(bootstrap), rustc_significant_interior_mutable_type), "i8", "", atomic_min, atomic_max, @@ -3466,6 +3472,7 @@ atomic_int! { rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"), rustc_const_stable(feature = "const_atomic_into_inner", since = "1.79.0"), rustc_diagnostic_item = "AtomicU8", + cfg_attr(not(bootstrap), rustc_significant_interior_mutable_type), "u8", "", atomic_umin, atomic_umax, @@ -3485,6 +3492,7 @@ atomic_int! { rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"), rustc_const_stable(feature = "const_atomic_into_inner", since = "1.79.0"), rustc_diagnostic_item = "AtomicI16", + cfg_attr(not(bootstrap), rustc_significant_interior_mutable_type), "i16", "", atomic_min, atomic_max, @@ -3504,6 +3512,7 @@ atomic_int! { rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"), rustc_const_stable(feature = "const_atomic_into_inner", since = "1.79.0"), rustc_diagnostic_item = "AtomicU16", + cfg_attr(not(bootstrap), rustc_significant_interior_mutable_type), "u16", "", atomic_umin, atomic_umax, @@ -3523,6 +3532,7 @@ atomic_int! { rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"), rustc_const_stable(feature = "const_atomic_into_inner", since = "1.79.0"), rustc_diagnostic_item = "AtomicI32", + cfg_attr(not(bootstrap), rustc_significant_interior_mutable_type), "i32", "", atomic_min, atomic_max, @@ -3542,6 +3552,7 @@ atomic_int! { rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"), rustc_const_stable(feature = "const_atomic_into_inner", since = "1.79.0"), rustc_diagnostic_item = "AtomicU32", + cfg_attr(not(bootstrap), rustc_significant_interior_mutable_type), "u32", "", atomic_umin, atomic_umax, @@ -3561,6 +3572,7 @@ atomic_int! { rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"), rustc_const_stable(feature = "const_atomic_into_inner", since = "1.79.0"), rustc_diagnostic_item = "AtomicI64", + cfg_attr(not(bootstrap), rustc_significant_interior_mutable_type), "i64", "", atomic_min, atomic_max, @@ -3580,6 +3592,7 @@ atomic_int! { rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"), rustc_const_stable(feature = "const_atomic_into_inner", since = "1.79.0"), rustc_diagnostic_item = "AtomicU64", + cfg_attr(not(bootstrap), rustc_significant_interior_mutable_type), "u64", "", atomic_umin, atomic_umax, @@ -3599,6 +3612,7 @@ atomic_int! { rustc_const_unstable(feature = "integer_atomics", issue = "99069"), rustc_const_unstable(feature = "integer_atomics", issue = "99069"), rustc_diagnostic_item = "AtomicI128", + cfg_attr(not(bootstrap), rustc_significant_interior_mutable_type), "i128", "#![feature(integer_atomics)]\n\n", atomic_min, atomic_max, @@ -3618,6 +3632,7 @@ atomic_int! { rustc_const_unstable(feature = "integer_atomics", issue = "99069"), rustc_const_unstable(feature = "integer_atomics", issue = "99069"), rustc_diagnostic_item = "AtomicU128", + cfg_attr(not(bootstrap), rustc_significant_interior_mutable_type), "u128", "#![feature(integer_atomics)]\n\n", atomic_umin, atomic_umax, @@ -3641,6 +3656,7 @@ macro_rules! atomic_int_ptr_sized { rustc_const_stable(feature = "const_ptr_sized_atomics", since = "1.24.0"), rustc_const_stable(feature = "const_atomic_into_inner", since = "1.79.0"), rustc_diagnostic_item = "AtomicIsize", + cfg_attr(not(bootstrap), rustc_significant_interior_mutable_type), "isize", "", atomic_min, atomic_max, @@ -3660,6 +3676,7 @@ macro_rules! atomic_int_ptr_sized { rustc_const_stable(feature = "const_ptr_sized_atomics", since = "1.24.0"), rustc_const_stable(feature = "const_atomic_into_inner", since = "1.79.0"), rustc_diagnostic_item = "AtomicUsize", + cfg_attr(not(bootstrap), rustc_significant_interior_mutable_type), "usize", "", atomic_umin, atomic_umax, @@ -3675,6 +3692,7 @@ macro_rules! atomic_int_ptr_sized { note = "the `new` function is now preferred", suggestion = "AtomicIsize::new(0)", )] + #[cfg_attr(not(bootstrap), expect(interior_mutable_consts))] pub const ATOMIC_ISIZE_INIT: AtomicIsize = AtomicIsize::new(0); /// An [`AtomicUsize`] initialized to `0`. @@ -3685,6 +3703,7 @@ macro_rules! atomic_int_ptr_sized { note = "the `new` function is now preferred", suggestion = "AtomicUsize::new(0)", )] + #[cfg_attr(not(bootstrap), expect(interior_mutable_consts))] pub const ATOMIC_USIZE_INIT: AtomicUsize = AtomicUsize::new(0); )* }; } diff --git a/library/coretests/tests/cell.rs b/library/coretests/tests/cell.rs index d6a401c2b4d98..fc4db8df10d9e 100644 --- a/library/coretests/tests/cell.rs +++ b/library/coretests/tests/cell.rs @@ -456,6 +456,7 @@ fn refcell_format() { } #[allow(dead_code)] +#[cfg_attr(not(bootstrap), allow(interior_mutable_consts))] fn const_cells() { const UNSAFE_CELL: UnsafeCell = UnsafeCell::new(3); const _: i32 = UNSAFE_CELL.into_inner(); diff --git a/library/std/src/collections/hash/map.rs b/library/std/src/collections/hash/map.rs index 2487f5a2a503f..f7aa35fd428eb 100644 --- a/library/std/src/collections/hash/map.rs +++ b/library/std/src/collections/hash/map.rs @@ -230,6 +230,7 @@ use crate::ops::Index; /// Mutex::new(HashMap::with_hasher(BuildHasherDefault::new())); /// /// // HashMaps using LazyLock to retain random seeding +/// # #[cfg_attr(not(bootstrap), allow(interior_mutable_consts))] /// const RANDOM_EMPTY_MAP: LazyLock>> = /// LazyLock::new(HashMap::new); /// static RANDOM_MAP: LazyLock>>> = diff --git a/library/std/src/sync/barrier.rs b/library/std/src/sync/barrier.rs index 067ff66d9af73..93145d7ec9636 100644 --- a/library/std/src/sync/barrier.rs +++ b/library/std/src/sync/barrier.rs @@ -26,6 +26,7 @@ use crate::sync::{Condvar, Mutex}; /// }); /// ``` #[stable(feature = "rust1", since = "1.0.0")] +#[cfg_attr(not(bootstrap), rustc_significant_interior_mutable_type)] pub struct Barrier { lock: Mutex, cvar: Condvar, diff --git a/library/std/src/sync/lazy_lock.rs b/library/std/src/sync/lazy_lock.rs index 78cf8841efefb..ffc6895ba5e56 100644 --- a/library/std/src/sync/lazy_lock.rs +++ b/library/std/src/sync/lazy_lock.rs @@ -62,6 +62,7 @@ union Data { /// } /// ``` #[stable(feature = "lazy_cell", since = "1.80.0")] +#[cfg_attr(not(bootstrap), rustc_significant_interior_mutable_type)] pub struct LazyLock T> { // FIXME(nonpoison_once): if possible, switch to nonpoison version once it is available once: Once, diff --git a/library/std/src/sync/once_lock.rs b/library/std/src/sync/once_lock.rs index ffb90b1469584..76231d98b58ae 100644 --- a/library/std/src/sync/once_lock.rs +++ b/library/std/src/sync/once_lock.rs @@ -103,6 +103,7 @@ use crate::sync::Once; /// /// ``` #[stable(feature = "once_cell", since = "1.70.0")] +#[cfg_attr(not(bootstrap), rustc_significant_interior_mutable_type)] pub struct OnceLock { // FIXME(nonpoison_once): switch to nonpoison version once it is available once: Once, diff --git a/library/std/src/sync/poison/condvar.rs b/library/std/src/sync/poison/condvar.rs index 7f0f3f652bcb7..5241d174f2fb1 100644 --- a/library/std/src/sync/poison/condvar.rs +++ b/library/std/src/sync/poison/condvar.rs @@ -106,6 +106,7 @@ impl WaitTimeoutResult { /// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] +#[cfg_attr(not(bootstrap), rustc_significant_interior_mutable_type)] pub struct Condvar { inner: sys::Condvar, } diff --git a/library/std/src/sync/poison/mutex.rs b/library/std/src/sync/poison/mutex.rs index 9362c764173a8..90439df22a386 100644 --- a/library/std/src/sync/poison/mutex.rs +++ b/library/std/src/sync/poison/mutex.rs @@ -172,6 +172,7 @@ use crate::sys::sync as sys; /// #[stable(feature = "rust1", since = "1.0.0")] #[cfg_attr(not(test), rustc_diagnostic_item = "Mutex")] +#[cfg_attr(not(bootstrap), rustc_significant_interior_mutable_type)] pub struct Mutex { inner: sys::Mutex, poison: poison::Flag, diff --git a/library/std/src/sync/poison/once.rs b/library/std/src/sync/poison/once.rs index 103e519540795..a158902a7e82c 100644 --- a/library/std/src/sync/poison/once.rs +++ b/library/std/src/sync/poison/once.rs @@ -32,6 +32,7 @@ use crate::sys::sync as sys; /// [`OnceLock`]: crate::sync::OnceLock /// [`LazyLock`]: crate::sync::LazyLock #[stable(feature = "rust1", since = "1.0.0")] +#[cfg_attr(not(bootstrap), rustc_significant_interior_mutable_type)] pub struct Once { inner: sys::Once, } @@ -70,6 +71,7 @@ pub(crate) enum ExclusiveState { note = "the `Once::new()` function is now preferred", suggestion = "Once::new()" )] +#[cfg_attr(not(bootstrap), expect(interior_mutable_consts))] pub const ONCE_INIT: Once = Once::new(); impl Once { diff --git a/library/std/src/sync/poison/rwlock.rs b/library/std/src/sync/poison/rwlock.rs index f9d9321f5f2d8..777d7630673a1 100644 --- a/library/std/src/sync/poison/rwlock.rs +++ b/library/std/src/sync/poison/rwlock.rs @@ -77,6 +77,7 @@ use crate::sys::sync as sys; /// [`Mutex`]: super::Mutex #[stable(feature = "rust1", since = "1.0.0")] #[cfg_attr(not(test), rustc_diagnostic_item = "RwLock")] +#[cfg_attr(not(bootstrap), rustc_significant_interior_mutable_type)] pub struct RwLock { inner: sys::RwLock, poison: poison::Flag, diff --git a/library/std/src/sync/reentrant_lock.rs b/library/std/src/sync/reentrant_lock.rs index e009eb410efc0..1b31c7c53f5ac 100644 --- a/library/std/src/sync/reentrant_lock.rs +++ b/library/std/src/sync/reentrant_lock.rs @@ -80,6 +80,7 @@ use crate::thread::{ThreadId, current_id}; // we don't need to further synchronize the TID accesses, so they can be regular 64-bit // non-atomic accesses. #[unstable(feature = "reentrant_lock", issue = "121440")] +#[cfg_attr(not(bootstrap), rustc_significant_interior_mutable_type)] pub struct ReentrantLock { mutex: sys::Mutex, owner: Tid, diff --git a/library/std/src/sys/thread_local/native/mod.rs b/library/std/src/sys/thread_local/native/mod.rs index a5dffe3c45883..0b23ebc3529e6 100644 --- a/library/std/src/sys/thread_local/native/mod.rs +++ b/library/std/src/sys/thread_local/native/mod.rs @@ -55,6 +55,7 @@ pub macro thread_local_inner { // Used to generate the `LocalKey` value for const-initialized thread locals. (@key $t:ty, const $init:expr) => {{ + #[allow(unknown_lints, interior_mutable_consts)] // cfg(bootstrap) for unknown_lints const __INIT: $t = $init; unsafe { diff --git a/src/tools/clippy/tests/ui/borrow_interior_mutable_const/others.rs b/src/tools/clippy/tests/ui/borrow_interior_mutable_const/others.rs index fa729b62d7f51..e253f9561c622 100644 --- a/src/tools/clippy/tests/ui/borrow_interior_mutable_const/others.rs +++ b/src/tools/clippy/tests/ui/borrow_interior_mutable_const/others.rs @@ -1,6 +1,6 @@ #![deny(clippy::borrow_interior_mutable_const)] #![allow(clippy::declare_interior_mutable_const, clippy::needless_borrow)] -#![allow(const_item_mutation)] +#![allow(const_item_mutation, interior_mutable_consts)] use std::borrow::Cow; use std::cell::{Cell, UnsafeCell}; diff --git a/src/tools/clippy/tests/ui/declare_interior_mutable_const/others.rs b/src/tools/clippy/tests/ui/declare_interior_mutable_const/others.rs index 7ce04a3f2c340..5d3c25eefcdf1 100644 --- a/src/tools/clippy/tests/ui/declare_interior_mutable_const/others.rs +++ b/src/tools/clippy/tests/ui/declare_interior_mutable_const/others.rs @@ -1,5 +1,5 @@ #![warn(clippy::declare_interior_mutable_const)] - +#![allow(interior_mutable_consts)] use std::borrow::Cow; use std::cell::Cell; use std::fmt::Display; diff --git a/tests/ui/consts/issue-17718.rs b/tests/ui/consts/issue-17718.rs index b6c676886c10d..38f5420324569 100644 --- a/tests/ui/consts/issue-17718.rs +++ b/tests/ui/consts/issue-17718.rs @@ -1,5 +1,6 @@ //@ run-pass #![allow(dead_code)] +#![allow(interior_mutable_consts)] //@ aux-build:issue-17718-aux.rs extern crate issue_17718_aux as other; diff --git a/tests/ui/lint/interior-mutable-types-in-consts-not-sync.rs b/tests/ui/lint/interior-mutable-types-in-consts-not-sync.rs new file mode 100644 index 0000000000000..4a7b0bb5a5929 --- /dev/null +++ b/tests/ui/lint/interior-mutable-types-in-consts-not-sync.rs @@ -0,0 +1,16 @@ +//@ check-pass + +use std::cell::{Cell, RefCell, UnsafeCell, LazyCell, OnceCell}; + +const A: Cell = Cell::new(0); +//~^ WARN interior mutability in `const` item +const B: RefCell = RefCell::new(0); +//~^ WARN interior mutability in `const` item +const C: UnsafeCell = UnsafeCell::new(0); +//~^ WARN interior mutability in `const` item +const D: LazyCell = LazyCell::new(|| 0); +//~^ WARN interior mutability in `const` item +const E: OnceCell = OnceCell::new(); +//~^ WARN interior mutability in `const` item + +fn main() {} diff --git a/tests/ui/lint/interior-mutable-types-in-consts-not-sync.stderr b/tests/ui/lint/interior-mutable-types-in-consts-not-sync.stderr new file mode 100644 index 0000000000000..ce5ef55187ab8 --- /dev/null +++ b/tests/ui/lint/interior-mutable-types-in-consts-not-sync.stderr @@ -0,0 +1,108 @@ +warning: interior mutability in `const` item have no effect to the `const` item itself + --> $DIR/interior-mutable-types-in-consts-not-sync.rs:5:1 + | +LL | const A: Cell = Cell::new(0); + | ^^^^^^^^^---------^^^^^^^^^^^^^^^^ + | | + | `Cell` is an interior mutable type + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const` item `A` will be modified + = help: for use as an initializer, consider using an inline-const `const { /* ... */ }` at the usage site instead + = note: `#[warn(interior_mutable_consts)]` on by default +help: for a shared instance of `A`, consider using a `static` item instead + | +LL - const A: Cell = Cell::new(0); +LL + static A: Cell = Cell::new(0); + | +help: alternatively consider allowing the lint + | +LL | #[allow(interior_mutable_consts)] const A: Cell = Cell::new(0); + | +++++++++++++++++++++++++++++++++ + +warning: interior mutability in `const` item have no effect to the `const` item itself + --> $DIR/interior-mutable-types-in-consts-not-sync.rs:7:1 + | +LL | const B: RefCell = RefCell::new(0); + | ^^^^^^^^^------------^^^^^^^^^^^^^^^^^^^ + | | + | `RefCell` is an interior mutable type + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const` item `B` will be modified + = help: for use as an initializer, consider using an inline-const `const { /* ... */ }` at the usage site instead +help: for a shared instance of `B`, consider using a `static` item instead + | +LL - const B: RefCell = RefCell::new(0); +LL + static B: RefCell = RefCell::new(0); + | +help: alternatively consider allowing the lint + | +LL | #[allow(interior_mutable_consts)] const B: RefCell = RefCell::new(0); + | +++++++++++++++++++++++++++++++++ + +warning: interior mutability in `const` item have no effect to the `const` item itself + --> $DIR/interior-mutable-types-in-consts-not-sync.rs:9:1 + | +LL | const C: UnsafeCell = UnsafeCell::new(0); + | ^^^^^^^^^---------------^^^^^^^^^^^^^^^^^^^^^^ + | | + | `UnsafeCell` is an interior mutable type + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const` item `C` will be modified + = help: for use as an initializer, consider using an inline-const `const { /* ... */ }` at the usage site instead +help: for a shared instance of `C`, consider using a `static` item instead + | +LL - const C: UnsafeCell = UnsafeCell::new(0); +LL + static C: UnsafeCell = UnsafeCell::new(0); + | +help: alternatively consider allowing the lint + | +LL | #[allow(interior_mutable_consts)] const C: UnsafeCell = UnsafeCell::new(0); + | +++++++++++++++++++++++++++++++++ + +warning: interior mutability in `const` item have no effect to the `const` item itself + --> $DIR/interior-mutable-types-in-consts-not-sync.rs:11:1 + | +LL | const D: LazyCell = LazyCell::new(|| 0); + | ^^^^^^^^^-------------^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `LazyCell` is an interior mutable type + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const` item `D` will be modified + = help: for use as an initializer, consider using an inline-const `const { /* ... */ }` at the usage site instead +help: for a shared instance of `D`, consider using a `static` item instead + | +LL - const D: LazyCell = LazyCell::new(|| 0); +LL + static D: LazyCell = LazyCell::new(|| 0); + | +help: alternatively consider allowing the lint + | +LL | #[allow(interior_mutable_consts)] const D: LazyCell = LazyCell::new(|| 0); + | +++++++++++++++++++++++++++++++++ + +warning: interior mutability in `const` item have no effect to the `const` item itself + --> $DIR/interior-mutable-types-in-consts-not-sync.rs:13:1 + | +LL | const E: OnceCell = OnceCell::new(); + | ^^^^^^^^^-------------^^^^^^^^^^^^^^^^^^^ + | | + | `OnceCell` is an interior mutable type + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const` item `E` will be modified + = help: for use as an initializer, consider using an inline-const `const { /* ... */ }` at the usage site instead +help: for a shared instance of `E`, consider using a `static` item instead + | +LL - const E: OnceCell = OnceCell::new(); +LL + static E: OnceCell = OnceCell::new(); + | +help: alternatively consider allowing the lint + | +LL | #[allow(interior_mutable_consts)] const E: OnceCell = OnceCell::new(); + | +++++++++++++++++++++++++++++++++ + +warning: 5 warnings emitted + diff --git a/tests/ui/lint/interior-mutable-types-in-consts.fixed b/tests/ui/lint/interior-mutable-types-in-consts.fixed new file mode 100644 index 0000000000000..65b921f627174 --- /dev/null +++ b/tests/ui/lint/interior-mutable-types-in-consts.fixed @@ -0,0 +1,46 @@ +//@ check-pass +//@ run-rustfix + +#![allow(dead_code)] // for rustfix +#![feature(reentrant_lock)] + +use std::sync::{Once, Barrier, Condvar, LazyLock, Mutex, OnceLock, ReentrantLock, RwLock}; +use std::sync::atomic::{AtomicBool, AtomicPtr, AtomicI32, AtomicU32}; + +#[allow(interior_mutable_consts)] static A: Once = Once::new(); +//~^ WARN interior mutability in `const` item +#[allow(interior_mutable_consts)] static B: Barrier = Barrier::new(0); +//~^ WARN interior mutability in `const` item +#[allow(interior_mutable_consts)] static C: Condvar = Condvar::new(); +//~^ WARN interior mutability in `const` item +#[allow(interior_mutable_consts)] static D: LazyLock = LazyLock::new(|| 0); +//~^ WARN interior mutability in `const` item +#[allow(interior_mutable_consts)] static E: Mutex = Mutex::new(0); +//~^ WARN interior mutability in `const` item +#[allow(interior_mutable_consts)] static F: OnceLock = OnceLock::new(); +//~^ WARN interior mutability in `const` item +#[allow(interior_mutable_consts)] static G: ReentrantLock = ReentrantLock::new(0); +//~^ WARN interior mutability in `const` item +#[allow(interior_mutable_consts)] static H: RwLock = RwLock::new(0); +//~^ WARN interior mutability in `const` item +#[allow(interior_mutable_consts)] static I: AtomicBool = AtomicBool::new(false); +//~^ WARN interior mutability in `const` item +#[allow(interior_mutable_consts)] static J: AtomicPtr = AtomicPtr::new(std::ptr::null_mut()); +//~^ WARN interior mutability in `const` item +#[allow(interior_mutable_consts)] static K: AtomicI32 = AtomicI32::new(0); +//~^ WARN interior mutability in `const` item +#[allow(interior_mutable_consts)] static L: AtomicU32 = AtomicU32::new(0); +//~^ WARN interior mutability in `const` item + +#[allow(interior_mutable_consts)] pub(crate) static X: Once = Once::new(); +//~^ WARN interior mutability in `const` item + +fn main() { + #[allow(interior_mutable_consts)] static Z: Once = Once::new(); + //~^ WARN interior mutability in `const` item +} + +struct S; +impl S { + const Z: Once = Once::new(); // not a const-item +} diff --git a/tests/ui/lint/interior-mutable-types-in-consts.rs b/tests/ui/lint/interior-mutable-types-in-consts.rs new file mode 100644 index 0000000000000..06461482aaddc --- /dev/null +++ b/tests/ui/lint/interior-mutable-types-in-consts.rs @@ -0,0 +1,46 @@ +//@ check-pass +//@ run-rustfix + +#![allow(dead_code)] // for rustfix +#![feature(reentrant_lock)] + +use std::sync::{Once, Barrier, Condvar, LazyLock, Mutex, OnceLock, ReentrantLock, RwLock}; +use std::sync::atomic::{AtomicBool, AtomicPtr, AtomicI32, AtomicU32}; + +const A: Once = Once::new(); +//~^ WARN interior mutability in `const` item +const B: Barrier = Barrier::new(0); +//~^ WARN interior mutability in `const` item +const C: Condvar = Condvar::new(); +//~^ WARN interior mutability in `const` item +const D: LazyLock = LazyLock::new(|| 0); +//~^ WARN interior mutability in `const` item +const E: Mutex = Mutex::new(0); +//~^ WARN interior mutability in `const` item +const F: OnceLock = OnceLock::new(); +//~^ WARN interior mutability in `const` item +const G: ReentrantLock = ReentrantLock::new(0); +//~^ WARN interior mutability in `const` item +const H: RwLock = RwLock::new(0); +//~^ WARN interior mutability in `const` item +const I: AtomicBool = AtomicBool::new(false); +//~^ WARN interior mutability in `const` item +const J: AtomicPtr = AtomicPtr::new(std::ptr::null_mut()); +//~^ WARN interior mutability in `const` item +const K: AtomicI32 = AtomicI32::new(0); +//~^ WARN interior mutability in `const` item +const L: AtomicU32 = AtomicU32::new(0); +//~^ WARN interior mutability in `const` item + +pub(crate) const X: Once = Once::new(); +//~^ WARN interior mutability in `const` item + +fn main() { + const Z: Once = Once::new(); + //~^ WARN interior mutability in `const` item +} + +struct S; +impl S { + const Z: Once = Once::new(); // not a const-item +} diff --git a/tests/ui/lint/interior-mutable-types-in-consts.stderr b/tests/ui/lint/interior-mutable-types-in-consts.stderr new file mode 100644 index 0000000000000..eea7cffa39e92 --- /dev/null +++ b/tests/ui/lint/interior-mutable-types-in-consts.stderr @@ -0,0 +1,297 @@ +warning: interior mutability in `const` item have no effect to the `const` item itself + --> $DIR/interior-mutable-types-in-consts.rs:10:1 + | +LL | const A: Once = Once::new(); + | ^^^^^^^^^----^^^^^^^^^^^^^^^ + | | + | `Once` is an interior mutable type + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const` item `A` will be modified + = help: for use as an initializer, consider using an inline-const `const { /* ... */ }` at the usage site instead + = note: `#[warn(interior_mutable_consts)]` on by default +help: for a shared instance of `A`, consider using a `static` item instead + | +LL - const A: Once = Once::new(); +LL + static A: Once = Once::new(); + | +help: alternatively consider allowing the lint + | +LL | #[allow(interior_mutable_consts)] const A: Once = Once::new(); + | +++++++++++++++++++++++++++++++++ + +warning: interior mutability in `const` item have no effect to the `const` item itself + --> $DIR/interior-mutable-types-in-consts.rs:12:1 + | +LL | const B: Barrier = Barrier::new(0); + | ^^^^^^^^^-------^^^^^^^^^^^^^^^^^^^ + | | + | `Barrier` is an interior mutable type + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const` item `B` will be modified + = help: for use as an initializer, consider using an inline-const `const { /* ... */ }` at the usage site instead +help: for a shared instance of `B`, consider using a `static` item instead + | +LL - const B: Barrier = Barrier::new(0); +LL + static B: Barrier = Barrier::new(0); + | +help: alternatively consider allowing the lint + | +LL | #[allow(interior_mutable_consts)] const B: Barrier = Barrier::new(0); + | +++++++++++++++++++++++++++++++++ + +warning: interior mutability in `const` item have no effect to the `const` item itself + --> $DIR/interior-mutable-types-in-consts.rs:14:1 + | +LL | const C: Condvar = Condvar::new(); + | ^^^^^^^^^-------^^^^^^^^^^^^^^^^^^ + | | + | `Condvar` is an interior mutable type + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const` item `C` will be modified + = help: for use as an initializer, consider using an inline-const `const { /* ... */ }` at the usage site instead +help: for a shared instance of `C`, consider using a `static` item instead + | +LL - const C: Condvar = Condvar::new(); +LL + static C: Condvar = Condvar::new(); + | +help: alternatively consider allowing the lint + | +LL | #[allow(interior_mutable_consts)] const C: Condvar = Condvar::new(); + | +++++++++++++++++++++++++++++++++ + +warning: interior mutability in `const` item have no effect to the `const` item itself + --> $DIR/interior-mutable-types-in-consts.rs:16:1 + | +LL | const D: LazyLock = LazyLock::new(|| 0); + | ^^^^^^^^^-------------^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `LazyLock` is an interior mutable type + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const` item `D` will be modified + = help: for use as an initializer, consider using an inline-const `const { /* ... */ }` at the usage site instead +help: for a shared instance of `D`, consider using a `static` item instead + | +LL - const D: LazyLock = LazyLock::new(|| 0); +LL + static D: LazyLock = LazyLock::new(|| 0); + | +help: alternatively consider allowing the lint + | +LL | #[allow(interior_mutable_consts)] const D: LazyLock = LazyLock::new(|| 0); + | +++++++++++++++++++++++++++++++++ + +warning: interior mutability in `const` item have no effect to the `const` item itself + --> $DIR/interior-mutable-types-in-consts.rs:18:1 + | +LL | const E: Mutex = Mutex::new(0); + | ^^^^^^^^^----------^^^^^^^^^^^^^^^^^ + | | + | `Mutex` is an interior mutable type + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const` item `E` will be modified + = help: for use as an initializer, consider using an inline-const `const { /* ... */ }` at the usage site instead +help: for a shared instance of `E`, consider using a `static` item instead + | +LL - const E: Mutex = Mutex::new(0); +LL + static E: Mutex = Mutex::new(0); + | +help: alternatively consider allowing the lint + | +LL | #[allow(interior_mutable_consts)] const E: Mutex = Mutex::new(0); + | +++++++++++++++++++++++++++++++++ + +warning: interior mutability in `const` item have no effect to the `const` item itself + --> $DIR/interior-mutable-types-in-consts.rs:20:1 + | +LL | const F: OnceLock = OnceLock::new(); + | ^^^^^^^^^-------------^^^^^^^^^^^^^^^^^^^ + | | + | `OnceLock` is an interior mutable type + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const` item `F` will be modified + = help: for use as an initializer, consider using an inline-const `const { /* ... */ }` at the usage site instead +help: for a shared instance of `F`, consider using a `static` item instead + | +LL - const F: OnceLock = OnceLock::new(); +LL + static F: OnceLock = OnceLock::new(); + | +help: alternatively consider allowing the lint + | +LL | #[allow(interior_mutable_consts)] const F: OnceLock = OnceLock::new(); + | +++++++++++++++++++++++++++++++++ + +warning: interior mutability in `const` item have no effect to the `const` item itself + --> $DIR/interior-mutable-types-in-consts.rs:22:1 + | +LL | const G: ReentrantLock = ReentrantLock::new(0); + | ^^^^^^^^^------------------^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `ReentrantLock` is an interior mutable type + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const` item `G` will be modified + = help: for use as an initializer, consider using an inline-const `const { /* ... */ }` at the usage site instead +help: for a shared instance of `G`, consider using a `static` item instead + | +LL - const G: ReentrantLock = ReentrantLock::new(0); +LL + static G: ReentrantLock = ReentrantLock::new(0); + | +help: alternatively consider allowing the lint + | +LL | #[allow(interior_mutable_consts)] const G: ReentrantLock = ReentrantLock::new(0); + | +++++++++++++++++++++++++++++++++ + +warning: interior mutability in `const` item have no effect to the `const` item itself + --> $DIR/interior-mutable-types-in-consts.rs:24:1 + | +LL | const H: RwLock = RwLock::new(0); + | ^^^^^^^^^-----------^^^^^^^^^^^^^^^^^^ + | | + | `RwLock` is an interior mutable type + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const` item `H` will be modified + = help: for use as an initializer, consider using an inline-const `const { /* ... */ }` at the usage site instead +help: for a shared instance of `H`, consider using a `static` item instead + | +LL - const H: RwLock = RwLock::new(0); +LL + static H: RwLock = RwLock::new(0); + | +help: alternatively consider allowing the lint + | +LL | #[allow(interior_mutable_consts)] const H: RwLock = RwLock::new(0); + | +++++++++++++++++++++++++++++++++ + +warning: interior mutability in `const` item have no effect to the `const` item itself + --> $DIR/interior-mutable-types-in-consts.rs:26:1 + | +LL | const I: AtomicBool = AtomicBool::new(false); + | ^^^^^^^^^----------^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `AtomicBool` is an interior mutable type + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const` item `I` will be modified + = help: for use as an initializer, consider using an inline-const `const { /* ... */ }` at the usage site instead +help: for a shared instance of `I`, consider using a `static` item instead + | +LL - const I: AtomicBool = AtomicBool::new(false); +LL + static I: AtomicBool = AtomicBool::new(false); + | +help: alternatively consider allowing the lint + | +LL | #[allow(interior_mutable_consts)] const I: AtomicBool = AtomicBool::new(false); + | +++++++++++++++++++++++++++++++++ + +warning: interior mutability in `const` item have no effect to the `const` item itself + --> $DIR/interior-mutable-types-in-consts.rs:28:1 + | +LL | const J: AtomicPtr = AtomicPtr::new(std::ptr::null_mut()); + | ^^^^^^^^^--------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `AtomicPtr` is an interior mutable type + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const` item `J` will be modified + = help: for use as an initializer, consider using an inline-const `const { /* ... */ }` at the usage site instead +help: for a shared instance of `J`, consider using a `static` item instead + | +LL - const J: AtomicPtr = AtomicPtr::new(std::ptr::null_mut()); +LL + static J: AtomicPtr = AtomicPtr::new(std::ptr::null_mut()); + | +help: alternatively consider allowing the lint + | +LL | #[allow(interior_mutable_consts)] const J: AtomicPtr = AtomicPtr::new(std::ptr::null_mut()); + | +++++++++++++++++++++++++++++++++ + +warning: interior mutability in `const` item have no effect to the `const` item itself + --> $DIR/interior-mutable-types-in-consts.rs:30:1 + | +LL | const K: AtomicI32 = AtomicI32::new(0); + | ^^^^^^^^^---------^^^^^^^^^^^^^^^^^^^^^ + | | + | `AtomicI32` is an interior mutable type + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const` item `K` will be modified + = help: for use as an initializer, consider using an inline-const `const { /* ... */ }` at the usage site instead +help: for a shared instance of `K`, consider using a `static` item instead + | +LL - const K: AtomicI32 = AtomicI32::new(0); +LL + static K: AtomicI32 = AtomicI32::new(0); + | +help: alternatively consider allowing the lint + | +LL | #[allow(interior_mutable_consts)] const K: AtomicI32 = AtomicI32::new(0); + | +++++++++++++++++++++++++++++++++ + +warning: interior mutability in `const` item have no effect to the `const` item itself + --> $DIR/interior-mutable-types-in-consts.rs:32:1 + | +LL | const L: AtomicU32 = AtomicU32::new(0); + | ^^^^^^^^^---------^^^^^^^^^^^^^^^^^^^^^ + | | + | `AtomicU32` is an interior mutable type + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const` item `L` will be modified + = help: for use as an initializer, consider using an inline-const `const { /* ... */ }` at the usage site instead +help: for a shared instance of `L`, consider using a `static` item instead + | +LL - const L: AtomicU32 = AtomicU32::new(0); +LL + static L: AtomicU32 = AtomicU32::new(0); + | +help: alternatively consider allowing the lint + | +LL | #[allow(interior_mutable_consts)] const L: AtomicU32 = AtomicU32::new(0); + | +++++++++++++++++++++++++++++++++ + +warning: interior mutability in `const` item have no effect to the `const` item itself + --> $DIR/interior-mutable-types-in-consts.rs:35:1 + | +LL | pub(crate) const X: Once = Once::new(); + | ^^^^^^^^^^^^^^^^^^^^----^^^^^^^^^^^^^^^ + | | + | `Once` is an interior mutable type + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const` item `X` will be modified + = help: for use as an initializer, consider using an inline-const `const { /* ... */ }` at the usage site instead +help: for a shared instance of `X`, consider using a `static` item instead + | +LL - pub(crate) const X: Once = Once::new(); +LL + pub(crate) static X: Once = Once::new(); + | +help: alternatively consider allowing the lint + | +LL | #[allow(interior_mutable_consts)] pub(crate) const X: Once = Once::new(); + | +++++++++++++++++++++++++++++++++ + +warning: interior mutability in `const` item have no effect to the `const` item itself + --> $DIR/interior-mutable-types-in-consts.rs:39:5 + | +LL | const Z: Once = Once::new(); + | ^^^^^^^^^----^^^^^^^^^^^^^^^ + | | + | `Once` is an interior mutable type + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const` item `Z` will be modified + = help: for use as an initializer, consider using an inline-const `const { /* ... */ }` at the usage site instead +help: for a shared instance of `Z`, consider using a `static` item instead + | +LL - const Z: Once = Once::new(); +LL + static Z: Once = Once::new(); + | +help: alternatively consider allowing the lint + | +LL | #[allow(interior_mutable_consts)] const Z: Once = Once::new(); + | +++++++++++++++++++++++++++++++++ + +warning: 14 warnings emitted +