use std::ptr;
+use clippy_utils::diagnostics::span_lint_and_then;
+use clippy_utils::in_constant;
+use if_chain::if_chain;
use rustc_hir::def::{DefKind, Res};
use rustc_hir::def_id::DefId;
use rustc_hir::{
use rustc_span::{InnerSpan, Span, DUMMY_SP};
use rustc_typeck::hir_ty_to_ty;
-use crate::utils::{in_constant, span_lint_and_then};
-use if_chain::if_chain;
-
// FIXME: this is a correctness problem but there's no suitable
// warn-by-default category.
declare_clippy_lint! {
- /// **What it does:** Checks for declaration of `const` items which is interior
+ /// ### What it does
+ /// Checks for declaration of `const` items which is interior
/// mutable (e.g., contains a `Cell`, `Mutex`, `AtomicXxxx`, etc.).
///
- /// **Why is this bad?** Consts are copied everywhere they are referenced, i.e.,
+ /// ### Why is this bad?
+ /// Consts are copied everywhere they are referenced, i.e.,
/// every time you refer to the const a fresh instance of the `Cell` or `Mutex`
/// or `AtomicXxxx` will be created, which defeats the whole purpose of using
/// these types in the first place.
/// The `const` should better be replaced by a `static` item if a global
/// variable is wanted, or replaced by a `const fn` if a constructor is wanted.
///
- /// **Known problems:** A "non-constant" const item is a legacy way to supply an
+ /// ### Known problems
+ /// A "non-constant" const item is a legacy way to supply an
/// initialized value to downstream `static` items (e.g., the
/// `std::sync::ONCE_INIT` constant). In this case the use of `const` is legit,
/// and this lint should be suppressed.
/// the interior mutable field is used or not. See issues
/// [#5812](https://github.com/rust-lang/rust-clippy/issues/5812) and
///
- /// **Example:**
+ /// ### Example
/// ```rust
/// use std::sync::atomic::{AtomicUsize, Ordering::SeqCst};
///
// FIXME: this is a correctness problem but there's no suitable
// warn-by-default category.
declare_clippy_lint! {
- /// **What it does:** Checks if `const` items which is interior mutable (e.g.,
+ /// ### What it does
+ /// Checks if `const` items which is interior mutable (e.g.,
/// contains a `Cell`, `Mutex`, `AtomicXxxx`, etc.) has been borrowed directly.
///
- /// **Why is this bad?** Consts are copied everywhere they are referenced, i.e.,
+ /// ### Why is this bad?
+ /// Consts are copied everywhere they are referenced, i.e.,
/// every time you refer to the const a fresh instance of the `Cell` or `Mutex`
/// or `AtomicXxxx` will be created, which defeats the whole purpose of using
/// these types in the first place.
///
/// The `const` value should be stored inside a `static` item.
///
- /// **Known problems:** When an enum has variants with interior mutability, use of its non
+ /// ### Known problems
+ /// When an enum has variants with interior mutability, use of its non
/// interior mutable variants can generate false positives. See issue
/// [#3962](https://github.com/rust-lang/rust-clippy/issues/3962)
///
/// [#5812](https://github.com/rust-lang/rust-clippy/issues/5812) and
/// [#3825](https://github.com/rust-lang/rust-clippy/issues/3825)
///
- /// **Example:**
+ /// ### Example
/// ```rust
/// use std::sync::atomic::{AtomicUsize, Ordering::SeqCst};
/// const CONST_ATOM: AtomicUsize = AtomicUsize::new(12);
fn is_value_unfrozen_expr<'tcx>(cx: &LateContext<'tcx>, hir_id: HirId, def_id: DefId, ty: Ty<'tcx>) -> bool {
let substs = cx.typeck_results().node_substs(hir_id);
- let result = cx
- .tcx
- .const_eval_resolve(cx.param_env, ty::WithOptConstParam::unknown(def_id), substs, None, None);
+ let result = cx.tcx.const_eval_resolve(
+ cx.param_env,
+ ty::Unevaluated {
+ def: ty::WithOptConstParam::unknown(def_id),
+ substs,
+ promoted: None,
+ },
+ None,
+ );
is_value_unfrozen_raw(cx, result, ty)
}
fn check_impl_item(&mut self, cx: &LateContext<'tcx>, impl_item: &'tcx ImplItem<'_>) {
if let ImplItemKind::Const(hir_ty, body_id) = &impl_item.kind {
- let item_hir_id = cx.tcx.hir().get_parent_node(impl_item.hir_id);
+ let item_hir_id = cx.tcx.hir().get_parent_node(impl_item.hir_id());
let item = cx.tcx.hir().expect_item(item_hir_id);
match &item.kind {
// we should use here as a frozen variant is a potential to be frozen
// similar to unknown layouts.
// e.g. `layout_of(...).is_err() || has_frozen_variant(...);`
+ let ty = hir_ty_to_ty(cx.tcx, hir_ty);
+ let normalized = cx.tcx.normalize_erasing_regions(cx.param_env, ty);
+ if is_unfrozen(cx, normalized);
+ if is_value_unfrozen_poly(cx, *body_id, normalized);
then {
- let ty = hir_ty_to_ty(cx.tcx, hir_ty);
- let normalized = cx.tcx.normalize_erasing_regions(cx.param_env, ty);
- if is_unfrozen(cx, normalized)
- && is_value_unfrozen_poly(cx, *body_id, normalized)
- {
- lint(
- cx,
- Source::Assoc {
- item: impl_item.span,
- },
- );
- }
+ lint(
+ cx,
+ Source::Assoc {
+ item: impl_item.span,
+ },
+ );
}
}
},