From dfcfd73b2c3bc0c076226ebbb04554b689dd5041 Mon Sep 17 00:00:00 2001 From: linshuy2 Date: Mon, 26 Jan 2026 17:57:34 +0000 Subject: [PATCH] fix: `cmp_owned` FP when `to_string` comes from macro input --- clippy_lints/src/operators/cmp_owned.rs | 12 ++++++--- clippy_lints/src/operators/mod.rs | 2 +- tests/ui/cmp_owned/with_suggestion.fixed | 32 +++++++++++++++++++++++ tests/ui/cmp_owned/with_suggestion.rs | 32 +++++++++++++++++++++++ tests/ui/cmp_owned/with_suggestion.stderr | 15 ++++++++++- 5 files changed, 87 insertions(+), 6 deletions(-) diff --git a/clippy_lints/src/operators/cmp_owned.rs b/clippy_lints/src/operators/cmp_owned.rs index 39097833a6c5..db55772f4e01 100644 --- a/clippy_lints/src/operators/cmp_owned.rs +++ b/clippy_lints/src/operators/cmp_owned.rs @@ -10,10 +10,10 @@ use super::CMP_OWNED; -pub(super) fn check(cx: &LateContext<'_>, op: BinOpKind, lhs: &Expr<'_>, rhs: &Expr<'_>) { +pub(super) fn check(cx: &LateContext<'_>, e: &Expr<'_>, op: BinOpKind, lhs: &Expr<'_>, rhs: &Expr<'_>) { if op.is_comparison() { - check_op(cx, lhs, rhs, true); - check_op(cx, rhs, lhs, false); + check_op(cx, e, lhs, rhs, true); + check_op(cx, e, rhs, lhs, false); } } @@ -35,7 +35,11 @@ fn symmetric_partial_eq<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>, other: Ty<'t }) } -fn check_op(cx: &LateContext<'_>, expr: &Expr<'_>, other: &Expr<'_>, left: bool) { +fn check_op(cx: &LateContext<'_>, outer: &Expr<'_>, expr: &Expr<'_>, other: &Expr<'_>, left: bool) { + if !outer.span.eq_ctxt(expr.span) { + return; + } + let typeck = cx.typeck_results(); let (arg, arg_span) = match expr.kind { ExprKind::MethodCall(_, arg, [], _) diff --git a/clippy_lints/src/operators/mod.rs b/clippy_lints/src/operators/mod.rs index 53b8e9e5d5ae..383b135dfa50 100644 --- a/clippy_lints/src/operators/mod.rs +++ b/clippy_lints/src/operators/mod.rs @@ -1038,7 +1038,7 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) { float_equality_without_abs::check(cx, e, op.node, lhs, rhs); integer_division::check(cx, e, op.node, lhs, rhs); integer_division_remainder_used::check(cx, op.node, lhs, rhs, e.span); - cmp_owned::check(cx, op.node, lhs, rhs); + cmp_owned::check(cx, e, op.node, lhs, rhs); float_cmp::check(cx, e, op.node, lhs, rhs); modulo_one::check(cx, e, op.node, rhs); modulo_arithmetic::check( diff --git a/tests/ui/cmp_owned/with_suggestion.fixed b/tests/ui/cmp_owned/with_suggestion.fixed index 4c3b13b30043..f65339605e75 100644 --- a/tests/ui/cmp_owned/with_suggestion.fixed +++ b/tests/ui/cmp_owned/with_suggestion.fixed @@ -112,3 +112,35 @@ fn issue16322(item: String) { println!("Ja!"); } } + +fn issue16458() { + macro_rules! partly_comes_from_macro { + ($i:ident: $ty:ty, $def:expr) => { + let _ = { + let res = <$ty>::default() == $def; + let _i: $ty = $def; + res + }; + }; + } + + partly_comes_from_macro! { + required_version: String, env!("HOME").to_string() + } + + macro_rules! all_comes_from_macro { + ($($i:ident: $ty:ty, $def:expr);+ $(;)*) => { + $( + let _ = { + let res = <$ty>::default() == "$def"; + //~^ cmp_owned + let _i: $ty = $def; + res + }; + )+ + }; + } + all_comes_from_macro! { + required_version: String, env!("HOME").to_string(); + } +} diff --git a/tests/ui/cmp_owned/with_suggestion.rs b/tests/ui/cmp_owned/with_suggestion.rs index a9d7509feaaf..ed2300c80eaa 100644 --- a/tests/ui/cmp_owned/with_suggestion.rs +++ b/tests/ui/cmp_owned/with_suggestion.rs @@ -112,3 +112,35 @@ fn issue16322(item: String) { println!("Ja!"); } } + +fn issue16458() { + macro_rules! partly_comes_from_macro { + ($i:ident: $ty:ty, $def:expr) => { + let _ = { + let res = <$ty>::default() == $def; + let _i: $ty = $def; + res + }; + }; + } + + partly_comes_from_macro! { + required_version: String, env!("HOME").to_string() + } + + macro_rules! all_comes_from_macro { + ($($i:ident: $ty:ty, $def:expr);+ $(;)*) => { + $( + let _ = { + let res = <$ty>::default() == "$def".to_string(); + //~^ cmp_owned + let _i: $ty = $def; + res + }; + )+ + }; + } + all_comes_from_macro! { + required_version: String, env!("HOME").to_string(); + } +} diff --git a/tests/ui/cmp_owned/with_suggestion.stderr b/tests/ui/cmp_owned/with_suggestion.stderr index 66544ce0c217..38d124baa4b5 100644 --- a/tests/ui/cmp_owned/with_suggestion.stderr +++ b/tests/ui/cmp_owned/with_suggestion.stderr @@ -55,5 +55,18 @@ error: this creates an owned instance just for comparison LL | if item == t!(frohes_neu_Jahr).to_string() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `t!(frohes_neu_Jahr)` -error: aborting due to 9 previous errors +error: this creates an owned instance just for comparison + --> tests/ui/cmp_owned/with_suggestion.rs:135:51 + | +LL | let res = <$ty>::default() == "$def".to_string(); + | ^^^^^^^^^^^^^^^^^^ help: try: `"$def"` +... +LL | / all_comes_from_macro! { +LL | | required_version: String, env!("HOME").to_string(); +LL | | } + | |_____- in this macro invocation + | + = note: this error originates in the macro `all_comes_from_macro` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 10 previous errors