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(if_let_guard)]
|
||||
#![feature(iter_intersperse)]
|
||||
#![feature(iter_partition_in_place)]
|
||||
#![feature(let_chains)]
|
||||
#![feature(never_type)]
|
||||
#![feature(rustc_private)]
|
||||
|
@ -82,29 +82,26 @@ impl Variant {
|
||||
|
||||
impl<'tcx> LateLintPass<'tcx> for ManualFloatMethods {
|
||||
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
|
||||
if !in_external_macro(cx.sess(), expr.span)
|
||||
&& (
|
||||
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
|
||||
if let ExprKind::Binary(kind, lhs, rhs) = expr.kind
|
||||
&& let ExprKind::Binary(lhs_kind, lhs_lhs, lhs_rhs) = lhs.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
|
||||
// 16 possible alignments of constants/operands. For now, let's use `partition`.
|
||||
&& let (operands, constants) = [lhs_lhs, lhs_rhs, rhs_lhs, rhs_rhs]
|
||||
.into_iter()
|
||||
.partition::<Vec<&Expr<'_>>, _>(|i| path_to_local(i).is_some())
|
||||
&& let [first, second] = &*operands
|
||||
&& let Some([const_1, const_2]) = constants
|
||||
.into_iter()
|
||||
.map(|i| constant(cx, cx.typeck_results(), i))
|
||||
.collect::<Option<Vec<_>>>()
|
||||
.as_deref()
|
||||
&& let mut exprs = [lhs_lhs, lhs_rhs, rhs_lhs, rhs_rhs]
|
||||
&& exprs.iter_mut().partition_in_place(|i| path_to_local(i).is_some()) == 2
|
||||
&& !in_external_macro(cx.sess(), expr.span)
|
||||
&& (
|
||||
matches!(cx.tcx.constness(cx.tcx.hir().enclosing_body_owner(expr.hir_id)), Constness::NotConst)
|
||||
|| cx.tcx.features().declared(sym!(const_float_classify))
|
||||
)
|
||||
&& let [first, second, const_1, const_2] = exprs
|
||||
&& 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))
|
||||
// The actual infinity check, we also allow `NEG_INFINITY` before` INFINITY` just in
|
||||
// case somebody does that for some reason
|
||||
&& (is_infinity(const_1) && is_neg_infinity(const_2)
|
||||
|| is_neg_infinity(const_1) && is_infinity(const_2))
|
||||
&& (is_infinity(&const_1) && is_neg_infinity(&const_2)
|
||||
|| is_neg_infinity(&const_1) && is_infinity(&const_2))
|
||||
&& let Some(local_snippet) = snippet_opt(cx, first.span)
|
||||
{
|
||||
let variant = match (kind.node, lhs_kind.node, rhs_kind.node) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user