From 0bc29cec45412ee3cc68a1ef1556814885543d55 Mon Sep 17 00:00:00 2001 From: Urgau Date: Fri, 19 Dec 2025 17:55:19 +0100 Subject: [PATCH 1/2] Add regression test for `const_item_interior_mutations` deref FP --- ...nst-item-interior-mutations-const-deref.rs | 30 +++++++++++++++ ...item-interior-mutations-const-deref.stderr | 37 +++++++++++++++++++ 2 files changed, 67 insertions(+) create mode 100644 tests/ui/lint/const-item-interior-mutations-const-deref.rs create mode 100644 tests/ui/lint/const-item-interior-mutations-const-deref.stderr diff --git a/tests/ui/lint/const-item-interior-mutations-const-deref.rs b/tests/ui/lint/const-item-interior-mutations-const-deref.rs new file mode 100644 index 0000000000000..ce684abacccd7 --- /dev/null +++ b/tests/ui/lint/const-item-interior-mutations-const-deref.rs @@ -0,0 +1,30 @@ +// Regression test for +// +// We shouldn't lint on user types, including through deref. + +//@ check-pass + +use std::cell::Cell; +use std::ops::Deref; + +// Cut down version of the issue reproducer without the thread local to just a Deref +pub struct LocalKey { + inner: T, +} + +impl Deref for LocalKey { + type Target = T; + + fn deref(&self) -> &Self::Target { + &self.inner + } +} + +const LOCAL_COUNT: LocalKey> = LocalKey { inner: Cell::new(8) }; + +fn main() { + let count = LOCAL_COUNT.get(); + //~^ WARN mutation of an interior mutable `const` + LOCAL_COUNT.set(count); + //~^ WARN mutation of an interior mutable `const` +} diff --git a/tests/ui/lint/const-item-interior-mutations-const-deref.stderr b/tests/ui/lint/const-item-interior-mutations-const-deref.stderr new file mode 100644 index 0000000000000..35696d0ba100a --- /dev/null +++ b/tests/ui/lint/const-item-interior-mutations-const-deref.stderr @@ -0,0 +1,37 @@ +warning: mutation of an interior mutable `const` item with call to `get` + --> $DIR/const-item-interior-mutations-const-deref.rs:26:17 + | +LL | let count = LOCAL_COUNT.get(); + | -----------^^^^^^ + | | + | `LOCAL_COUNT` is a interior mutable `const` item of type `LocalKey>` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const LOCAL_COUNT` will be modified + = help: for more details on interior mutability see + = note: `#[warn(const_item_interior_mutations)]` on by default +help: for a shared instance of `LOCAL_COUNT`, consider making it a `static` item instead + | +LL - const LOCAL_COUNT: LocalKey> = LocalKey { inner: Cell::new(8) }; +LL + static LOCAL_COUNT: LocalKey> = LocalKey { inner: Cell::new(8) }; + | + +warning: mutation of an interior mutable `const` item with call to `set` + --> $DIR/const-item-interior-mutations-const-deref.rs:28:5 + | +LL | LOCAL_COUNT.set(count); + | -----------^^^^^^^^^^^ + | | + | `LOCAL_COUNT` is a interior mutable `const` item of type `LocalKey>` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const LOCAL_COUNT` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `LOCAL_COUNT`, consider making it a `static` item instead + | +LL - const LOCAL_COUNT: LocalKey> = LocalKey { inner: Cell::new(8) }; +LL + static LOCAL_COUNT: LocalKey> = LocalKey { inner: Cell::new(8) }; + | + +warning: 2 warnings emitted + From 2581c2571c904c180ec8dc2b0242413a5b251358 Mon Sep 17 00:00:00 2001 From: Urgau Date: Fri, 19 Dec 2025 18:13:07 +0100 Subject: [PATCH 2/2] Don't lint on interior mutable `const` item coming from derefs --- .../rustc_lint/src/interior_mutable_consts.rs | 8 ++++ ...nst-item-interior-mutations-const-deref.rs | 2 - ...item-interior-mutations-const-deref.stderr | 37 ------------------- 3 files changed, 8 insertions(+), 39 deletions(-) delete mode 100644 tests/ui/lint/const-item-interior-mutations-const-deref.stderr diff --git a/compiler/rustc_lint/src/interior_mutable_consts.rs b/compiler/rustc_lint/src/interior_mutable_consts.rs index 8576698dec33e..4c7d2c6af93b1 100644 --- a/compiler/rustc_lint/src/interior_mutable_consts.rs +++ b/compiler/rustc_lint/src/interior_mutable_consts.rs @@ -1,6 +1,7 @@ use rustc_hir::attrs::AttributeKind; use rustc_hir::def::{DefKind, Res}; use rustc_hir::{Expr, ExprKind, ItemKind, Node, find_attr}; +use rustc_middle::ty::adjustment::Adjust; use rustc_session::{declare_lint, declare_lint_pass}; use crate::lints::{ConstItemInteriorMutationsDiag, ConstItemInteriorMutationsSuggestionStatic}; @@ -77,6 +78,13 @@ impl<'tcx> LateLintPass<'tcx> for InteriorMutableConsts { if let ExprKind::Path(qpath) = &receiver.kind && let Res::Def(DefKind::Const | DefKind::AssocConst, const_did) = typeck.qpath_res(qpath, receiver.hir_id) + // Don't consider derefs as those can do arbitrary things + // like using thread local (see rust-lang/rust#150157) + && !cx + .typeck_results() + .expr_adjustments(receiver) + .into_iter() + .any(|adj| matches!(adj.kind, Adjust::Deref(_))) // Let's do the attribute check after the other checks for perf reasons && find_attr!( cx.tcx.get_all_attrs(method_did), diff --git a/tests/ui/lint/const-item-interior-mutations-const-deref.rs b/tests/ui/lint/const-item-interior-mutations-const-deref.rs index ce684abacccd7..021e0952da704 100644 --- a/tests/ui/lint/const-item-interior-mutations-const-deref.rs +++ b/tests/ui/lint/const-item-interior-mutations-const-deref.rs @@ -24,7 +24,5 @@ const LOCAL_COUNT: LocalKey> = LocalKey { inner: Cell::new(8) }; fn main() { let count = LOCAL_COUNT.get(); - //~^ WARN mutation of an interior mutable `const` LOCAL_COUNT.set(count); - //~^ WARN mutation of an interior mutable `const` } diff --git a/tests/ui/lint/const-item-interior-mutations-const-deref.stderr b/tests/ui/lint/const-item-interior-mutations-const-deref.stderr deleted file mode 100644 index 35696d0ba100a..0000000000000 --- a/tests/ui/lint/const-item-interior-mutations-const-deref.stderr +++ /dev/null @@ -1,37 +0,0 @@ -warning: mutation of an interior mutable `const` item with call to `get` - --> $DIR/const-item-interior-mutations-const-deref.rs:26:17 - | -LL | let count = LOCAL_COUNT.get(); - | -----------^^^^^^ - | | - | `LOCAL_COUNT` is a interior mutable `const` item of type `LocalKey>` - | - = note: each usage of a `const` item creates a new temporary - = note: only the temporaries and never the original `const LOCAL_COUNT` will be modified - = help: for more details on interior mutability see - = note: `#[warn(const_item_interior_mutations)]` on by default -help: for a shared instance of `LOCAL_COUNT`, consider making it a `static` item instead - | -LL - const LOCAL_COUNT: LocalKey> = LocalKey { inner: Cell::new(8) }; -LL + static LOCAL_COUNT: LocalKey> = LocalKey { inner: Cell::new(8) }; - | - -warning: mutation of an interior mutable `const` item with call to `set` - --> $DIR/const-item-interior-mutations-const-deref.rs:28:5 - | -LL | LOCAL_COUNT.set(count); - | -----------^^^^^^^^^^^ - | | - | `LOCAL_COUNT` is a interior mutable `const` item of type `LocalKey>` - | - = note: each usage of a `const` item creates a new temporary - = note: only the temporaries and never the original `const LOCAL_COUNT` will be modified - = help: for more details on interior mutability see -help: for a shared instance of `LOCAL_COUNT`, consider making it a `static` item instead - | -LL - const LOCAL_COUNT: LocalKey> = LocalKey { inner: Cell::new(8) }; -LL + static LOCAL_COUNT: LocalKey> = LocalKey { inner: Cell::new(8) }; - | - -warning: 2 warnings emitted -