manual_float_methods
:
* Check HIR tree first. * Use `partition_in_place`.
This commit is contained in:
parent
b9ba340db6
commit
95348adcb9
@ -5,6 +5,7 @@
|
|||||||
#![feature(f16)]
|
#![feature(f16)]
|
||||||
#![feature(if_let_guard)]
|
#![feature(if_let_guard)]
|
||||||
#![feature(iter_intersperse)]
|
#![feature(iter_intersperse)]
|
||||||
|
#![feature(iter_partition_in_place)]
|
||||||
#![feature(let_chains)]
|
#![feature(let_chains)]
|
||||||
#![feature(never_type)]
|
#![feature(never_type)]
|
||||||
#![feature(rustc_private)]
|
#![feature(rustc_private)]
|
||||||
|
@ -82,29 +82,26 @@ impl Variant {
|
|||||||
|
|
||||||
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 !in_external_macro(cx.sess(), expr.span)
|
if let ExprKind::Binary(kind, lhs, rhs) = expr.kind
|
||||||
&& (
|
|
||||||
matches!(cx.tcx.constness(cx.tcx.hir().enclosing_body_owner(expr.hir_id)), Constness::NotConst)
|
|
||||||
|| cx.tcx.features().declared(sym!(const_float_classify))
|
|
||||||
) && let ExprKind::Binary(kind, lhs, rhs) = expr.kind
|
|
||||||
&& let ExprKind::Binary(lhs_kind, lhs_lhs, lhs_rhs) = lhs.kind
|
&& let ExprKind::Binary(lhs_kind, lhs_lhs, lhs_rhs) = lhs.kind
|
||||||
&& let ExprKind::Binary(rhs_kind, rhs_lhs, rhs_rhs) = rhs.kind
|
&& let ExprKind::Binary(rhs_kind, rhs_lhs, rhs_rhs) = rhs.kind
|
||||||
// Checking all possible scenarios using a function would be a hopeless task, as we have
|
// Checking all possible scenarios using a function would be a hopeless task, as we have
|
||||||
// 16 possible alignments of constants/operands. For now, let's use `partition`.
|
// 16 possible alignments of constants/operands. For now, let's use `partition`.
|
||||||
&& let (operands, constants) = [lhs_lhs, lhs_rhs, rhs_lhs, rhs_rhs]
|
&& let mut exprs = [lhs_lhs, lhs_rhs, rhs_lhs, rhs_rhs]
|
||||||
.into_iter()
|
&& exprs.iter_mut().partition_in_place(|i| path_to_local(i).is_some()) == 2
|
||||||
.partition::<Vec<&Expr<'_>>, _>(|i| path_to_local(i).is_some())
|
&& !in_external_macro(cx.sess(), expr.span)
|
||||||
&& let [first, second] = &*operands
|
&& (
|
||||||
&& let Some([const_1, const_2]) = constants
|
matches!(cx.tcx.constness(cx.tcx.hir().enclosing_body_owner(expr.hir_id)), Constness::NotConst)
|
||||||
.into_iter()
|
|| cx.tcx.features().declared(sym!(const_float_classify))
|
||||||
.map(|i| constant(cx, cx.typeck_results(), i))
|
)
|
||||||
.collect::<Option<Vec<_>>>()
|
&& let [first, second, const_1, const_2] = exprs
|
||||||
.as_deref()
|
&& let Some(const_1) = constant(cx, cx.typeck_results(), const_1)
|
||||||
|
&& let Some(const_2) = constant(cx, cx.typeck_results(), const_2)
|
||||||
&& path_to_local(first).is_some_and(|f| path_to_local(second).is_some_and(|s| f == s))
|
&& path_to_local(first).is_some_and(|f| path_to_local(second).is_some_and(|s| f == s))
|
||||||
// The actual infinity check, we also allow `NEG_INFINITY` before` INFINITY` just in
|
// The actual infinity check, we also allow `NEG_INFINITY` before` INFINITY` just in
|
||||||
// case somebody does that for some reason
|
// case somebody does that for some reason
|
||||||
&& (is_infinity(const_1) && is_neg_infinity(const_2)
|
&& (is_infinity(&const_1) && is_neg_infinity(&const_2)
|
||||||
|| is_neg_infinity(const_1) && is_infinity(const_2))
|
|| is_neg_infinity(&const_1) && is_infinity(&const_2))
|
||||||
&& let Some(local_snippet) = snippet_opt(cx, first.span)
|
&& let Some(local_snippet) = snippet_opt(cx, first.span)
|
||||||
{
|
{
|
||||||
let variant = match (kind.node, lhs_kind.node, rhs_kind.node) {
|
let variant = match (kind.node, lhs_kind.node, rhs_kind.node) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user