Rollup merge of #150166 - Urgau:const-item-lint-150157, r=Kivooeo
Don't lint on interior mutable `const` item coming from derefs This PR fixes the `const_item_interior_mutations` lint so we don't lint on interior mutable `const` item coming from derefs. Fixes https://github.com/rust-lang/rust/issues/150157
This commit is contained in:
commit
a65fa4a357
2 changed files with 36 additions and 0 deletions
|
|
@ -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),
|
||||
|
|
|
|||
28
tests/ui/lint/const-item-interior-mutations-const-deref.rs
Normal file
28
tests/ui/lint/const-item-interior-mutations-const-deref.rs
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
// Regression test for <https://github.com/rust-lang/rust/issues/150157>
|
||||
//
|
||||
// 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<T> {
|
||||
inner: T,
|
||||
}
|
||||
|
||||
impl<T> Deref for LocalKey<T> {
|
||||
type Target = T;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.inner
|
||||
}
|
||||
}
|
||||
|
||||
const LOCAL_COUNT: LocalKey<Cell<usize>> = LocalKey { inner: Cell::new(8) };
|
||||
|
||||
fn main() {
|
||||
let count = LOCAL_COUNT.get();
|
||||
LOCAL_COUNT.set(count);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue