#![deny(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 mutability 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 mutability let _ = &Self::STRING; } } // a helper trait used below trait ConstDefault { const DEFAULT: Self; } trait GenericTypes { const TO_REMAIN_GENERIC: T; const TO_BE_CONCRETE: U; fn function() { let _ = &Self::TO_REMAIN_GENERIC; } } impl GenericTypes for Vec { 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 mutability } } // a helper type used below pub struct Wrapper(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; const WRAPPED_TO_BE_GENERIC_PARAM: Wrapper; fn function() { let _ = &Self::TO_BE_FROZEN; let _ = &Self::WRAPPED_TO_BE_UNFROZEN; } } impl AssocTypes for Vec { 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 = Wrapper(AtomicUsize::new(14)); const WRAPPED_TO_BE_GENERIC_PARAM: Wrapper = Wrapper(T::DEFAULT); fn function() { let _ = &Self::TO_BE_FROZEN; let _ = &Self::TO_BE_UNFROZEN; //~ ERROR: interior mutability let _ = &Self::WRAPPED_TO_BE_UNFROZEN; //~ ERROR: interior mutability 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 where T: AssocTypesHelper, { const NOT_BOUNDED: T::NotToBeBounded; const BOUNDED: T::ToBeBounded; fn function() { let _ = &Self::NOT_BOUNDED; let _ = &Self::BOUNDED; //~ ERROR: interior mutability } } impl AssocTypesFromGenericParam for Vec where T: AssocTypesHelper, { 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 mutability } } trait SelfType: Sized { const SELF: Self; const WRAPPED_SELF: Option; fn function() { let _ = &Self::SELF; let _ = &Self::WRAPPED_SELF; } } impl SelfType for u64 { const SELF: Self = 16; const WRAPPED_SELF: Option = 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 = Some(AtomicUsize::new(21)); fn function() { let _ = &Self::SELF; //~ ERROR: interior mutability let _ = &Self::WRAPPED_SELF; //~ ERROR: interior mutability } } trait BothOfCellAndGeneric { const DIRECT: Cell; const INDIRECT: Cell<*const T>; fn function() { let _ = &Self::DIRECT; //~ ERROR: interior mutability let _ = &Self::INDIRECT; //~ ERROR: interior mutability } } impl BothOfCellAndGeneric for Vec { const DIRECT: Cell = Cell::new(T::DEFAULT); const INDIRECT: Cell<*const T> = Cell::new(std::ptr::null()); fn function() { let _ = &Self::DIRECT; //~ ERROR: interior mutability let _ = &Self::INDIRECT; //~ ERROR: interior mutability } } struct Local(T); impl Local where T: ConstDefault + AssocTypesHelper, { 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 mutability let _ = &Self::COW; let _ = &Self::GENERIC_TYPE; let _ = &Self::ASSOC_TYPE; let _ = &Self::BOUNDED_ASSOC_TYPE; //~ ERROR: interior mutability } } fn main() { u64::ATOMIC.store(5, Ordering::SeqCst); //~ ERROR: interior mutability assert_eq!(u64::ATOMIC.load(Ordering::SeqCst), 9); //~ ERROR: interior mutability }