Require the constness
query to only be invoked on things that can have constness
This commit is contained in:
parent
3d0bf68625
commit
c0e0d8f874
6 changed files with 66 additions and 13 deletions
|
@ -18,9 +18,7 @@ fn constness(tcx: TyCtxt<'_>, def_id: LocalDefId) -> hir::Constness {
|
||||||
let node = tcx.hir_node_by_def_id(def_id);
|
let node = tcx.hir_node_by_def_id(def_id);
|
||||||
|
|
||||||
match node {
|
match node {
|
||||||
hir::Node::Ctor(_)
|
hir::Node::Ctor(hir::VariantData::Tuple(..))
|
||||||
| hir::Node::AnonConst(_)
|
|
||||||
| hir::Node::ConstBlock(_)
|
|
||||||
| hir::Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Const(..), .. }) => {
|
| hir::Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Const(..), .. }) => {
|
||||||
hir::Constness::Const
|
hir::Constness::Const
|
||||||
}
|
}
|
||||||
|
@ -41,7 +39,10 @@ fn constness(tcx: TyCtxt<'_>, def_id: LocalDefId) -> hir::Constness {
|
||||||
let is_const = is_parent_const_impl_raw(tcx, def_id);
|
let is_const = is_parent_const_impl_raw(tcx, def_id);
|
||||||
if is_const { hir::Constness::Const } else { hir::Constness::NotConst }
|
if is_const { hir::Constness::Const } else { hir::Constness::NotConst }
|
||||||
} else {
|
} else {
|
||||||
hir::Constness::NotConst
|
tcx.dcx().span_bug(
|
||||||
|
tcx.def_span(def_id),
|
||||||
|
format!("should not be requesting the constness of items that can't be const: {node:#?}: {:?}", tcx.def_kind(def_id))
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4044,9 +4044,7 @@ impl<'hir> Node<'hir> {
|
||||||
_ => None,
|
_ => None,
|
||||||
},
|
},
|
||||||
Node::TraitItem(ti) => match ti.kind {
|
Node::TraitItem(ti) => match ti.kind {
|
||||||
TraitItemKind::Fn(ref sig, TraitFn::Provided(_)) => {
|
TraitItemKind::Fn(ref sig, _) => Some(FnKind::Method(ti.ident, sig)),
|
||||||
Some(FnKind::Method(ti.ident, sig))
|
|
||||||
}
|
|
||||||
_ => None,
|
_ => None,
|
||||||
},
|
},
|
||||||
Node::ImplItem(ii) => match ii.kind {
|
Node::ImplItem(ii) => match ii.kind {
|
||||||
|
|
|
@ -1268,8 +1268,7 @@ fn should_encode_constness(def_kind: DefKind) -> bool {
|
||||||
| DefKind::AssocFn
|
| DefKind::AssocFn
|
||||||
| DefKind::Closure
|
| DefKind::Closure
|
||||||
| DefKind::Impl { of_trait: true }
|
| DefKind::Impl { of_trait: true }
|
||||||
| DefKind::Variant
|
| DefKind::Ctor(_, CtorKind::Fn) => true,
|
||||||
| DefKind::Ctor(..) => true,
|
|
||||||
|
|
||||||
DefKind::Struct
|
DefKind::Struct
|
||||||
| DefKind::Union
|
| DefKind::Union
|
||||||
|
@ -1296,6 +1295,8 @@ fn should_encode_constness(def_kind: DefKind) -> bool {
|
||||||
| DefKind::LifetimeParam
|
| DefKind::LifetimeParam
|
||||||
| DefKind::GlobalAsm
|
| DefKind::GlobalAsm
|
||||||
| DefKind::ExternCrate
|
| DefKind::ExternCrate
|
||||||
|
| DefKind::Ctor(_, CtorKind::Const)
|
||||||
|
| DefKind::Variant
|
||||||
| DefKind::SyntheticCoroutineBody => false,
|
| DefKind::SyntheticCoroutineBody => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -746,7 +746,9 @@ rustc_queries! {
|
||||||
desc { |tcx| "computing drop-check constraints for `{}`", tcx.def_path_str(key) }
|
desc { |tcx| "computing drop-check constraints for `{}`", tcx.def_path_str(key) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `true` if this is a const fn / const impl.
|
/// Returns the constness of functions and impls.
|
||||||
|
///
|
||||||
|
/// Will ICE if used on things that are always const or never const.
|
||||||
///
|
///
|
||||||
/// **Do not call this function manually.** It is only meant to cache the base data for the
|
/// **Do not call this function manually.** It is only meant to cache the base data for the
|
||||||
/// higher-level functions. Consider using `is_const_fn` or `is_const_trait_impl` instead.
|
/// higher-level functions. Consider using `is_const_fn` or `is_const_trait_impl` instead.
|
||||||
|
|
|
@ -2014,7 +2014,17 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||||
self.constness(def_id) == hir::Constness::Const
|
self.constness(def_id) == hir::Constness::Const
|
||||||
}
|
}
|
||||||
DefKind::Trait => self.is_const_trait(def_id),
|
DefKind::Trait => self.is_const_trait(def_id),
|
||||||
DefKind::AssocTy | DefKind::AssocFn => {
|
DefKind::AssocTy => {
|
||||||
|
let parent_def_id = self.parent(def_id);
|
||||||
|
match self.def_kind(parent_def_id) {
|
||||||
|
DefKind::Impl { of_trait: false } => false,
|
||||||
|
DefKind::Impl { of_trait: true } | DefKind::Trait => {
|
||||||
|
self.is_conditionally_const(parent_def_id)
|
||||||
|
}
|
||||||
|
_ => bug!("unexpected parent item of associated type: {parent_def_id:?}"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DefKind::AssocFn => {
|
||||||
let parent_def_id = self.parent(def_id);
|
let parent_def_id = self.parent(def_id);
|
||||||
match self.def_kind(parent_def_id) {
|
match self.def_kind(parent_def_id) {
|
||||||
DefKind::Impl { of_trait: false } => {
|
DefKind::Impl { of_trait: false } => {
|
||||||
|
@ -2023,7 +2033,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||||
DefKind::Impl { of_trait: true } | DefKind::Trait => {
|
DefKind::Impl { of_trait: true } | DefKind::Trait => {
|
||||||
self.is_conditionally_const(parent_def_id)
|
self.is_conditionally_const(parent_def_id)
|
||||||
}
|
}
|
||||||
_ => bug!("unexpected parent item of associated item: {parent_def_id:?}"),
|
_ => bug!("unexpected parent item of associated fn: {parent_def_id:?}"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DefKind::OpaqueTy => match self.opaque_ty_origin(def_id) {
|
DefKind::OpaqueTy => match self.opaque_ty_origin(def_id) {
|
||||||
|
|
|
@ -6,8 +6,11 @@ use clippy_utils::source::SpanRangeExt;
|
||||||
use clippy_utils::{is_from_proc_macro, path_to_local};
|
use clippy_utils::{is_from_proc_macro, path_to_local};
|
||||||
use rustc_errors::Applicability;
|
use rustc_errors::Applicability;
|
||||||
use rustc_hir::{BinOpKind, Constness, Expr, ExprKind};
|
use rustc_hir::{BinOpKind, Constness, Expr, ExprKind};
|
||||||
|
use rustc_hir::def::DefKind;
|
||||||
|
use rustc_hir::def_id::DefId;
|
||||||
use rustc_lint::{LateContext, LateLintPass, Lint, LintContext};
|
use rustc_lint::{LateContext, LateLintPass, Lint, LintContext};
|
||||||
use rustc_middle::lint::in_external_macro;
|
use rustc_middle::lint::in_external_macro;
|
||||||
|
use rustc_middle::ty::TyCtxt;
|
||||||
use rustc_session::impl_lint_pass;
|
use rustc_session::impl_lint_pass;
|
||||||
|
|
||||||
declare_clippy_lint! {
|
declare_clippy_lint! {
|
||||||
|
@ -94,6 +97,44 @@ impl ManualFloatMethods {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn is_not_const(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
|
||||||
|
match tcx.def_kind(def_id) {
|
||||||
|
DefKind::Mod
|
||||||
|
| DefKind::Struct
|
||||||
|
| DefKind::Union
|
||||||
|
| DefKind::Enum
|
||||||
|
| DefKind::Variant
|
||||||
|
| DefKind::Trait
|
||||||
|
| DefKind::TyAlias
|
||||||
|
| DefKind::ForeignTy
|
||||||
|
| DefKind::TraitAlias
|
||||||
|
| DefKind::AssocTy
|
||||||
|
| DefKind::Macro(..)
|
||||||
|
| DefKind::Field
|
||||||
|
| DefKind::LifetimeParam
|
||||||
|
| DefKind::ExternCrate
|
||||||
|
| DefKind::Use
|
||||||
|
| DefKind::ForeignMod
|
||||||
|
| DefKind::GlobalAsm
|
||||||
|
| DefKind::Impl { .. }
|
||||||
|
| DefKind::OpaqueTy
|
||||||
|
| DefKind::SyntheticCoroutineBody
|
||||||
|
| DefKind::TyParam => true,
|
||||||
|
|
||||||
|
DefKind::AnonConst
|
||||||
|
| DefKind::InlineConst
|
||||||
|
| DefKind::Const
|
||||||
|
| DefKind::ConstParam
|
||||||
|
| DefKind::Static { .. }
|
||||||
|
| DefKind::Ctor(..)
|
||||||
|
| DefKind::AssocConst => false,
|
||||||
|
|
||||||
|
DefKind::Fn
|
||||||
|
| DefKind::AssocFn
|
||||||
|
| DefKind::Closure => tcx.constness(def_id) == Constness::NotConst,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'tcx> LateLintPass<'tcx> for ManualFloatMethods {
|
impl<'tcx> LateLintPass<'tcx> for ManualFloatMethods {
|
||||||
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
|
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
|
||||||
if let ExprKind::Binary(kind, lhs, rhs) = expr.kind
|
if let ExprKind::Binary(kind, lhs, rhs) = expr.kind
|
||||||
|
@ -105,7 +146,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualFloatMethods {
|
||||||
&& exprs.iter_mut().partition_in_place(|i| path_to_local(i).is_some()) == 2
|
&& exprs.iter_mut().partition_in_place(|i| path_to_local(i).is_some()) == 2
|
||||||
&& !in_external_macro(cx.sess(), expr.span)
|
&& !in_external_macro(cx.sess(), expr.span)
|
||||||
&& (
|
&& (
|
||||||
matches!(cx.tcx.constness(cx.tcx.hir().enclosing_body_owner(expr.hir_id)), Constness::NotConst)
|
is_not_const(cx.tcx, cx.tcx.hir().enclosing_body_owner(expr.hir_id).into())
|
||||||
|| self.msrv.meets(msrvs::CONST_FLOAT_CLASSIFY)
|
|| self.msrv.meets(msrvs::CONST_FLOAT_CLASSIFY)
|
||||||
)
|
)
|
||||||
&& let [first, second, const_1, const_2] = exprs
|
&& let [first, second, const_1, const_2] = exprs
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue