+++ /dev/null
-#![warn(clippy::borrow_interior_mutable_const)]
-#![allow(clippy::declare_interior_mutable_const, clippy::ref_in_deref)]
-#![allow(const_item_mutation)]
-
-use std::borrow::Cow;
-use std::cell::{Cell, UnsafeCell};
-use std::fmt::Display;
-use std::sync::atomic::{AtomicUsize, Ordering};
-use std::sync::Once;
-
-const ATOMIC: AtomicUsize = AtomicUsize::new(5);
-const CELL: Cell<usize> = Cell::new(6);
-const ATOMIC_TUPLE: ([AtomicUsize; 1], Vec<AtomicUsize>, u8) = ([ATOMIC], Vec::new(), 7);
-const INTEGER: u8 = 8;
-const STRING: String = String::new();
-const STR: &str = "012345";
-const COW: Cow<str> = Cow::Borrowed("abcdef");
-const NO_ANN: &dyn Display = &70;
-static STATIC_TUPLE: (AtomicUsize, String) = (ATOMIC, STRING);
-const ONCE_INIT: Once = Once::new();
-
-trait Trait<T> {
- type AssocType;
-
- const ATOMIC: AtomicUsize;
- const INPUT: T;
- const ASSOC: Self::AssocType;
-
- fn function() {
- let _ = &Self::INPUT;
- let _ = &Self::ASSOC;
- }
-}
-
-impl Trait<u32> for u64 {
- type AssocType = AtomicUsize;
-
- const ATOMIC: AtomicUsize = AtomicUsize::new(9);
- const INPUT: u32 = 10;
- const ASSOC: Self::AssocType = AtomicUsize::new(11);
-
- fn function() {
- let _ = &Self::INPUT;
- let _ = &Self::ASSOC; //~ ERROR interior mutability
- }
-}
-
-// This is just a pointer that can be safely dereferended,
-// it's semantically the same as `&'static T`;
-// but it isn't allowed to make a static reference from an arbitrary integer value at the moment.
-// For more information, please see the issue #5918.
-pub struct StaticRef<T> {
- ptr: *const T,
-}
-
-impl<T> StaticRef<T> {
- /// Create a new `StaticRef` from a raw pointer
- ///
- /// ## Safety
- ///
- /// Callers must pass in a reference to statically allocated memory which
- /// does not overlap with other values.
- pub const unsafe fn new(ptr: *const T) -> StaticRef<T> {
- StaticRef { ptr }
- }
-}
-
-impl<T> std::ops::Deref for StaticRef<T> {
- type Target = T;
-
- fn deref(&self) -> &'static T {
- unsafe { &*self.ptr }
- }
-}
-
-// use a tuple to make sure referencing a field behind a pointer isn't linted.
-const CELL_REF: StaticRef<(UnsafeCell<u32>,)> = unsafe { StaticRef::new(std::ptr::null()) };
-
-fn main() {
- ATOMIC.store(1, Ordering::SeqCst); //~ ERROR interior mutability
- assert_eq!(ATOMIC.load(Ordering::SeqCst), 5); //~ ERROR interior mutability
-
- let _once = ONCE_INIT;
- let _once_ref = &ONCE_INIT; //~ ERROR interior mutability
- let _once_ref_2 = &&ONCE_INIT; //~ ERROR interior mutability
- let _once_ref_4 = &&&&ONCE_INIT; //~ ERROR interior mutability
- let _once_mut = &mut ONCE_INIT; //~ ERROR interior mutability
- let _atomic_into_inner = ATOMIC.into_inner();
- // these should be all fine.
- let _twice = (ONCE_INIT, ONCE_INIT);
- let _ref_twice = &(ONCE_INIT, ONCE_INIT);
- let _ref_once = &(ONCE_INIT, ONCE_INIT).0;
- let _array_twice = [ONCE_INIT, ONCE_INIT];
- let _ref_array_twice = &[ONCE_INIT, ONCE_INIT];
- let _ref_array_once = &[ONCE_INIT, ONCE_INIT][0];
-
- // referencing projection is still bad.
- let _ = &ATOMIC_TUPLE; //~ ERROR interior mutability
- let _ = &ATOMIC_TUPLE.0; //~ ERROR interior mutability
- let _ = &(&&&&ATOMIC_TUPLE).0; //~ ERROR interior mutability
- let _ = &ATOMIC_TUPLE.0[0]; //~ ERROR interior mutability
- let _ = ATOMIC_TUPLE.0[0].load(Ordering::SeqCst); //~ ERROR interior mutability
- let _ = &*ATOMIC_TUPLE.1; //~ ERROR interior mutability
- let _ = &ATOMIC_TUPLE.2;
- let _ = (&&&&ATOMIC_TUPLE).0;
- let _ = (&&&&ATOMIC_TUPLE).2;
- let _ = ATOMIC_TUPLE.0;
- let _ = ATOMIC_TUPLE.0[0]; //~ ERROR interior mutability
- let _ = ATOMIC_TUPLE.1.into_iter();
- let _ = ATOMIC_TUPLE.2;
- let _ = &{ ATOMIC_TUPLE };
-
- CELL.set(2); //~ ERROR interior mutability
- assert_eq!(CELL.get(), 6); //~ ERROR interior mutability
-
- assert_eq!(INTEGER, 8);
- assert!(STRING.is_empty());
-
- let a = ATOMIC;
- a.store(4, Ordering::SeqCst);
- assert_eq!(a.load(Ordering::SeqCst), 4);
-
- STATIC_TUPLE.0.store(3, Ordering::SeqCst);
- assert_eq!(STATIC_TUPLE.0.load(Ordering::SeqCst), 3);
- assert!(STATIC_TUPLE.1.is_empty());
-
- u64::ATOMIC.store(5, Ordering::SeqCst); //~ ERROR interior mutability
- assert_eq!(u64::ATOMIC.load(Ordering::SeqCst), 9); //~ ERROR interior mutability
-
- assert_eq!(NO_ANN.to_string(), "70"); // should never lint this.
-
- let _ = &CELL_REF.0;
-}
+++ /dev/null
-error: a `const` item with interior mutability should not be borrowed
- --> $DIR/borrow_interior_mutable_const.rs:44:18
- |
-LL | let _ = &Self::ASSOC; //~ ERROR interior mutability
- | ^^^^^^^^^^^
- |
- = note: `-D clippy::borrow-interior-mutable-const` implied by `-D warnings`
- = help: assign this const to a local or static variable, and use the variable here
-
-error: a `const` item with interior mutability should not be borrowed
- --> $DIR/borrow_interior_mutable_const.rs:80:5
- |
-LL | ATOMIC.store(1, Ordering::SeqCst); //~ ERROR interior mutability
- | ^^^^^^
- |
- = help: assign this const to a local or static variable, and use the variable here
-
-error: a `const` item with interior mutability should not be borrowed
- --> $DIR/borrow_interior_mutable_const.rs:81:16
- |
-LL | assert_eq!(ATOMIC.load(Ordering::SeqCst), 5); //~ ERROR interior mutability
- | ^^^^^^
- |
- = help: assign this const to a local or static variable, and use the variable here
-
-error: a `const` item with interior mutability should not be borrowed
- --> $DIR/borrow_interior_mutable_const.rs:84:22
- |
-LL | let _once_ref = &ONCE_INIT; //~ ERROR interior mutability
- | ^^^^^^^^^
- |
- = help: assign this const to a local or static variable, and use the variable here
-
-error: a `const` item with interior mutability should not be borrowed
- --> $DIR/borrow_interior_mutable_const.rs:85:25
- |
-LL | let _once_ref_2 = &&ONCE_INIT; //~ ERROR interior mutability
- | ^^^^^^^^^
- |
- = help: assign this const to a local or static variable, and use the variable here
-
-error: a `const` item with interior mutability should not be borrowed
- --> $DIR/borrow_interior_mutable_const.rs:86:27
- |
-LL | let _once_ref_4 = &&&&ONCE_INIT; //~ ERROR interior mutability
- | ^^^^^^^^^
- |
- = help: assign this const to a local or static variable, and use the variable here
-
-error: a `const` item with interior mutability should not be borrowed
- --> $DIR/borrow_interior_mutable_const.rs:87:26
- |
-LL | let _once_mut = &mut ONCE_INIT; //~ ERROR interior mutability
- | ^^^^^^^^^
- |
- = help: assign this const to a local or static variable, and use the variable here
-
-error: a `const` item with interior mutability should not be borrowed
- --> $DIR/borrow_interior_mutable_const.rs:98:14
- |
-LL | let _ = &ATOMIC_TUPLE; //~ ERROR interior mutability
- | ^^^^^^^^^^^^
- |
- = help: assign this const to a local or static variable, and use the variable here
-
-error: a `const` item with interior mutability should not be borrowed
- --> $DIR/borrow_interior_mutable_const.rs:99:14
- |
-LL | let _ = &ATOMIC_TUPLE.0; //~ ERROR interior mutability
- | ^^^^^^^^^^^^
- |
- = help: assign this const to a local or static variable, and use the variable here
-
-error: a `const` item with interior mutability should not be borrowed
- --> $DIR/borrow_interior_mutable_const.rs:100:19
- |
-LL | let _ = &(&&&&ATOMIC_TUPLE).0; //~ ERROR interior mutability
- | ^^^^^^^^^^^^
- |
- = help: assign this const to a local or static variable, and use the variable here
-
-error: a `const` item with interior mutability should not be borrowed
- --> $DIR/borrow_interior_mutable_const.rs:101:14
- |
-LL | let _ = &ATOMIC_TUPLE.0[0]; //~ ERROR interior mutability
- | ^^^^^^^^^^^^
- |
- = help: assign this const to a local or static variable, and use the variable here
-
-error: a `const` item with interior mutability should not be borrowed
- --> $DIR/borrow_interior_mutable_const.rs:102:13
- |
-LL | let _ = ATOMIC_TUPLE.0[0].load(Ordering::SeqCst); //~ ERROR interior mutability
- | ^^^^^^^^^^^^
- |
- = help: assign this const to a local or static variable, and use the variable here
-
-error: a `const` item with interior mutability should not be borrowed
- --> $DIR/borrow_interior_mutable_const.rs:108:13
- |
-LL | let _ = ATOMIC_TUPLE.0[0]; //~ ERROR interior mutability
- | ^^^^^^^^^^^^
- |
- = help: assign this const to a local or static variable, and use the variable here
-
-error: a `const` item with interior mutability should not be borrowed
- --> $DIR/borrow_interior_mutable_const.rs:113:5
- |
-LL | CELL.set(2); //~ ERROR interior mutability
- | ^^^^
- |
- = help: assign this const to a local or static variable, and use the variable here
-
-error: a `const` item with interior mutability should not be borrowed
- --> $DIR/borrow_interior_mutable_const.rs:114:16
- |
-LL | assert_eq!(CELL.get(), 6); //~ ERROR interior mutability
- | ^^^^
- |
- = help: assign this const to a local or static variable, and use the variable here
-
-error: a `const` item with interior mutability should not be borrowed
- --> $DIR/borrow_interior_mutable_const.rs:127:5
- |
-LL | u64::ATOMIC.store(5, Ordering::SeqCst); //~ ERROR interior mutability
- | ^^^^^^^^^^^
- |
- = help: assign this const to a local or static variable, and use the variable here
-
-error: a `const` item with interior mutability should not be borrowed
- --> $DIR/borrow_interior_mutable_const.rs:128:16
- |
-LL | assert_eq!(u64::ATOMIC.load(Ordering::SeqCst), 9); //~ ERROR interior mutability
- | ^^^^^^^^^^^
- |
- = help: assign this const to a local or static variable, and use the variable here
-
-error: aborting due to 17 previous errors
-
--- /dev/null
+#![warn(clippy::borrow_interior_mutable_const)]
+#![allow(clippy::declare_interior_mutable_const, clippy::ref_in_deref)]
+#![allow(const_item_mutation)]
+
+use std::borrow::Cow;
+use std::cell::{Cell, UnsafeCell};
+use std::fmt::Display;
+use std::sync::atomic::{AtomicUsize, Ordering};
+use std::sync::Once;
+
+const ATOMIC: AtomicUsize = AtomicUsize::new(5);
+const CELL: Cell<usize> = Cell::new(6);
+const ATOMIC_TUPLE: ([AtomicUsize; 1], Vec<AtomicUsize>, u8) = ([ATOMIC], Vec::new(), 7);
+const INTEGER: u8 = 8;
+const STRING: String = String::new();
+const STR: &str = "012345";
+const COW: Cow<str> = Cow::Borrowed("abcdef");
+const NO_ANN: &dyn Display = &70;
+static STATIC_TUPLE: (AtomicUsize, String) = (ATOMIC, STRING);
+const ONCE_INIT: Once = Once::new();
+
+// This is just a pointer that can be safely dereferenced,
+// it's semantically the same as `&'static T`;
+// but it isn't allowed to make a static reference from an arbitrary integer value at the moment.
+// For more information, please see the issue #5918.
+pub struct StaticRef<T> {
+ ptr: *const T,
+}
+
+impl<T> StaticRef<T> {
+ /// Create a new `StaticRef` from a raw pointer
+ ///
+ /// ## Safety
+ ///
+ /// Callers must pass in a reference to statically allocated memory which
+ /// does not overlap with other values.
+ pub const unsafe fn new(ptr: *const T) -> StaticRef<T> {
+ StaticRef { ptr }
+ }
+}
+
+impl<T> std::ops::Deref for StaticRef<T> {
+ type Target = T;
+
+ fn deref(&self) -> &'static T {
+ unsafe { &*self.ptr }
+ }
+}
+
+// use a tuple to make sure referencing a field behind a pointer isn't linted.
+const CELL_REF: StaticRef<(UnsafeCell<u32>,)> = unsafe { StaticRef::new(std::ptr::null()) };
+
+fn main() {
+ ATOMIC.store(1, Ordering::SeqCst); //~ ERROR interior mutability
+ assert_eq!(ATOMIC.load(Ordering::SeqCst), 5); //~ ERROR interior mutability
+
+ let _once = ONCE_INIT;
+ let _once_ref = &ONCE_INIT; //~ ERROR interior mutability
+ let _once_ref_2 = &&ONCE_INIT; //~ ERROR interior mutability
+ let _once_ref_4 = &&&&ONCE_INIT; //~ ERROR interior mutability
+ let _once_mut = &mut ONCE_INIT; //~ ERROR interior mutability
+ let _atomic_into_inner = ATOMIC.into_inner();
+ // these should be all fine.
+ let _twice = (ONCE_INIT, ONCE_INIT);
+ let _ref_twice = &(ONCE_INIT, ONCE_INIT);
+ let _ref_once = &(ONCE_INIT, ONCE_INIT).0;
+ let _array_twice = [ONCE_INIT, ONCE_INIT];
+ let _ref_array_twice = &[ONCE_INIT, ONCE_INIT];
+ let _ref_array_once = &[ONCE_INIT, ONCE_INIT][0];
+
+ // referencing projection is still bad.
+ let _ = &ATOMIC_TUPLE; //~ ERROR interior mutability
+ let _ = &ATOMIC_TUPLE.0; //~ ERROR interior mutability
+ let _ = &(&&&&ATOMIC_TUPLE).0; //~ ERROR interior mutability
+ let _ = &ATOMIC_TUPLE.0[0]; //~ ERROR interior mutability
+ let _ = ATOMIC_TUPLE.0[0].load(Ordering::SeqCst); //~ ERROR interior mutability
+ let _ = &*ATOMIC_TUPLE.1;
+ let _ = &ATOMIC_TUPLE.2;
+ let _ = (&&&&ATOMIC_TUPLE).0;
+ let _ = (&&&&ATOMIC_TUPLE).2;
+ let _ = ATOMIC_TUPLE.0;
+ let _ = ATOMIC_TUPLE.0[0]; //~ ERROR interior mutability
+ let _ = ATOMIC_TUPLE.1.into_iter();
+ let _ = ATOMIC_TUPLE.2;
+ let _ = &{ ATOMIC_TUPLE };
+
+ CELL.set(2); //~ ERROR interior mutability
+ assert_eq!(CELL.get(), 6); //~ ERROR interior mutability
+
+ assert_eq!(INTEGER, 8);
+ assert!(STRING.is_empty());
+
+ let a = ATOMIC;
+ a.store(4, Ordering::SeqCst);
+ assert_eq!(a.load(Ordering::SeqCst), 4);
+
+ STATIC_TUPLE.0.store(3, Ordering::SeqCst);
+ assert_eq!(STATIC_TUPLE.0.load(Ordering::SeqCst), 3);
+ assert!(STATIC_TUPLE.1.is_empty());
+
+ assert_eq!(NO_ANN.to_string(), "70"); // should never lint this.
+
+ let _ = &CELL_REF.0;
+}
--- /dev/null
+error: a `const` item with interior mutability should not be borrowed
+ --> $DIR/others.rs:54:5
+ |
+LL | ATOMIC.store(1, Ordering::SeqCst); //~ ERROR interior mutability
+ | ^^^^^^
+ |
+ = note: `-D clippy::borrow-interior-mutable-const` implied by `-D warnings`
+ = help: assign this const to a local or static variable, and use the variable here
+
+error: a `const` item with interior mutability should not be borrowed
+ --> $DIR/others.rs:55:16
+ |
+LL | assert_eq!(ATOMIC.load(Ordering::SeqCst), 5); //~ ERROR interior mutability
+ | ^^^^^^
+ |
+ = help: assign this const to a local or static variable, and use the variable here
+
+error: a `const` item with interior mutability should not be borrowed
+ --> $DIR/others.rs:58:22
+ |
+LL | let _once_ref = &ONCE_INIT; //~ ERROR interior mutability
+ | ^^^^^^^^^
+ |
+ = help: assign this const to a local or static variable, and use the variable here
+
+error: a `const` item with interior mutability should not be borrowed
+ --> $DIR/others.rs:59:25
+ |
+LL | let _once_ref_2 = &&ONCE_INIT; //~ ERROR interior mutability
+ | ^^^^^^^^^
+ |
+ = help: assign this const to a local or static variable, and use the variable here
+
+error: a `const` item with interior mutability should not be borrowed
+ --> $DIR/others.rs:60:27
+ |
+LL | let _once_ref_4 = &&&&ONCE_INIT; //~ ERROR interior mutability
+ | ^^^^^^^^^
+ |
+ = help: assign this const to a local or static variable, and use the variable here
+
+error: a `const` item with interior mutability should not be borrowed
+ --> $DIR/others.rs:61:26
+ |
+LL | let _once_mut = &mut ONCE_INIT; //~ ERROR interior mutability
+ | ^^^^^^^^^
+ |
+ = help: assign this const to a local or static variable, and use the variable here
+
+error: a `const` item with interior mutability should not be borrowed
+ --> $DIR/others.rs:72:14
+ |
+LL | let _ = &ATOMIC_TUPLE; //~ ERROR interior mutability
+ | ^^^^^^^^^^^^
+ |
+ = help: assign this const to a local or static variable, and use the variable here
+
+error: a `const` item with interior mutability should not be borrowed
+ --> $DIR/others.rs:73:14
+ |
+LL | let _ = &ATOMIC_TUPLE.0; //~ ERROR interior mutability
+ | ^^^^^^^^^^^^
+ |
+ = help: assign this const to a local or static variable, and use the variable here
+
+error: a `const` item with interior mutability should not be borrowed
+ --> $DIR/others.rs:74:19
+ |
+LL | let _ = &(&&&&ATOMIC_TUPLE).0; //~ ERROR interior mutability
+ | ^^^^^^^^^^^^
+ |
+ = help: assign this const to a local or static variable, and use the variable here
+
+error: a `const` item with interior mutability should not be borrowed
+ --> $DIR/others.rs:75:14
+ |
+LL | let _ = &ATOMIC_TUPLE.0[0]; //~ ERROR interior mutability
+ | ^^^^^^^^^^^^
+ |
+ = help: assign this const to a local or static variable, and use the variable here
+
+error: a `const` item with interior mutability should not be borrowed
+ --> $DIR/others.rs:76:13
+ |
+LL | let _ = ATOMIC_TUPLE.0[0].load(Ordering::SeqCst); //~ ERROR interior mutability
+ | ^^^^^^^^^^^^
+ |
+ = help: assign this const to a local or static variable, and use the variable here
+
+error: a `const` item with interior mutability should not be borrowed
+ --> $DIR/others.rs:82:13
+ |
+LL | let _ = ATOMIC_TUPLE.0[0]; //~ ERROR interior mutability
+ | ^^^^^^^^^^^^
+ |
+ = help: assign this const to a local or static variable, and use the variable here
+
+error: a `const` item with interior mutability should not be borrowed
+ --> $DIR/others.rs:87:5
+ |
+LL | CELL.set(2); //~ ERROR interior mutability
+ | ^^^^
+ |
+ = help: assign this const to a local or static variable, and use the variable here
+
+error: a `const` item with interior mutability should not be borrowed
+ --> $DIR/others.rs:88:16
+ |
+LL | assert_eq!(CELL.get(), 6); //~ ERROR interior mutability
+ | ^^^^
+ |
+ = help: assign this const to a local or static variable, and use the variable here
+
+error: aborting due to 14 previous errors
+
--- /dev/null
+#![warn(clippy::borrow_interior_mutable_const)]
+#![allow(clippy::declare_interior_mutable_const)]
+
+// this file replicates its `declare` counterpart. Please see it for more discussions.
+
+use std::borrow::Cow;
+use std::cell::Cell;
+use std::sync::atomic::{AtomicUsize, Ordering};
+
+trait ConcreteTypes {
+ const ATOMIC: AtomicUsize;
+ const STRING: String;
+
+ fn function() {
+ let _ = &Self::ATOMIC; //~ ERROR interior mutable
+ let _ = &Self::STRING;
+ }
+}
+
+impl ConcreteTypes for u64 {
+ const ATOMIC: AtomicUsize = AtomicUsize::new(9);
+ const STRING: String = String::new();
+
+ fn function() {
+ // Lint this again since implementers can choose not to borrow it.
+ let _ = &Self::ATOMIC; //~ ERROR interior mutable
+ let _ = &Self::STRING;
+ }
+}
+
+// a helper trait used below
+trait ConstDefault {
+ const DEFAULT: Self;
+}
+
+trait GenericTypes<T, U> {
+ const TO_REMAIN_GENERIC: T;
+ const TO_BE_CONCRETE: U;
+
+ fn function() {
+ let _ = &Self::TO_REMAIN_GENERIC;
+ }
+}
+
+impl<T: ConstDefault> GenericTypes<T, AtomicUsize> for Vec<T> {
+ const TO_REMAIN_GENERIC: T = T::DEFAULT;
+ const TO_BE_CONCRETE: AtomicUsize = AtomicUsize::new(11);
+
+ fn function() {
+ let _ = &Self::TO_REMAIN_GENERIC;
+ let _ = &Self::TO_BE_CONCRETE; //~ ERROR interior mutable
+ }
+}
+
+// a helper type used below
+pub struct Wrapper<T>(T);
+
+trait AssocTypes {
+ type ToBeFrozen;
+ type ToBeUnfrozen;
+ type ToBeGenericParam;
+
+ const TO_BE_FROZEN: Self::ToBeFrozen;
+ const TO_BE_UNFROZEN: Self::ToBeUnfrozen;
+ const WRAPPED_TO_BE_UNFROZEN: Wrapper<Self::ToBeUnfrozen>;
+ const WRAPPED_TO_BE_GENERIC_PARAM: Wrapper<Self::ToBeGenericParam>;
+
+ fn function() {
+ let _ = &Self::TO_BE_FROZEN;
+ let _ = &Self::WRAPPED_TO_BE_UNFROZEN;
+ }
+}
+
+impl<T: ConstDefault> AssocTypes for Vec<T> {
+ type ToBeFrozen = u16;
+ type ToBeUnfrozen = AtomicUsize;
+ type ToBeGenericParam = T;
+
+ const TO_BE_FROZEN: Self::ToBeFrozen = 12;
+ const TO_BE_UNFROZEN: Self::ToBeUnfrozen = AtomicUsize::new(13);
+ const WRAPPED_TO_BE_UNFROZEN: Wrapper<Self::ToBeUnfrozen> = Wrapper(AtomicUsize::new(14));
+ const WRAPPED_TO_BE_GENERIC_PARAM: Wrapper<Self::ToBeGenericParam> = Wrapper(T::DEFAULT);
+
+ fn function() {
+ let _ = &Self::TO_BE_FROZEN;
+ let _ = &Self::TO_BE_UNFROZEN; //~ ERROR interior mutable
+ let _ = &Self::WRAPPED_TO_BE_UNFROZEN; //~ ERROR interior mutable
+ let _ = &Self::WRAPPED_TO_BE_GENERIC_PARAM;
+ }
+}
+
+// a helper trait used below
+trait AssocTypesHelper {
+ type NotToBeBounded;
+ type ToBeBounded;
+
+ const NOT_TO_BE_BOUNDED: Self::NotToBeBounded;
+}
+
+trait AssocTypesFromGenericParam<T>
+where
+ T: AssocTypesHelper<ToBeBounded = AtomicUsize>,
+{
+ const NOT_BOUNDED: T::NotToBeBounded;
+ const BOUNDED: T::ToBeBounded;
+
+ fn function() {
+ let _ = &Self::NOT_BOUNDED;
+ let _ = &Self::BOUNDED; //~ ERROR interior mutable
+ }
+}
+
+impl<T> AssocTypesFromGenericParam<T> for Vec<T>
+where
+ T: AssocTypesHelper<ToBeBounded = AtomicUsize>,
+{
+ const NOT_BOUNDED: T::NotToBeBounded = T::NOT_TO_BE_BOUNDED;
+ const BOUNDED: T::ToBeBounded = AtomicUsize::new(15);
+
+ fn function() {
+ let _ = &Self::NOT_BOUNDED;
+ let _ = &Self::BOUNDED; //~ ERROR interior mutable
+ }
+}
+
+trait SelfType: Sized {
+ const SELF: Self;
+ const WRAPPED_SELF: Option<Self>;
+
+ fn function() {
+ let _ = &Self::SELF;
+ let _ = &Self::WRAPPED_SELF;
+ }
+}
+
+impl SelfType for u64 {
+ const SELF: Self = 16;
+ const WRAPPED_SELF: Option<Self> = Some(20);
+
+ fn function() {
+ let _ = &Self::SELF;
+ let _ = &Self::WRAPPED_SELF;
+ }
+}
+
+impl SelfType for AtomicUsize {
+ const SELF: Self = AtomicUsize::new(17);
+ const WRAPPED_SELF: Option<Self> = Some(AtomicUsize::new(21));
+
+ fn function() {
+ let _ = &Self::SELF; //~ ERROR interior mutable
+ let _ = &Self::WRAPPED_SELF; //~ ERROR interior mutable
+ }
+}
+
+trait BothOfCellAndGeneric<T> {
+ const DIRECT: Cell<T>;
+ const INDIRECT: Cell<*const T>;
+
+ fn function() {
+ let _ = &Self::DIRECT;
+ let _ = &Self::INDIRECT; //~ ERROR interior mutable
+ }
+}
+
+impl<T: ConstDefault> BothOfCellAndGeneric<T> for Vec<T> {
+ const DIRECT: Cell<T> = Cell::new(T::DEFAULT);
+ const INDIRECT: Cell<*const T> = Cell::new(std::ptr::null());
+
+ fn function() {
+ let _ = &Self::DIRECT;
+ let _ = &Self::INDIRECT; //~ ERROR interior mutable
+ }
+}
+
+struct Local<T>(T);
+
+impl<T> Local<T>
+where
+ T: ConstDefault + AssocTypesHelper<ToBeBounded = AtomicUsize>,
+{
+ const ATOMIC: AtomicUsize = AtomicUsize::new(18);
+ const COW: Cow<'static, str> = Cow::Borrowed("tuvwxy");
+
+ const GENERIC_TYPE: T = T::DEFAULT;
+
+ const ASSOC_TYPE: T::NotToBeBounded = T::NOT_TO_BE_BOUNDED;
+ const BOUNDED_ASSOC_TYPE: T::ToBeBounded = AtomicUsize::new(19);
+
+ fn function() {
+ let _ = &Self::ATOMIC; //~ ERROR interior mutable
+ let _ = &Self::COW;
+ let _ = &Self::GENERIC_TYPE;
+ let _ = &Self::ASSOC_TYPE;
+ let _ = &Self::BOUNDED_ASSOC_TYPE; //~ ERROR interior mutable
+ }
+}
+
+fn main() {
+ u64::ATOMIC.store(5, Ordering::SeqCst); //~ ERROR interior mutability
+ assert_eq!(u64::ATOMIC.load(Ordering::SeqCst), 9); //~ ERROR interior mutability
+}
--- /dev/null
+error: a `const` item with interior mutability should not be borrowed
+ --> $DIR/traits.rs:15:18
+ |
+LL | let _ = &Self::ATOMIC; //~ ERROR interior mutable
+ | ^^^^^^^^^^^^
+ |
+ = note: `-D clippy::borrow-interior-mutable-const` implied by `-D warnings`
+ = help: assign this const to a local or static variable, and use the variable here
+
+error: a `const` item with interior mutability should not be borrowed
+ --> $DIR/traits.rs:26:18
+ |
+LL | let _ = &Self::ATOMIC; //~ ERROR interior mutable
+ | ^^^^^^^^^^^^
+ |
+ = help: assign this const to a local or static variable, and use the variable here
+
+error: a `const` item with interior mutability should not be borrowed
+ --> $DIR/traits.rs:51:18
+ |
+LL | let _ = &Self::TO_BE_CONCRETE; //~ ERROR interior mutable
+ | ^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: assign this const to a local or static variable, and use the variable here
+
+error: a `const` item with interior mutability should not be borrowed
+ --> $DIR/traits.rs:86:18
+ |
+LL | let _ = &Self::TO_BE_UNFROZEN; //~ ERROR interior mutable
+ | ^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: assign this const to a local or static variable, and use the variable here
+
+error: a `const` item with interior mutability should not be borrowed
+ --> $DIR/traits.rs:87:18
+ |
+LL | let _ = &Self::WRAPPED_TO_BE_UNFROZEN; //~ ERROR interior mutable
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: assign this const to a local or static variable, and use the variable here
+
+error: a `const` item with interior mutability should not be borrowed
+ --> $DIR/traits.rs:109:18
+ |
+LL | let _ = &Self::BOUNDED; //~ ERROR interior mutable
+ | ^^^^^^^^^^^^^
+ |
+ = help: assign this const to a local or static variable, and use the variable here
+
+error: a `const` item with interior mutability should not be borrowed
+ --> $DIR/traits.rs:122:18
+ |
+LL | let _ = &Self::BOUNDED; //~ ERROR interior mutable
+ | ^^^^^^^^^^^^^
+ |
+ = help: assign this const to a local or static variable, and use the variable here
+
+error: a `const` item with interior mutability should not be borrowed
+ --> $DIR/traits.rs:151:18
+ |
+LL | let _ = &Self::SELF; //~ ERROR interior mutable
+ | ^^^^^^^^^^
+ |
+ = help: assign this const to a local or static variable, and use the variable here
+
+error: a `const` item with interior mutability should not be borrowed
+ --> $DIR/traits.rs:152:18
+ |
+LL | let _ = &Self::WRAPPED_SELF; //~ ERROR interior mutable
+ | ^^^^^^^^^^^^^^^^^^
+ |
+ = help: assign this const to a local or static variable, and use the variable here
+
+error: a `const` item with interior mutability should not be borrowed
+ --> $DIR/traits.rs:162:18
+ |
+LL | let _ = &Self::INDIRECT; //~ ERROR interior mutable
+ | ^^^^^^^^^^^^^^
+ |
+ = help: assign this const to a local or static variable, and use the variable here
+
+error: a `const` item with interior mutability should not be borrowed
+ --> $DIR/traits.rs:172:18
+ |
+LL | let _ = &Self::INDIRECT; //~ ERROR interior mutable
+ | ^^^^^^^^^^^^^^
+ |
+ = help: assign this const to a local or static variable, and use the variable here
+
+error: a `const` item with interior mutability should not be borrowed
+ --> $DIR/traits.rs:191:18
+ |
+LL | let _ = &Self::ATOMIC; //~ ERROR interior mutable
+ | ^^^^^^^^^^^^
+ |
+ = help: assign this const to a local or static variable, and use the variable here
+
+error: a `const` item with interior mutability should not be borrowed
+ --> $DIR/traits.rs:195:18
+ |
+LL | let _ = &Self::BOUNDED_ASSOC_TYPE; //~ ERROR interior mutable
+ | ^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: assign this const to a local or static variable, and use the variable here
+
+error: a `const` item with interior mutability should not be borrowed
+ --> $DIR/traits.rs:200:5
+ |
+LL | u64::ATOMIC.store(5, Ordering::SeqCst); //~ ERROR interior mutability
+ | ^^^^^^^^^^^
+ |
+ = help: assign this const to a local or static variable, and use the variable here
+
+error: a `const` item with interior mutability should not be borrowed
+ --> $DIR/traits.rs:201:16
+ |
+LL | assert_eq!(u64::ATOMIC.load(Ordering::SeqCst), 9); //~ ERROR interior mutability
+ | ^^^^^^^^^^^
+ |
+ = help: assign this const to a local or static variable, and use the variable here
+
+error: aborting due to 15 previous errors
+
+++ /dev/null
-#![warn(clippy::declare_interior_mutable_const)]
-
-use std::borrow::Cow;
-use std::cell::Cell;
-use std::fmt::Display;
-use std::sync::atomic::AtomicUsize;
-use std::sync::Once;
-
-const ATOMIC: AtomicUsize = AtomicUsize::new(5); //~ ERROR interior mutable
-const CELL: Cell<usize> = Cell::new(6); //~ ERROR interior mutable
-const ATOMIC_TUPLE: ([AtomicUsize; 1], Vec<AtomicUsize>, u8) = ([ATOMIC], Vec::new(), 7);
-//~^ ERROR interior mutable
-
-macro_rules! declare_const {
- ($name:ident: $ty:ty = $e:expr) => {
- const $name: $ty = $e;
- };
-}
-declare_const!(_ONCE: Once = Once::new()); //~ ERROR interior mutable
-
-// const ATOMIC_REF: &AtomicUsize = &AtomicUsize::new(7); // This will simply trigger E0492.
-
-const INTEGER: u8 = 8;
-const STRING: String = String::new();
-const STR: &str = "012345";
-const COW: Cow<str> = Cow::Borrowed("abcdef");
-//^ note: a const item of Cow is used in the `postgres` package.
-
-const NO_ANN: &dyn Display = &70;
-
-static STATIC_TUPLE: (AtomicUsize, String) = (ATOMIC, STRING);
-//^ there should be no lints on this line
-
-#[allow(clippy::declare_interior_mutable_const)]
-const ONCE_INIT: Once = Once::new();
-
-// a constant whose type is a concrete type should be linted at the definition site.
-trait ConcreteTypes {
- const ATOMIC: AtomicUsize; //~ ERROR interior mutable
- const INTEGER: u64;
- const STRING: String;
- declare_const!(ANOTHER_ATOMIC: AtomicUsize = Self::ATOMIC); //~ ERROR interior mutable
-}
-
-impl ConcreteTypes for u64 {
- const ATOMIC: AtomicUsize = AtomicUsize::new(9);
- const INTEGER: u64 = 10;
- const STRING: String = String::new();
-}
-
-// a helper trait used below
-trait ConstDefault {
- const DEFAULT: Self;
-}
-
-// a constant whose type is a generic type should be linted at the implementation site.
-trait GenericTypes<T, U> {
- const TO_REMAIN_GENERIC: T;
- const TO_BE_CONCRETE: U;
-
- const HAVING_DEFAULT: T = Self::TO_REMAIN_GENERIC;
- declare_const!(IN_MACRO: T = Self::TO_REMAIN_GENERIC);
-}
-
-impl<T: ConstDefault> GenericTypes<T, AtomicUsize> for u64 {
- const TO_REMAIN_GENERIC: T = T::DEFAULT;
- const TO_BE_CONCRETE: AtomicUsize = AtomicUsize::new(11); //~ ERROR interior mutable
-}
-
-// a helper type used below
-struct Wrapper<T>(T);
-
-// a constant whose type is an associated type should be linted at the implementation site, too.
-trait AssocTypes {
- type ToBeFrozen;
- type ToBeUnfrozen;
- type ToBeGenericParam;
-
- const TO_BE_FROZEN: Self::ToBeFrozen;
- const TO_BE_UNFROZEN: Self::ToBeUnfrozen;
- const WRAPPED_TO_BE_UNFROZEN: Wrapper<Self::ToBeUnfrozen>;
- // to ensure it can handle things when a generic type remains after normalization.
- const WRAPPED_TO_BE_GENERIC_PARAM: Wrapper<Self::ToBeGenericParam>;
-}
-
-impl<T: ConstDefault> AssocTypes for Vec<T> {
- type ToBeFrozen = u16;
- type ToBeUnfrozen = AtomicUsize;
- type ToBeGenericParam = T;
-
- const TO_BE_FROZEN: Self::ToBeFrozen = 12;
- const TO_BE_UNFROZEN: Self::ToBeUnfrozen = AtomicUsize::new(13); //~ ERROR interior mutable
- const WRAPPED_TO_BE_UNFROZEN: Wrapper<Self::ToBeUnfrozen> = Wrapper(AtomicUsize::new(14)); //~ ERROR interior mutable
- const WRAPPED_TO_BE_GENERIC_PARAM: Wrapper<Self::ToBeGenericParam> = Wrapper(T::DEFAULT);
-}
-
-// a helper trait used below
-trait AssocTypesHelper {
- type NotToBeBounded;
- type ToBeBounded;
-
- const NOT_TO_BE_BOUNDED: Self::NotToBeBounded;
-}
-
-// a constant whose type is an assoc type originated from a generic param bounded at the definition
-// site should be linted at there.
-trait AssocTypesFromGenericParam<T>
-where
- T: AssocTypesHelper<ToBeBounded = AtomicUsize>,
-{
- const NOT_BOUNDED: T::NotToBeBounded;
- const BOUNDED: T::ToBeBounded; //~ ERROR interior mutable
-}
-
-impl<T> AssocTypesFromGenericParam<T> for u64
-where
- T: AssocTypesHelper<ToBeBounded = AtomicUsize>,
-{
- // an associated type could remain unknown in a trait impl.
- const NOT_BOUNDED: T::NotToBeBounded = T::NOT_TO_BE_BOUNDED;
- const BOUNDED: T::ToBeBounded = AtomicUsize::new(15);
-}
-
-// a constant whose type is `Self` should be linted at the implementation site as well.
-// (`Option` requires `Sized` bound.)
-trait SelfType: Sized {
- const SELF: Self;
- // this was the one in the original issue (#5050).
- const WRAPPED_SELF: Option<Self>;
-}
-
-impl SelfType for u64 {
- const SELF: Self = 16;
- const WRAPPED_SELF: Option<Self> = Some(20);
-}
-
-impl SelfType for AtomicUsize {
- // this (interior mutable `Self` const) exists in `parking_lot`.
- // `const_trait_impl` will replace it in the future, hopefully.
- const SELF: Self = AtomicUsize::new(17); //~ ERROR interior mutable
- const WRAPPED_SELF: Option<Self> = Some(AtomicUsize::new(21)); //~ ERROR interior mutable
-}
-
-// Even though a constant contains a generic type, if it also have a interior mutable type,
-// it should be linted at the definition site.
-trait BothOfCellAndGeneric<T> {
- // this is a false negative in the current implementation.
- const DIRECT: Cell<T>;
- const INDIRECT: Cell<*const T>; //~ ERROR interior mutable
-}
-
-impl<T: ConstDefault> BothOfCellAndGeneric<T> for u64 {
- const DIRECT: Cell<T> = Cell::new(T::DEFAULT);
- const INDIRECT: Cell<*const T> = Cell::new(std::ptr::null());
-}
-
-struct Local<T>(T);
-
-// a constant in an inherent impl are essentially the same as a normal const item
-// except there can be a generic or associated type.
-impl<T> Local<T>
-where
- T: ConstDefault + AssocTypesHelper<ToBeBounded = AtomicUsize>,
-{
- const ATOMIC: AtomicUsize = AtomicUsize::new(18); //~ ERROR interior mutable
- const COW: Cow<'static, str> = Cow::Borrowed("tuvwxy");
-
- const GENERIC_TYPE: T = T::DEFAULT;
-
- const ASSOC_TYPE: T::NotToBeBounded = T::NOT_TO_BE_BOUNDED;
- const BOUNDED_ASSOC_TYPE: T::ToBeBounded = AtomicUsize::new(19); //~ ERROR interior mutable
-}
-
-fn main() {}
+++ /dev/null
-error: a `const` item should never be interior mutable
- --> $DIR/declare_interior_mutable_const.rs:9:1
- |
-LL | const ATOMIC: AtomicUsize = AtomicUsize::new(5); //~ ERROR interior mutable
- | -----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- | |
- | make this a static item (maybe with lazy_static)
- |
- = note: `-D clippy::declare-interior-mutable-const` implied by `-D warnings`
-
-error: a `const` item should never be interior mutable
- --> $DIR/declare_interior_mutable_const.rs:10:1
- |
-LL | const CELL: Cell<usize> = Cell::new(6); //~ ERROR interior mutable
- | -----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- | |
- | make this a static item (maybe with lazy_static)
-
-error: a `const` item should never be interior mutable
- --> $DIR/declare_interior_mutable_const.rs:11:1
- |
-LL | const ATOMIC_TUPLE: ([AtomicUsize; 1], Vec<AtomicUsize>, u8) = ([ATOMIC], Vec::new(), 7);
- | -----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- | |
- | make this a static item (maybe with lazy_static)
-
-error: a `const` item should never be interior mutable
- --> $DIR/declare_interior_mutable_const.rs:16:9
- |
-LL | const $name: $ty = $e;
- | ^^^^^^^^^^^^^^^^^^^^^^
-...
-LL | declare_const!(_ONCE: Once = Once::new()); //~ ERROR interior mutable
- | ------------------------------------------ in this macro invocation
- |
- = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
-
-error: a `const` item should never be interior mutable
- --> $DIR/declare_interior_mutable_const.rs:39:5
- |
-LL | const ATOMIC: AtomicUsize; //~ ERROR interior mutable
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: a `const` item should never be interior mutable
- --> $DIR/declare_interior_mutable_const.rs:16:9
- |
-LL | const $name: $ty = $e;
- | ^^^^^^^^^^^^^^^^^^^^^^
-...
-LL | declare_const!(ANOTHER_ATOMIC: AtomicUsize = Self::ATOMIC); //~ ERROR interior mutable
- | ----------------------------------------------------------- in this macro invocation
- |
- = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
-
-error: a `const` item should never be interior mutable
- --> $DIR/declare_interior_mutable_const.rs:67:5
- |
-LL | const TO_BE_CONCRETE: AtomicUsize = AtomicUsize::new(11); //~ ERROR interior mutable
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: a `const` item should never be interior mutable
- --> $DIR/declare_interior_mutable_const.rs:92:5
- |
-LL | const TO_BE_UNFROZEN: Self::ToBeUnfrozen = AtomicUsize::new(13); //~ ERROR interior mutable
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: a `const` item should never be interior mutable
- --> $DIR/declare_interior_mutable_const.rs:93:5
- |
-LL | const WRAPPED_TO_BE_UNFROZEN: Wrapper<Self::ToBeUnfrozen> = Wrapper(AtomicUsize::new(14)); //~ ERROR interior mutable
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: a `const` item should never be interior mutable
- --> $DIR/declare_interior_mutable_const.rs:112:5
- |
-LL | const BOUNDED: T::ToBeBounded; //~ ERROR interior mutable
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: a `const` item should never be interior mutable
- --> $DIR/declare_interior_mutable_const.rs:140:5
- |
-LL | const SELF: Self = AtomicUsize::new(17); //~ ERROR interior mutable
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: a `const` item should never be interior mutable
- --> $DIR/declare_interior_mutable_const.rs:141:5
- |
-LL | const WRAPPED_SELF: Option<Self> = Some(AtomicUsize::new(21)); //~ ERROR interior mutable
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: a `const` item should never be interior mutable
- --> $DIR/declare_interior_mutable_const.rs:149:5
- |
-LL | const INDIRECT: Cell<*const T>; //~ ERROR interior mutable
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: a `const` item should never be interior mutable
- --> $DIR/declare_interior_mutable_const.rs:165:5
- |
-LL | const ATOMIC: AtomicUsize = AtomicUsize::new(18); //~ ERROR interior mutable
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: a `const` item should never be interior mutable
- --> $DIR/declare_interior_mutable_const.rs:171:5
- |
-LL | const BOUNDED_ASSOC_TYPE: T::ToBeBounded = AtomicUsize::new(19); //~ ERROR interior mutable
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: aborting due to 15 previous errors
-
--- /dev/null
+#![warn(clippy::declare_interior_mutable_const)]
+
+use std::borrow::Cow;
+use std::cell::Cell;
+use std::fmt::Display;
+use std::sync::atomic::AtomicUsize;
+use std::sync::Once;
+
+const ATOMIC: AtomicUsize = AtomicUsize::new(5); //~ ERROR interior mutable
+const CELL: Cell<usize> = Cell::new(6); //~ ERROR interior mutable
+const ATOMIC_TUPLE: ([AtomicUsize; 1], Vec<AtomicUsize>, u8) = ([ATOMIC], Vec::new(), 7);
+//~^ ERROR interior mutable
+
+macro_rules! declare_const {
+ ($name:ident: $ty:ty = $e:expr) => {
+ const $name: $ty = $e;
+ };
+}
+declare_const!(_ONCE: Once = Once::new()); //~ ERROR interior mutable
+
+// const ATOMIC_REF: &AtomicUsize = &AtomicUsize::new(7); // This will simply trigger E0492.
+
+const INTEGER: u8 = 8;
+const STRING: String = String::new();
+const STR: &str = "012345";
+const COW: Cow<str> = Cow::Borrowed("abcdef");
+//^ note: a const item of Cow is used in the `postgres` package.
+
+const NO_ANN: &dyn Display = &70;
+
+static STATIC_TUPLE: (AtomicUsize, String) = (ATOMIC, STRING);
+//^ there should be no lints on this line
+
+fn main() {}
--- /dev/null
+error: a `const` item should never be interior mutable
+ --> $DIR/others.rs:9:1
+ |
+LL | const ATOMIC: AtomicUsize = AtomicUsize::new(5); //~ ERROR interior mutable
+ | -----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | |
+ | make this a static item (maybe with lazy_static)
+ |
+ = note: `-D clippy::declare-interior-mutable-const` implied by `-D warnings`
+
+error: a `const` item should never be interior mutable
+ --> $DIR/others.rs:10:1
+ |
+LL | const CELL: Cell<usize> = Cell::new(6); //~ ERROR interior mutable
+ | -----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | |
+ | make this a static item (maybe with lazy_static)
+
+error: a `const` item should never be interior mutable
+ --> $DIR/others.rs:11:1
+ |
+LL | const ATOMIC_TUPLE: ([AtomicUsize; 1], Vec<AtomicUsize>, u8) = ([ATOMIC], Vec::new(), 7);
+ | -----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | |
+ | make this a static item (maybe with lazy_static)
+
+error: a `const` item should never be interior mutable
+ --> $DIR/others.rs:16:9
+ |
+LL | const $name: $ty = $e;
+ | ^^^^^^^^^^^^^^^^^^^^^^
+...
+LL | declare_const!(_ONCE: Once = Once::new()); //~ ERROR interior mutable
+ | ------------------------------------------ in this macro invocation
+ |
+ = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 4 previous errors
+
--- /dev/null
+#![warn(clippy::declare_interior_mutable_const)]
+
+use std::borrow::Cow;
+use std::cell::Cell;
+use std::sync::atomic::AtomicUsize;
+
+macro_rules! declare_const {
+ ($name:ident: $ty:ty = $e:expr) => {
+ const $name: $ty = $e;
+ };
+}
+
+// a constant whose type is a concrete type should be linted at the definition site.
+trait ConcreteTypes {
+ const ATOMIC: AtomicUsize; //~ ERROR interior mutable
+ const INTEGER: u64;
+ const STRING: String;
+ declare_const!(ANOTHER_ATOMIC: AtomicUsize = Self::ATOMIC); //~ ERROR interior mutable
+}
+
+impl ConcreteTypes for u64 {
+ const ATOMIC: AtomicUsize = AtomicUsize::new(9);
+ const INTEGER: u64 = 10;
+ const STRING: String = String::new();
+}
+
+// a helper trait used below
+trait ConstDefault {
+ const DEFAULT: Self;
+}
+
+// a constant whose type is a generic type should be linted at the implementation site.
+trait GenericTypes<T, U> {
+ const TO_REMAIN_GENERIC: T;
+ const TO_BE_CONCRETE: U;
+
+ const HAVING_DEFAULT: T = Self::TO_REMAIN_GENERIC;
+ declare_const!(IN_MACRO: T = Self::TO_REMAIN_GENERIC);
+}
+
+impl<T: ConstDefault> GenericTypes<T, AtomicUsize> for u64 {
+ const TO_REMAIN_GENERIC: T = T::DEFAULT;
+ const TO_BE_CONCRETE: AtomicUsize = AtomicUsize::new(11); //~ ERROR interior mutable
+}
+
+// a helper type used below
+struct Wrapper<T>(T);
+
+// a constant whose type is an associated type should be linted at the implementation site, too.
+trait AssocTypes {
+ type ToBeFrozen;
+ type ToBeUnfrozen;
+ type ToBeGenericParam;
+
+ const TO_BE_FROZEN: Self::ToBeFrozen;
+ const TO_BE_UNFROZEN: Self::ToBeUnfrozen;
+ const WRAPPED_TO_BE_UNFROZEN: Wrapper<Self::ToBeUnfrozen>;
+ // to ensure it can handle things when a generic type remains after normalization.
+ const WRAPPED_TO_BE_GENERIC_PARAM: Wrapper<Self::ToBeGenericParam>;
+}
+
+impl<T: ConstDefault> AssocTypes for Vec<T> {
+ type ToBeFrozen = u16;
+ type ToBeUnfrozen = AtomicUsize;
+ type ToBeGenericParam = T;
+
+ const TO_BE_FROZEN: Self::ToBeFrozen = 12;
+ const TO_BE_UNFROZEN: Self::ToBeUnfrozen = AtomicUsize::new(13); //~ ERROR interior mutable
+ const WRAPPED_TO_BE_UNFROZEN: Wrapper<Self::ToBeUnfrozen> = Wrapper(AtomicUsize::new(14)); //~ ERROR interior mutable
+ const WRAPPED_TO_BE_GENERIC_PARAM: Wrapper<Self::ToBeGenericParam> = Wrapper(T::DEFAULT);
+}
+
+// a helper trait used below
+trait AssocTypesHelper {
+ type NotToBeBounded;
+ type ToBeBounded;
+
+ const NOT_TO_BE_BOUNDED: Self::NotToBeBounded;
+}
+
+// a constant whose type is an assoc type originated from a generic param bounded at the definition
+// site should be linted at there.
+trait AssocTypesFromGenericParam<T>
+where
+ T: AssocTypesHelper<ToBeBounded = AtomicUsize>,
+{
+ const NOT_BOUNDED: T::NotToBeBounded;
+ const BOUNDED: T::ToBeBounded; //~ ERROR interior mutable
+}
+
+impl<T> AssocTypesFromGenericParam<T> for u64
+where
+ T: AssocTypesHelper<ToBeBounded = AtomicUsize>,
+{
+ // an associated type could remain unknown in a trait impl.
+ const NOT_BOUNDED: T::NotToBeBounded = T::NOT_TO_BE_BOUNDED;
+ const BOUNDED: T::ToBeBounded = AtomicUsize::new(15);
+}
+
+// a constant whose type is `Self` should be linted at the implementation site as well.
+// (`Option` requires `Sized` bound.)
+trait SelfType: Sized {
+ const SELF: Self;
+ // this was the one in the original issue (#5050).
+ const WRAPPED_SELF: Option<Self>;
+}
+
+impl SelfType for u64 {
+ const SELF: Self = 16;
+ const WRAPPED_SELF: Option<Self> = Some(20);
+}
+
+impl SelfType for AtomicUsize {
+ // this (interior mutable `Self` const) exists in `parking_lot`.
+ // `const_trait_impl` will replace it in the future, hopefully.
+ const SELF: Self = AtomicUsize::new(17); //~ ERROR interior mutable
+ const WRAPPED_SELF: Option<Self> = Some(AtomicUsize::new(21)); //~ ERROR interior mutable
+}
+
+// Even though a constant contains a generic type, if it also have a interior mutable type,
+// it should be linted at the definition site.
+trait BothOfCellAndGeneric<T> {
+ // this is a false negative in the current implementation.
+ const DIRECT: Cell<T>;
+ const INDIRECT: Cell<*const T>; //~ ERROR interior mutable
+}
+
+impl<T: ConstDefault> BothOfCellAndGeneric<T> for u64 {
+ const DIRECT: Cell<T> = Cell::new(T::DEFAULT);
+ const INDIRECT: Cell<*const T> = Cell::new(std::ptr::null());
+}
+
+struct Local<T>(T);
+
+// a constant in an inherent impl are essentially the same as a normal const item
+// except there can be a generic or associated type.
+impl<T> Local<T>
+where
+ T: ConstDefault + AssocTypesHelper<ToBeBounded = AtomicUsize>,
+{
+ const ATOMIC: AtomicUsize = AtomicUsize::new(18); //~ ERROR interior mutable
+ const COW: Cow<'static, str> = Cow::Borrowed("tuvwxy");
+
+ const GENERIC_TYPE: T = T::DEFAULT;
+
+ const ASSOC_TYPE: T::NotToBeBounded = T::NOT_TO_BE_BOUNDED;
+ const BOUNDED_ASSOC_TYPE: T::ToBeBounded = AtomicUsize::new(19); //~ ERROR interior mutable
+}
+
+fn main() {}
--- /dev/null
+error: a `const` item should never be interior mutable
+ --> $DIR/traits.rs:15:5
+ |
+LL | const ATOMIC: AtomicUsize; //~ ERROR interior mutable
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: `-D clippy::declare-interior-mutable-const` implied by `-D warnings`
+
+error: a `const` item should never be interior mutable
+ --> $DIR/traits.rs:9:9
+ |
+LL | const $name: $ty = $e;
+ | ^^^^^^^^^^^^^^^^^^^^^^
+...
+LL | declare_const!(ANOTHER_ATOMIC: AtomicUsize = Self::ATOMIC); //~ ERROR interior mutable
+ | ----------------------------------------------------------- in this macro invocation
+ |
+ = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: a `const` item should never be interior mutable
+ --> $DIR/traits.rs:43:5
+ |
+LL | const TO_BE_CONCRETE: AtomicUsize = AtomicUsize::new(11); //~ ERROR interior mutable
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: a `const` item should never be interior mutable
+ --> $DIR/traits.rs:68:5
+ |
+LL | const TO_BE_UNFROZEN: Self::ToBeUnfrozen = AtomicUsize::new(13); //~ ERROR interior mutable
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: a `const` item should never be interior mutable
+ --> $DIR/traits.rs:69:5
+ |
+LL | const WRAPPED_TO_BE_UNFROZEN: Wrapper<Self::ToBeUnfrozen> = Wrapper(AtomicUsize::new(14)); //~ ERROR interior mutable
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: a `const` item should never be interior mutable
+ --> $DIR/traits.rs:88:5
+ |
+LL | const BOUNDED: T::ToBeBounded; //~ ERROR interior mutable
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: a `const` item should never be interior mutable
+ --> $DIR/traits.rs:116:5
+ |
+LL | const SELF: Self = AtomicUsize::new(17); //~ ERROR interior mutable
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: a `const` item should never be interior mutable
+ --> $DIR/traits.rs:117:5
+ |
+LL | const WRAPPED_SELF: Option<Self> = Some(AtomicUsize::new(21)); //~ ERROR interior mutable
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: a `const` item should never be interior mutable
+ --> $DIR/traits.rs:125:5
+ |
+LL | const INDIRECT: Cell<*const T>; //~ ERROR interior mutable
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: a `const` item should never be interior mutable
+ --> $DIR/traits.rs:141:5
+ |
+LL | const ATOMIC: AtomicUsize = AtomicUsize::new(18); //~ ERROR interior mutable
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: a `const` item should never be interior mutable
+ --> $DIR/traits.rs:147:5
+ |
+LL | const BOUNDED_ASSOC_TYPE: T::ToBeBounded = AtomicUsize::new(19); //~ ERROR interior mutable
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 11 previous errors
+