From 8c416c31975764c97812aa33eaa10c74d521d47e Mon Sep 17 00:00:00 2001 From: Philipp Hansch Date: Sat, 26 Jan 2019 09:49:55 +0100 Subject: [PATCH] Prevent incorrect cast_lossless suggestion in const_fn `::from` is not a const fn, so applying the suggestion of `cast_lossless` would fail to compile. The fix is to skip the lint if the cast is found inside a const fn. --- clippy_lints/src/utils/mod.rs | 4 +++ tests/ui/cast_lossless_float.fixed | 12 +++++++-- tests/ui/cast_lossless_float.rs | 12 +++++++-- tests/ui/cast_lossless_float.stderr | 20 +++++++-------- tests/ui/cast_lossless_integer.fixed | 12 +++++++-- tests/ui/cast_lossless_integer.rs | 12 +++++++-- tests/ui/cast_lossless_integer.stderr | 36 +++++++++++++-------------- 7 files changed, 72 insertions(+), 36 deletions(-) diff --git a/clippy_lints/src/utils/mod.rs b/clippy_lints/src/utils/mod.rs index c83b0f155fc..9df0896068a 100644 --- a/clippy_lints/src/utils/mod.rs +++ b/clippy_lints/src/utils/mod.rs @@ -82,6 +82,10 @@ pub fn in_constant(cx: &LateContext<'_, '_>, id: NodeId) -> bool { node: ItemKind::Static(..), .. }) => true, + Node::Item(&Item { + node: ItemKind::Fn(_, header, ..), + .. + }) => header.constness == Constness::Const, _ => false, } } diff --git a/tests/ui/cast_lossless_float.fixed b/tests/ui/cast_lossless_float.fixed index 22df1137922..cc3b007ee5d 100644 --- a/tests/ui/cast_lossless_float.fixed +++ b/tests/ui/cast_lossless_float.fixed @@ -1,7 +1,8 @@ // run-rustfix -#[warn(clippy::cast_lossless)] -#[allow(clippy::no_effect, clippy::unnecessary_operation)] +#![allow(clippy::no_effect, clippy::unnecessary_operation, dead_code)] +#![warn(clippy::cast_lossless)] + fn main() { // Test clippy::cast_lossless with casts to floating-point types f32::from(1i8); @@ -15,3 +16,10 @@ fn main() { f64::from(1i32); f64::from(1u32); } + +// The lint would suggest using `f64::from(input)` here but the `XX::from` function is not const, +// so we skip the lint if the expression is in a const fn. +// See #3656 +const fn abc(input: f32) -> f64 { + input as f64 +} diff --git a/tests/ui/cast_lossless_float.rs b/tests/ui/cast_lossless_float.rs index c86b4d05f28..6684afa0ede 100644 --- a/tests/ui/cast_lossless_float.rs +++ b/tests/ui/cast_lossless_float.rs @@ -1,7 +1,8 @@ // run-rustfix -#[warn(clippy::cast_lossless)] -#[allow(clippy::no_effect, clippy::unnecessary_operation)] +#![allow(clippy::no_effect, clippy::unnecessary_operation, dead_code)] +#![warn(clippy::cast_lossless)] + fn main() { // Test clippy::cast_lossless with casts to floating-point types 1i8 as f32; @@ -15,3 +16,10 @@ fn main() { 1i32 as f64; 1u32 as f64; } + +// The lint would suggest using `f64::from(input)` here but the `XX::from` function is not const, +// so we skip the lint if the expression is in a const fn. +// See #3656 +const fn abc(input: f32) -> f64 { + input as f64 +} diff --git a/tests/ui/cast_lossless_float.stderr b/tests/ui/cast_lossless_float.stderr index c2b01e83bbe..691ce72399e 100644 --- a/tests/ui/cast_lossless_float.stderr +++ b/tests/ui/cast_lossless_float.stderr @@ -1,5 +1,5 @@ error: casting i8 to f32 may become silently lossy if types change - --> $DIR/cast_lossless_float.rs:7:5 + --> $DIR/cast_lossless_float.rs:8:5 | LL | 1i8 as f32; | ^^^^^^^^^^ help: try: `f32::from(1i8)` @@ -7,55 +7,55 @@ LL | 1i8 as f32; = note: `-D clippy::cast-lossless` implied by `-D warnings` error: casting i8 to f64 may become silently lossy if types change - --> $DIR/cast_lossless_float.rs:8:5 + --> $DIR/cast_lossless_float.rs:9:5 | LL | 1i8 as f64; | ^^^^^^^^^^ help: try: `f64::from(1i8)` error: casting u8 to f32 may become silently lossy if types change - --> $DIR/cast_lossless_float.rs:9:5 + --> $DIR/cast_lossless_float.rs:10:5 | LL | 1u8 as f32; | ^^^^^^^^^^ help: try: `f32::from(1u8)` error: casting u8 to f64 may become silently lossy if types change - --> $DIR/cast_lossless_float.rs:10:5 + --> $DIR/cast_lossless_float.rs:11:5 | LL | 1u8 as f64; | ^^^^^^^^^^ help: try: `f64::from(1u8)` error: casting i16 to f32 may become silently lossy if types change - --> $DIR/cast_lossless_float.rs:11:5 + --> $DIR/cast_lossless_float.rs:12:5 | LL | 1i16 as f32; | ^^^^^^^^^^^ help: try: `f32::from(1i16)` error: casting i16 to f64 may become silently lossy if types change - --> $DIR/cast_lossless_float.rs:12:5 + --> $DIR/cast_lossless_float.rs:13:5 | LL | 1i16 as f64; | ^^^^^^^^^^^ help: try: `f64::from(1i16)` error: casting u16 to f32 may become silently lossy if types change - --> $DIR/cast_lossless_float.rs:13:5 + --> $DIR/cast_lossless_float.rs:14:5 | LL | 1u16 as f32; | ^^^^^^^^^^^ help: try: `f32::from(1u16)` error: casting u16 to f64 may become silently lossy if types change - --> $DIR/cast_lossless_float.rs:14:5 + --> $DIR/cast_lossless_float.rs:15:5 | LL | 1u16 as f64; | ^^^^^^^^^^^ help: try: `f64::from(1u16)` error: casting i32 to f64 may become silently lossy if types change - --> $DIR/cast_lossless_float.rs:15:5 + --> $DIR/cast_lossless_float.rs:16:5 | LL | 1i32 as f64; | ^^^^^^^^^^^ help: try: `f64::from(1i32)` error: casting u32 to f64 may become silently lossy if types change - --> $DIR/cast_lossless_float.rs:16:5 + --> $DIR/cast_lossless_float.rs:17:5 | LL | 1u32 as f64; | ^^^^^^^^^^^ help: try: `f64::from(1u32)` diff --git a/tests/ui/cast_lossless_integer.fixed b/tests/ui/cast_lossless_integer.fixed index e5b33d5e1b0..6c384e7d38c 100644 --- a/tests/ui/cast_lossless_integer.fixed +++ b/tests/ui/cast_lossless_integer.fixed @@ -1,7 +1,8 @@ // run-rustfix -#[warn(clippy::cast_lossless)] -#[allow(clippy::no_effect, clippy::unnecessary_operation)] +#![allow(clippy::no_effect, clippy::unnecessary_operation, dead_code)] +#![warn(clippy::cast_lossless)] + fn main() { // Test clippy::cast_lossless with casts to integer types i16::from(1i8); @@ -23,3 +24,10 @@ fn main() { i64::from(1u32); u64::from(1u32); } + +// The lint would suggest using `f64::from(input)` here but the `XX::from` function is not const, +// so we skip the lint if the expression is in a const fn. +// See #3656 +const fn abc(input: u16) -> u32 { + input as u32 +} diff --git a/tests/ui/cast_lossless_integer.rs b/tests/ui/cast_lossless_integer.rs index 61170625c8a..35970bca88c 100644 --- a/tests/ui/cast_lossless_integer.rs +++ b/tests/ui/cast_lossless_integer.rs @@ -1,7 +1,8 @@ // run-rustfix -#[warn(clippy::cast_lossless)] -#[allow(clippy::no_effect, clippy::unnecessary_operation)] +#![allow(clippy::no_effect, clippy::unnecessary_operation, dead_code)] +#![warn(clippy::cast_lossless)] + fn main() { // Test clippy::cast_lossless with casts to integer types 1i8 as i16; @@ -23,3 +24,10 @@ fn main() { 1u32 as i64; 1u32 as u64; } + +// The lint would suggest using `f64::from(input)` here but the `XX::from` function is not const, +// so we skip the lint if the expression is in a const fn. +// See #3656 +const fn abc(input: u16) -> u32 { + input as u32 +} diff --git a/tests/ui/cast_lossless_integer.stderr b/tests/ui/cast_lossless_integer.stderr index ac385298ecb..ff98ec84a14 100644 --- a/tests/ui/cast_lossless_integer.stderr +++ b/tests/ui/cast_lossless_integer.stderr @@ -1,5 +1,5 @@ error: casting i8 to i16 may become silently lossy if types change - --> $DIR/cast_lossless_integer.rs:7:5 + --> $DIR/cast_lossless_integer.rs:8:5 | LL | 1i8 as i16; | ^^^^^^^^^^ help: try: `i16::from(1i8)` @@ -7,103 +7,103 @@ LL | 1i8 as i16; = note: `-D clippy::cast-lossless` implied by `-D warnings` error: casting i8 to i32 may become silently lossy if types change - --> $DIR/cast_lossless_integer.rs:8:5 + --> $DIR/cast_lossless_integer.rs:9:5 | LL | 1i8 as i32; | ^^^^^^^^^^ help: try: `i32::from(1i8)` error: casting i8 to i64 may become silently lossy if types change - --> $DIR/cast_lossless_integer.rs:9:5 + --> $DIR/cast_lossless_integer.rs:10:5 | LL | 1i8 as i64; | ^^^^^^^^^^ help: try: `i64::from(1i8)` error: casting u8 to i16 may become silently lossy if types change - --> $DIR/cast_lossless_integer.rs:10:5 + --> $DIR/cast_lossless_integer.rs:11:5 | LL | 1u8 as i16; | ^^^^^^^^^^ help: try: `i16::from(1u8)` error: casting u8 to i32 may become silently lossy if types change - --> $DIR/cast_lossless_integer.rs:11:5 + --> $DIR/cast_lossless_integer.rs:12:5 | LL | 1u8 as i32; | ^^^^^^^^^^ help: try: `i32::from(1u8)` error: casting u8 to i64 may become silently lossy if types change - --> $DIR/cast_lossless_integer.rs:12:5 + --> $DIR/cast_lossless_integer.rs:13:5 | LL | 1u8 as i64; | ^^^^^^^^^^ help: try: `i64::from(1u8)` error: casting u8 to u16 may become silently lossy if types change - --> $DIR/cast_lossless_integer.rs:13:5 + --> $DIR/cast_lossless_integer.rs:14:5 | LL | 1u8 as u16; | ^^^^^^^^^^ help: try: `u16::from(1u8)` error: casting u8 to u32 may become silently lossy if types change - --> $DIR/cast_lossless_integer.rs:14:5 + --> $DIR/cast_lossless_integer.rs:15:5 | LL | 1u8 as u32; | ^^^^^^^^^^ help: try: `u32::from(1u8)` error: casting u8 to u64 may become silently lossy if types change - --> $DIR/cast_lossless_integer.rs:15:5 + --> $DIR/cast_lossless_integer.rs:16:5 | LL | 1u8 as u64; | ^^^^^^^^^^ help: try: `u64::from(1u8)` error: casting i16 to i32 may become silently lossy if types change - --> $DIR/cast_lossless_integer.rs:16:5 + --> $DIR/cast_lossless_integer.rs:17:5 | LL | 1i16 as i32; | ^^^^^^^^^^^ help: try: `i32::from(1i16)` error: casting i16 to i64 may become silently lossy if types change - --> $DIR/cast_lossless_integer.rs:17:5 + --> $DIR/cast_lossless_integer.rs:18:5 | LL | 1i16 as i64; | ^^^^^^^^^^^ help: try: `i64::from(1i16)` error: casting u16 to i32 may become silently lossy if types change - --> $DIR/cast_lossless_integer.rs:18:5 + --> $DIR/cast_lossless_integer.rs:19:5 | LL | 1u16 as i32; | ^^^^^^^^^^^ help: try: `i32::from(1u16)` error: casting u16 to i64 may become silently lossy if types change - --> $DIR/cast_lossless_integer.rs:19:5 + --> $DIR/cast_lossless_integer.rs:20:5 | LL | 1u16 as i64; | ^^^^^^^^^^^ help: try: `i64::from(1u16)` error: casting u16 to u32 may become silently lossy if types change - --> $DIR/cast_lossless_integer.rs:20:5 + --> $DIR/cast_lossless_integer.rs:21:5 | LL | 1u16 as u32; | ^^^^^^^^^^^ help: try: `u32::from(1u16)` error: casting u16 to u64 may become silently lossy if types change - --> $DIR/cast_lossless_integer.rs:21:5 + --> $DIR/cast_lossless_integer.rs:22:5 | LL | 1u16 as u64; | ^^^^^^^^^^^ help: try: `u64::from(1u16)` error: casting i32 to i64 may become silently lossy if types change - --> $DIR/cast_lossless_integer.rs:22:5 + --> $DIR/cast_lossless_integer.rs:23:5 | LL | 1i32 as i64; | ^^^^^^^^^^^ help: try: `i64::from(1i32)` error: casting u32 to i64 may become silently lossy if types change - --> $DIR/cast_lossless_integer.rs:23:5 + --> $DIR/cast_lossless_integer.rs:24:5 | LL | 1u32 as i64; | ^^^^^^^^^^^ help: try: `i64::from(1u32)` error: casting u32 to u64 may become silently lossy if types change - --> $DIR/cast_lossless_integer.rs:24:5 + --> $DIR/cast_lossless_integer.rs:25:5 | LL | 1u32 as u64; | ^^^^^^^^^^^ help: try: `u64::from(1u32)`