Skip to content

Commit

Permalink
Auto merge of #12496 - Jacherr:issue-12492, r=blyxyas
Browse files Browse the repository at this point in the history
Disable `cast_lossless` when casting to u128 from any (u)int type

Fixes #12492

Disables `cast_lossless` when casting to u128 from any int or uint type. The lint states that when casting to any int type, there can potentially be lossy behaviour if the source type ever exceeds the size of the destination type in the future, which is impossible with a destination of u128.

It's possible this is a bit of a niche edge case which is better addressed by just disabling the lint in code, but I personally couldn't think of any good reason to still lint in this specific case - maybe except if the source is a bool, for readability reasons :).

changelog: FP: `cast_lossless`: disable lint when casting to u128 from any (u)int type
  • Loading branch information
bors committed Mar 20, 2024
2 parents 5b7efe8 + 477108d commit 34766a6
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 24 deletions.
7 changes: 5 additions & 2 deletions clippy_lints/src/casts/cast_lossless.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use clippy_utils::ty::is_isize_or_usize;
use rustc_errors::Applicability;
use rustc_hir::{Expr, ExprKind, QPath, TyKind};
use rustc_lint::LateContext;
use rustc_middle::ty::{self, FloatTy, Ty};
use rustc_middle::ty::{self, FloatTy, Ty, UintTy};

use super::{utils, CAST_LOSSLESS};

Expand Down Expand Up @@ -77,7 +77,10 @@ pub(super) fn check(

fn should_lint(cx: &LateContext<'_>, expr: &Expr<'_>, cast_from: Ty<'_>, cast_to: Ty<'_>, msrv: &Msrv) -> bool {
// Do not suggest using From in consts/statics until it is valid to do so (see #2267).
if in_constant(cx, expr.hir_id) {
//
// If destination is u128, do not lint because source type cannot be larger
// If source is bool, still lint due to the lint message differing (refers to style)
if in_constant(cx, expr.hir_id) || (!cast_from.is_bool() && matches!(cast_to.kind(), ty::Uint(UintTy::U128))) {
return false;
}

Expand Down
6 changes: 6 additions & 0 deletions tests/ui/cast_lossless_integer.fixed
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#![warn(clippy::cast_lossless)]

type I64 = i64;
type U128 = u128;

fn main() {
// Test clippy::cast_lossless with casts to integer types
Expand All @@ -28,6 +29,11 @@ fn main() {
let _ = u16::from(1u8 + 1u8);

let _ = I64::from(1i8);

// Do not lint if destination type is u128
// see https://github.com/rust-lang/rust-clippy/issues/12492
let _ = 1u8 as u128;
let _ = 1u8 as U128;
}

// The lint would suggest using `f64::from(input)` here but the `XX::from` function is not const,
Expand Down
6 changes: 6 additions & 0 deletions tests/ui/cast_lossless_integer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#![warn(clippy::cast_lossless)]

type I64 = i64;
type U128 = u128;

fn main() {
// Test clippy::cast_lossless with casts to integer types
Expand All @@ -28,6 +29,11 @@ fn main() {
let _ = (1u8 + 1u8) as u16;

let _ = 1i8 as I64;

// Do not lint if destination type is u128
// see https://github.com/rust-lang/rust-clippy/issues/12492
let _ = 1u8 as u128;
let _ = 1u8 as U128;
}

// The lint would suggest using `f64::from(input)` here but the `XX::from` function is not const,
Expand Down
44 changes: 22 additions & 22 deletions tests/ui/cast_lossless_integer.stderr
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
error: casting `i8` to `i16` may become silently lossy if you later change the type
--> tests/ui/cast_lossless_integer.rs:8:13
--> tests/ui/cast_lossless_integer.rs:9:13
|
LL | let _ = 1i8 as i16;
| ^^^^^^^^^^ help: try: `i16::from(1i8)`
Expand All @@ -8,127 +8,127 @@ LL | let _ = 1i8 as i16;
= help: to override `-D warnings` add `#[allow(clippy::cast_lossless)]`

error: casting `i8` to `i32` may become silently lossy if you later change the type
--> tests/ui/cast_lossless_integer.rs:9:13
--> tests/ui/cast_lossless_integer.rs:10:13
|
LL | let _ = 1i8 as i32;
| ^^^^^^^^^^ help: try: `i32::from(1i8)`

error: casting `i8` to `i64` may become silently lossy if you later change the type
--> tests/ui/cast_lossless_integer.rs:10:13
--> tests/ui/cast_lossless_integer.rs:11:13
|
LL | let _ = 1i8 as i64;
| ^^^^^^^^^^ help: try: `i64::from(1i8)`

error: casting `u8` to `i16` may become silently lossy if you later change the type
--> tests/ui/cast_lossless_integer.rs:11:13
--> tests/ui/cast_lossless_integer.rs:12:13
|
LL | let _ = 1u8 as i16;
| ^^^^^^^^^^ help: try: `i16::from(1u8)`

error: casting `u8` to `i32` may become silently lossy if you later change the type
--> tests/ui/cast_lossless_integer.rs:12:13
--> tests/ui/cast_lossless_integer.rs:13:13
|
LL | let _ = 1u8 as i32;
| ^^^^^^^^^^ help: try: `i32::from(1u8)`

error: casting `u8` to `i64` may become silently lossy if you later change the type
--> tests/ui/cast_lossless_integer.rs:13:13
--> tests/ui/cast_lossless_integer.rs:14:13
|
LL | let _ = 1u8 as i64;
| ^^^^^^^^^^ help: try: `i64::from(1u8)`

error: casting `u8` to `u16` may become silently lossy if you later change the type
--> tests/ui/cast_lossless_integer.rs:14:13
--> tests/ui/cast_lossless_integer.rs:15:13
|
LL | let _ = 1u8 as u16;
| ^^^^^^^^^^ help: try: `u16::from(1u8)`

error: casting `u8` to `u32` may become silently lossy if you later change the type
--> tests/ui/cast_lossless_integer.rs:15:13
--> tests/ui/cast_lossless_integer.rs:16:13
|
LL | let _ = 1u8 as u32;
| ^^^^^^^^^^ help: try: `u32::from(1u8)`

error: casting `u8` to `u64` may become silently lossy if you later change the type
--> tests/ui/cast_lossless_integer.rs:16:13
--> tests/ui/cast_lossless_integer.rs:17:13
|
LL | let _ = 1u8 as u64;
| ^^^^^^^^^^ help: try: `u64::from(1u8)`

error: casting `i16` to `i32` may become silently lossy if you later change the type
--> tests/ui/cast_lossless_integer.rs:17:13
--> tests/ui/cast_lossless_integer.rs:18:13
|
LL | let _ = 1i16 as i32;
| ^^^^^^^^^^^ help: try: `i32::from(1i16)`

error: casting `i16` to `i64` may become silently lossy if you later change the type
--> tests/ui/cast_lossless_integer.rs:18:13
--> tests/ui/cast_lossless_integer.rs:19:13
|
LL | let _ = 1i16 as i64;
| ^^^^^^^^^^^ help: try: `i64::from(1i16)`

error: casting `u16` to `i32` may become silently lossy if you later change the type
--> tests/ui/cast_lossless_integer.rs:19:13
--> tests/ui/cast_lossless_integer.rs:20:13
|
LL | let _ = 1u16 as i32;
| ^^^^^^^^^^^ help: try: `i32::from(1u16)`

error: casting `u16` to `i64` may become silently lossy if you later change the type
--> tests/ui/cast_lossless_integer.rs:20:13
--> tests/ui/cast_lossless_integer.rs:21:13
|
LL | let _ = 1u16 as i64;
| ^^^^^^^^^^^ help: try: `i64::from(1u16)`

error: casting `u16` to `u32` may become silently lossy if you later change the type
--> tests/ui/cast_lossless_integer.rs:21:13
--> tests/ui/cast_lossless_integer.rs:22:13
|
LL | let _ = 1u16 as u32;
| ^^^^^^^^^^^ help: try: `u32::from(1u16)`

error: casting `u16` to `u64` may become silently lossy if you later change the type
--> tests/ui/cast_lossless_integer.rs:22:13
--> tests/ui/cast_lossless_integer.rs:23:13
|
LL | let _ = 1u16 as u64;
| ^^^^^^^^^^^ help: try: `u64::from(1u16)`

error: casting `i32` to `i64` may become silently lossy if you later change the type
--> tests/ui/cast_lossless_integer.rs:23:13
--> tests/ui/cast_lossless_integer.rs:24:13
|
LL | let _ = 1i32 as i64;
| ^^^^^^^^^^^ help: try: `i64::from(1i32)`

error: casting `u32` to `i64` may become silently lossy if you later change the type
--> tests/ui/cast_lossless_integer.rs:24:13
--> tests/ui/cast_lossless_integer.rs:25:13
|
LL | let _ = 1u32 as i64;
| ^^^^^^^^^^^ help: try: `i64::from(1u32)`

error: casting `u32` to `u64` may become silently lossy if you later change the type
--> tests/ui/cast_lossless_integer.rs:25:13
--> tests/ui/cast_lossless_integer.rs:26:13
|
LL | let _ = 1u32 as u64;
| ^^^^^^^^^^^ help: try: `u64::from(1u32)`

error: casting `u8` to `u16` may become silently lossy if you later change the type
--> tests/ui/cast_lossless_integer.rs:28:13
--> tests/ui/cast_lossless_integer.rs:29:13
|
LL | let _ = (1u8 + 1u8) as u16;
| ^^^^^^^^^^^^^^^^^^ help: try: `u16::from(1u8 + 1u8)`

error: casting `i8` to `I64` may become silently lossy if you later change the type
--> tests/ui/cast_lossless_integer.rs:30:13
--> tests/ui/cast_lossless_integer.rs:31:13
|
LL | let _ = 1i8 as I64;
| ^^^^^^^^^^ help: try: `I64::from(1i8)`

error: casting `i8` to `i32` may become silently lossy if you later change the type
--> tests/ui/cast_lossless_integer.rs:64:13
--> tests/ui/cast_lossless_integer.rs:70:13
|
LL | let _ = sign_cast!(x, u8, i8) as i32;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `i32::from(sign_cast!(x, u8, i8))`

error: casting `i8` to `i32` may become silently lossy if you later change the type
--> tests/ui/cast_lossless_integer.rs:65:13
--> tests/ui/cast_lossless_integer.rs:71:13
|
LL | let _ = (sign_cast!(x, u8, i8) + 1) as i32;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `i32::from(sign_cast!(x, u8, i8) + 1)`
Expand Down

0 comments on commit 34766a6

Please sign in to comment.