summaryrefslogtreecommitdiffstats
path: root/src/tools/clippy/tests/ui/declare_interior_mutable_const
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools/clippy/tests/ui/declare_interior_mutable_const')
-rw-r--r--src/tools/clippy/tests/ui/declare_interior_mutable_const/enums.rs123
-rw-r--r--src/tools/clippy/tests/ui/declare_interior_mutable_const/enums.stderr89
-rw-r--r--src/tools/clippy/tests/ui/declare_interior_mutable_const/others.rs55
-rw-r--r--src/tools/clippy/tests/ui/declare_interior_mutable_const/others.stderr50
-rw-r--r--src/tools/clippy/tests/ui/declare_interior_mutable_const/traits.rs150
-rw-r--r--src/tools/clippy/tests/ui/declare_interior_mutable_const/traits.stderr75
6 files changed, 542 insertions, 0 deletions
diff --git a/src/tools/clippy/tests/ui/declare_interior_mutable_const/enums.rs b/src/tools/clippy/tests/ui/declare_interior_mutable_const/enums.rs
new file mode 100644
index 000000000..f44518694
--- /dev/null
+++ b/src/tools/clippy/tests/ui/declare_interior_mutable_const/enums.rs
@@ -0,0 +1,123 @@
+#![warn(clippy::declare_interior_mutable_const)]
+
+use std::cell::Cell;
+use std::sync::atomic::AtomicUsize;
+
+enum OptionalCell {
+ Unfrozen(Cell<bool>),
+ Frozen,
+}
+
+// a constant with enums should be linted only when the used variant is unfrozen (#3962).
+const UNFROZEN_VARIANT: OptionalCell = OptionalCell::Unfrozen(Cell::new(true)); //~ ERROR interior mutable
+const FROZEN_VARIANT: OptionalCell = OptionalCell::Frozen;
+
+const fn unfrozen_variant() -> OptionalCell {
+ OptionalCell::Unfrozen(Cell::new(false))
+}
+
+const fn frozen_variant() -> OptionalCell {
+ OptionalCell::Frozen
+}
+
+const UNFROZEN_VARIANT_FROM_FN: OptionalCell = unfrozen_variant(); //~ ERROR interior mutable
+const FROZEN_VARIANT_FROM_FN: OptionalCell = frozen_variant();
+
+enum NestedInnermost {
+ Unfrozen(AtomicUsize),
+ Frozen,
+}
+
+struct NestedInner {
+ inner: NestedInnermost,
+}
+
+enum NestedOuter {
+ NestedInner(NestedInner),
+ NotNested(usize),
+}
+
+struct NestedOutermost {
+ outer: NestedOuter,
+}
+
+// a constant with enums should be linted according to its value, no matter how structs involve.
+const NESTED_UNFROZEN_VARIANT: NestedOutermost = NestedOutermost {
+ outer: NestedOuter::NestedInner(NestedInner {
+ inner: NestedInnermost::Unfrozen(AtomicUsize::new(2)),
+ }),
+}; //~ ERROR interior mutable
+const NESTED_FROZEN_VARIANT: NestedOutermost = NestedOutermost {
+ outer: NestedOuter::NestedInner(NestedInner {
+ inner: NestedInnermost::Frozen,
+ }),
+};
+
+trait AssocConsts {
+ // When there's no default value, lint it only according to its type.
+ // Further details are on the corresponding code (`NonCopyConst::check_trait_item`).
+ const TO_BE_UNFROZEN_VARIANT: OptionalCell; //~ ERROR interior mutable
+ const TO_BE_FROZEN_VARIANT: OptionalCell; //~ ERROR interior mutable
+
+ // Lint default values accordingly.
+ const DEFAULTED_ON_UNFROZEN_VARIANT: OptionalCell = OptionalCell::Unfrozen(Cell::new(false)); //~ ERROR interior mutable
+ const DEFAULTED_ON_FROZEN_VARIANT: OptionalCell = OptionalCell::Frozen;
+}
+
+// The lint doesn't trigger for an assoc constant in a trait impl with an unfrozen type even if it
+// has enums. Further details are on the corresponding code in 'NonCopyConst::check_impl_item'.
+impl AssocConsts for u64 {
+ const TO_BE_UNFROZEN_VARIANT: OptionalCell = OptionalCell::Unfrozen(Cell::new(false));
+ const TO_BE_FROZEN_VARIANT: OptionalCell = OptionalCell::Frozen;
+
+ // even if this sets an unfrozen variant, the lint ignores it.
+ const DEFAULTED_ON_FROZEN_VARIANT: OptionalCell = OptionalCell::Unfrozen(Cell::new(false));
+}
+
+// At first, I thought I'd need to check every patterns in `trait.rs`; but, what matters
+// here are values; and I think substituted generics at definitions won't appear in MIR.
+trait AssocTypes {
+ type ToBeUnfrozen;
+
+ const TO_BE_UNFROZEN_VARIANT: Option<Self::ToBeUnfrozen>;
+ const TO_BE_FROZEN_VARIANT: Option<Self::ToBeUnfrozen>;
+}
+
+impl AssocTypes for u64 {
+ type ToBeUnfrozen = AtomicUsize;
+
+ const TO_BE_UNFROZEN_VARIANT: Option<Self::ToBeUnfrozen> = Some(Self::ToBeUnfrozen::new(4)); //~ ERROR interior mutable
+ const TO_BE_FROZEN_VARIANT: Option<Self::ToBeUnfrozen> = None;
+}
+
+// Use raw pointers since direct generics have a false negative at the type level.
+enum BothOfCellAndGeneric<T> {
+ Unfrozen(Cell<*const T>),
+ Generic(*const T),
+ Frozen(usize),
+}
+
+impl<T> BothOfCellAndGeneric<T> {
+ const UNFROZEN_VARIANT: BothOfCellAndGeneric<T> = BothOfCellAndGeneric::Unfrozen(Cell::new(std::ptr::null())); //~ ERROR interior mutable
+
+ // This is a false positive. The argument about this is on `is_value_unfrozen_raw`
+ const GENERIC_VARIANT: BothOfCellAndGeneric<T> = BothOfCellAndGeneric::Generic(std::ptr::null()); //~ ERROR interior mutable
+
+ const FROZEN_VARIANT: BothOfCellAndGeneric<T> = BothOfCellAndGeneric::Frozen(5);
+
+ // This is what is likely to be a false negative when one tries to fix
+ // the `GENERIC_VARIANT` false positive.
+ const NO_ENUM: Cell<*const T> = Cell::new(std::ptr::null()); //~ ERROR interior mutable
+}
+
+// associated types here is basically the same as the one above.
+trait BothOfCellAndGenericWithAssocType {
+ type AssocType;
+
+ const UNFROZEN_VARIANT: BothOfCellAndGeneric<Self::AssocType> =
+ BothOfCellAndGeneric::Unfrozen(Cell::new(std::ptr::null())); //~ ERROR interior mutable
+ const GENERIC_VARIANT: BothOfCellAndGeneric<Self::AssocType> = BothOfCellAndGeneric::Generic(std::ptr::null()); //~ ERROR interior mutable
+ const FROZEN_VARIANT: BothOfCellAndGeneric<Self::AssocType> = BothOfCellAndGeneric::Frozen(5);
+}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui/declare_interior_mutable_const/enums.stderr b/src/tools/clippy/tests/ui/declare_interior_mutable_const/enums.stderr
new file mode 100644
index 000000000..84198d546
--- /dev/null
+++ b/src/tools/clippy/tests/ui/declare_interior_mutable_const/enums.stderr
@@ -0,0 +1,89 @@
+error: a `const` item should never be interior mutable
+ --> $DIR/enums.rs:12:1
+ |
+LL | const UNFROZEN_VARIANT: OptionalCell = OptionalCell::Unfrozen(Cell::new(true)); //~ 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/enums.rs:23:1
+ |
+LL | const UNFROZEN_VARIANT_FROM_FN: OptionalCell = unfrozen_variant(); //~ ERROR interior mutable
+ | -----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | |
+ | make this a static item (maybe with lazy_static)
+
+error: a `const` item should never be interior mutable
+ --> $DIR/enums.rs:45:1
+ |
+LL | const NESTED_UNFROZEN_VARIANT: NestedOutermost = NestedOutermost {
+ | ^----
+ | |
+ | _make this a static item (maybe with lazy_static)
+ | |
+LL | | outer: NestedOuter::NestedInner(NestedInner {
+LL | | inner: NestedInnermost::Unfrozen(AtomicUsize::new(2)),
+LL | | }),
+LL | | }; //~ ERROR interior mutable
+ | |__^
+
+error: a `const` item should never be interior mutable
+ --> $DIR/enums.rs:59:5
+ |
+LL | const TO_BE_UNFROZEN_VARIANT: OptionalCell; //~ ERROR interior mutable
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: a `const` item should never be interior mutable
+ --> $DIR/enums.rs:60:5
+ |
+LL | const TO_BE_FROZEN_VARIANT: OptionalCell; //~ ERROR interior mutable
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: a `const` item should never be interior mutable
+ --> $DIR/enums.rs:63:5
+ |
+LL | const DEFAULTED_ON_UNFROZEN_VARIANT: OptionalCell = OptionalCell::Unfrozen(Cell::new(false)); //~ ERROR interior mutable
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: a `const` item should never be interior mutable
+ --> $DIR/enums.rs:89:5
+ |
+LL | const TO_BE_UNFROZEN_VARIANT: Option<Self::ToBeUnfrozen> = Some(Self::ToBeUnfrozen::new(4)); //~ ERROR interior mutable
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: a `const` item should never be interior mutable
+ --> $DIR/enums.rs:101:5
+ |
+LL | const UNFROZEN_VARIANT: BothOfCellAndGeneric<T> = BothOfCellAndGeneric::Unfrozen(Cell::new(std::ptr::null())); //~ ERROR interior mut...
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: a `const` item should never be interior mutable
+ --> $DIR/enums.rs:104:5
+ |
+LL | const GENERIC_VARIANT: BothOfCellAndGeneric<T> = BothOfCellAndGeneric::Generic(std::ptr::null()); //~ ERROR interior mutable
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: a `const` item should never be interior mutable
+ --> $DIR/enums.rs:110:5
+ |
+LL | const NO_ENUM: Cell<*const T> = Cell::new(std::ptr::null()); //~ ERROR interior mutable
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: a `const` item should never be interior mutable
+ --> $DIR/enums.rs:117:5
+ |
+LL | / const UNFROZEN_VARIANT: BothOfCellAndGeneric<Self::AssocType> =
+LL | | BothOfCellAndGeneric::Unfrozen(Cell::new(std::ptr::null())); //~ ERROR interior mutable
+ | |____________________________________________________________________^
+
+error: a `const` item should never be interior mutable
+ --> $DIR/enums.rs:119:5
+ |
+LL | const GENERIC_VARIANT: BothOfCellAndGeneric<Self::AssocType> = BothOfCellAndGeneric::Generic(std::ptr::null()); //~ ERROR interior mu...
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 12 previous errors
+
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
new file mode 100644
index 000000000..896596b56
--- /dev/null
+++ b/src/tools/clippy/tests/ui/declare_interior_mutable_const/others.rs
@@ -0,0 +1,55 @@
+#![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
+
+mod issue_8493 {
+ use std::cell::Cell;
+
+ thread_local! {
+ static _BAR: Cell<i32> = const { Cell::new(0) };
+ }
+
+ macro_rules! issue_8493 {
+ () => {
+ const _BAZ: Cell<usize> = Cell::new(0); //~ ERROR interior mutable
+ static _FOOBAR: () = {
+ thread_local! {
+ static _VAR: Cell<i32> = const { Cell::new(0) };
+ }
+ };
+ };
+ }
+
+ issue_8493!();
+}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui/declare_interior_mutable_const/others.stderr b/src/tools/clippy/tests/ui/declare_interior_mutable_const/others.stderr
new file mode 100644
index 000000000..1fd6d7322
--- /dev/null
+++ b/src/tools/clippy/tests/ui/declare_interior_mutable_const/others.stderr
@@ -0,0 +1,50 @@
+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 the macro `declare_const` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: a `const` item should never be interior mutable
+ --> $DIR/others.rs:43:13
+ |
+LL | const _BAZ: Cell<usize> = Cell::new(0); //~ ERROR interior mutable
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+...
+LL | issue_8493!();
+ | ------------- in this macro invocation
+ |
+ = note: this error originates in the macro `issue_8493` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 5 previous errors
+
diff --git a/src/tools/clippy/tests/ui/declare_interior_mutable_const/traits.rs b/src/tools/clippy/tests/ui/declare_interior_mutable_const/traits.rs
new file mode 100644
index 000000000..256a336db
--- /dev/null
+++ b/src/tools/clippy/tests/ui/declare_interior_mutable_const/traits.rs
@@ -0,0 +1,150 @@
+#![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 an 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() {}
diff --git a/src/tools/clippy/tests/ui/declare_interior_mutable_const/traits.stderr b/src/tools/clippy/tests/ui/declare_interior_mutable_const/traits.stderr
new file mode 100644
index 000000000..7debe059f
--- /dev/null
+++ b/src/tools/clippy/tests/ui/declare_interior_mutable_const/traits.stderr
@@ -0,0 +1,75 @@
+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 the macro `declare_const` (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
+