From ac225a3b1f30953f3fd45f02d9a08a857943b5b4 Mon Sep 17 00:00:00 2001 From: Francisco Salgueiro Date: Wed, 3 Apr 2024 21:43:06 +0100 Subject: [PATCH] Fix #11738: allow `cast` lints in macros Removed the `from_expansion` guard clause for cast lints, so that these warnings can be generated for internal macros. --- clippy_lints/src/casts/mod.rs | 11 ++++----- tests/ui/cast.rs | 12 ++++++++++ tests/ui/cast.stderr | 45 ++++++++++++++++++++++++++++++++--- 3 files changed, 58 insertions(+), 10 deletions(-) diff --git a/clippy_lints/src/casts/mod.rs b/clippy_lints/src/casts/mod.rs index 063aab28238..a87102b6bf4 100644 --- a/clippy_lints/src/casts/mod.rs +++ b/clippy_lints/src/casts/mod.rs @@ -754,13 +754,10 @@ impl_lint_pass!(Casts => [ impl<'tcx> LateLintPass<'tcx> for Casts { fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { - if !in_external_macro(cx.sess(), expr.span) { - ptr_as_ptr::check(cx, expr, &self.msrv); - } - - if expr.span.from_expansion() { + if in_external_macro(cx.sess(), expr.span) { return; } + ptr_as_ptr::check(cx, expr, &self.msrv); if let ExprKind::Cast(cast_expr, cast_to_hir) = expr.kind { if is_hir_ty_cfg_dependant(cx, cast_to_hir) { @@ -771,7 +768,7 @@ impl<'tcx> LateLintPass<'tcx> for Casts { cx.typeck_results().expr_ty(expr), ); - if unnecessary_cast::check(cx, expr, cast_expr, cast_from, cast_to) { + if !expr.span.from_expansion() && unnecessary_cast::check(cx, expr, cast_expr, cast_from, cast_to) { return; } cast_slice_from_raw_parts::check(cx, expr, cast_expr, cast_to, &self.msrv); @@ -782,7 +779,7 @@ impl<'tcx> LateLintPass<'tcx> for Casts { fn_to_numeric_cast_with_truncation::check(cx, expr, cast_expr, cast_from, cast_to); zero_ptr::check(cx, expr, cast_expr, cast_to_hir); - if cast_to.is_numeric() && !in_external_macro(cx.sess(), expr.span) { + if cast_to.is_numeric() { cast_possible_truncation::check(cx, expr, cast_expr, cast_from, cast_to, cast_to_hir.span); if cast_from.is_numeric() { cast_possible_wrap::check(cx, expr, cast_from, cast_to); diff --git a/tests/ui/cast.rs b/tests/ui/cast.rs index ce76ad3d3ad..215c008902d 100644 --- a/tests/ui/cast.rs +++ b/tests/ui/cast.rs @@ -463,6 +463,18 @@ fn issue11642() { } } +fn issue11738() { + macro_rules! m { + () => { + let _ = i32::MIN as u32; // cast_sign_loss + let _ = u32::MAX as u8; // cast_possible_truncation + let _ = std::f64::consts::PI as f32; // cast_possible_truncation + let _ = 0i8 as i32; // cast_lossless + }; + } + m!(); +} + fn issue12506() -> usize { let bar: Result, u32> = Ok(Some(10)); bar.unwrap().unwrap() as usize diff --git a/tests/ui/cast.stderr b/tests/ui/cast.stderr index 3736e8aee0a..8b269c47176 100644 --- a/tests/ui/cast.stderr +++ b/tests/ui/cast.stderr @@ -650,8 +650,47 @@ error: casting `i32` to `u32` may lose the sign of the value LL | (a.abs() * b.pow(2) / c.abs()) as u32 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +error: casting `i32` to `u32` may lose the sign of the value + --> tests/ui/cast.rs:469:21 + | +LL | let _ = i32::MIN as u32; // cast_sign_loss + | ^^^^^^^^^^^^^^^ +... +LL | m!(); + | ---- in this macro invocation + | + = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: casting `u32` to `u8` may truncate the value + --> tests/ui/cast.rs:470:21 + | +LL | let _ = u32::MAX as u8; // cast_possible_truncation + | ^^^^^^^^^^^^^^ +... +LL | m!(); + | ---- in this macro invocation + | + = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... + = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) +help: ... or use `try_from` and handle the error accordingly + | +LL | let _ = u8::try_from(u32::MAX); // cast_possible_truncation + | ~~~~~~~~~~~~~~~~~~~~~~ + +error: casting `f64` to `f32` may truncate the value + --> tests/ui/cast.rs:471:21 + | +LL | let _ = std::f64::consts::PI as f32; // cast_possible_truncation + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | m!(); + | ---- in this macro invocation + | + = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... + = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) + error: casting `i64` to `usize` may truncate the value on targets with 32-bit wide pointers - --> tests/ui/cast.rs:468:5 + --> tests/ui/cast.rs:480:5 | LL | bar.unwrap().unwrap() as usize | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -663,10 +702,10 @@ LL | usize::try_from(bar.unwrap().unwrap()) | error: casting `i64` to `usize` may lose the sign of the value - --> tests/ui/cast.rs:468:5 + --> tests/ui/cast.rs:480:5 | LL | bar.unwrap().unwrap() as usize | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 87 previous errors +error: aborting due to 90 previous errors