about summary refs log tree commit diff
path: root/clippy_lints/src/operators
diff options
context:
space:
mode:
authorPhilipp Krones <hello@philkrones.com>2025-05-31 14:09:03 +0200
committerPhilipp Krones <hello@philkrones.com>2025-05-31 14:09:03 +0200
commit384b53eee2a479969347bbe3a46c504353cc00a2 (patch)
treef11d7e335b46a53087a622c8360b5b842ef59e20 /clippy_lints/src/operators
parent660aede53066ca0ab4354160d982d19b7962739b (diff)
parent2948678647a298047a42c72d7060bf509d74bd1d (diff)
Merge remote-tracking branch 'upstream/master' into rustup
Diffstat (limited to 'clippy_lints/src/operators')
-rw-r--r--clippy_lints/src/operators/assign_op_pattern.rs14
-rw-r--r--clippy_lints/src/operators/mod.rs2
-rw-r--r--clippy_lints/src/operators/modulo_arithmetic.rs45
3 files changed, 31 insertions, 30 deletions
diff --git a/clippy_lints/src/operators/assign_op_pattern.rs b/clippy_lints/src/operators/assign_op_pattern.rs
index 4be42267b14..9c6141d8222 100644
--- a/clippy_lints/src/operators/assign_op_pattern.rs
+++ b/clippy_lints/src/operators/assign_op_pattern.rs
@@ -1,8 +1,10 @@
 use clippy_utils::diagnostics::span_lint_and_then;
+use clippy_utils::msrvs::Msrv;
+use clippy_utils::qualify_min_const_fn::is_stable_const_fn;
 use clippy_utils::source::SpanRangeExt;
 use clippy_utils::ty::implements_trait;
 use clippy_utils::visitors::for_each_expr_without_closures;
-use clippy_utils::{binop_traits, eq_expr_value, trait_ref_of_method};
+use clippy_utils::{binop_traits, eq_expr_value, is_in_const_context, trait_ref_of_method};
 use core::ops::ControlFlow;
 use rustc_errors::Applicability;
 use rustc_hir as hir;
@@ -19,6 +21,7 @@ pub(super) fn check<'tcx>(
     expr: &'tcx hir::Expr<'_>,
     assignee: &'tcx hir::Expr<'_>,
     e: &'tcx hir::Expr<'_>,
+    msrv: Msrv,
 ) {
     if let hir::ExprKind::Binary(op, l, r) = &e.kind {
         let lint = |assignee: &hir::Expr<'_>, rhs: &hir::Expr<'_>| {
@@ -40,6 +43,15 @@ pub(super) fn check<'tcx>(
                         return;
                     }
                 }
+
+                // Skip if the trait is not stable in const contexts
+                if is_in_const_context(cx)
+                    && let Some(binop_id) = cx.tcx.associated_item_def_ids(trait_id).first()
+                    && !is_stable_const_fn(cx, *binop_id, msrv)
+                {
+                    return;
+                }
+
                 span_lint_and_then(
                     cx,
                     ASSIGN_OP_PATTERN,
diff --git a/clippy_lints/src/operators/mod.rs b/clippy_lints/src/operators/mod.rs
index d32c062cf56..2f4e8e99588 100644
--- a/clippy_lints/src/operators/mod.rs
+++ b/clippy_lints/src/operators/mod.rs
@@ -919,7 +919,7 @@ impl<'tcx> LateLintPass<'tcx> for Operators {
                 modulo_arithmetic::check(cx, e, bin_op, lhs, rhs, false);
             },
             ExprKind::Assign(lhs, rhs, _) => {
-                assign_op_pattern::check(cx, e, lhs, rhs);
+                assign_op_pattern::check(cx, e, lhs, rhs, self.msrv);
                 self_assignment::check(cx, e, lhs, rhs);
             },
             ExprKind::Unary(op, arg) => {
diff --git a/clippy_lints/src/operators/modulo_arithmetic.rs b/clippy_lints/src/operators/modulo_arithmetic.rs
index 691d7b904ef..b79461663d7 100644
--- a/clippy_lints/src/operators/modulo_arithmetic.rs
+++ b/clippy_lints/src/operators/modulo_arithmetic.rs
@@ -34,14 +34,10 @@ pub(super) fn check<'tcx>(
 }
 
 fn used_in_comparison_with_zero(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
-    let Node::Expr(parent_expr) = cx.tcx.parent_hir_node(expr.hir_id) else {
-        return false;
-    };
-    let ExprKind::Binary(op, lhs, rhs) = parent_expr.kind else {
-        return false;
-    };
-
-    if op.node == BinOpKind::Eq || op.node == BinOpKind::Ne {
+    if let Node::Expr(parent_expr) = cx.tcx.parent_hir_node(expr.hir_id)
+        && let ExprKind::Binary(op, lhs, rhs) = parent_expr.kind
+        && let BinOpKind::Eq | BinOpKind::Ne = op.node
+    {
         let ecx = ConstEvalCtxt::new(cx);
         matches!(ecx.eval(lhs), Some(Constant::Int(0))) || matches!(ecx.eval(rhs), Some(Constant::Int(0)))
     } else {
@@ -56,35 +52,28 @@ struct OperandInfo {
 }
 
 fn analyze_operand(operand: &Expr<'_>, cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<OperandInfo> {
-    match ConstEvalCtxt::new(cx).eval(operand) {
-        Some(Constant::Int(v)) => match *cx.typeck_results().expr_ty(expr).kind() {
+    match ConstEvalCtxt::new(cx).eval(operand)? {
+        Constant::Int(v) => match *cx.typeck_results().expr_ty(expr).kind() {
             ty::Int(ity) => {
                 let value = sext(cx.tcx, v, ity);
-                return Some(OperandInfo {
+                Some(OperandInfo {
                     string_representation: Some(value.to_string()),
                     is_negative: value < 0,
                     is_integral: true,
-                });
-            },
-            ty::Uint(_) => {
-                return Some(OperandInfo {
-                    string_representation: None,
-                    is_negative: false,
-                    is_integral: true,
-                });
+                })
             },
-            _ => {},
+            ty::Uint(_) => Some(OperandInfo {
+                string_representation: None,
+                is_negative: false,
+                is_integral: true,
+            }),
+            _ => None,
         },
         // FIXME(f16_f128): add when casting is available on all platforms
-        Some(Constant::F32(f)) => {
-            return Some(floating_point_operand_info(&f));
-        },
-        Some(Constant::F64(f)) => {
-            return Some(floating_point_operand_info(&f));
-        },
-        _ => {},
+        Constant::F32(f) => Some(floating_point_operand_info(&f)),
+        Constant::F64(f) => Some(floating_point_operand_info(&f)),
+        _ => None,
     }
-    None
 }
 
 fn floating_point_operand_info<T: Display + PartialOrd + From<f32>>(f: &T) -> OperandInfo {