Skip to content

Commit ca1ddc0

Browse files
committed
Auto merge of rust-lang#12722 - MATSMACKE:master, r=Alexendoo
Fix false positive in `cast_possible_truncation` Fixes [rust-lang#12721](rust-lang/rust-clippy#12721) changelog: [`cast_possible_truncation`]: Separated checking whether integer constant has sufficient leading zeroes to be safely casted when getting remainder from bitwise and, since the latter allows a constant on either side of the operator to increase the number of leading zeroes that can be guaranteed.
2 parents a18f50f + 0b1f09e commit ca1ddc0

File tree

3 files changed

+141
-93
lines changed

3 files changed

+141
-93
lines changed

clippy_lints/src/casts/cast_possible_truncation.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,14 @@ fn apply_reductions(cx: &LateContext<'_>, nbits: u64, expr: &Expr<'_>, signed: b
4040
get_constant_bits(cx, right).map_or(0, |b| b.saturating_sub(1))
4141
})
4242
},
43-
BinOpKind::Rem | BinOpKind::BitAnd => get_constant_bits(cx, right)
43+
BinOpKind::Rem => get_constant_bits(cx, right)
4444
.unwrap_or(u64::MAX)
4545
.min(apply_reductions(cx, nbits, left, signed)),
46+
BinOpKind::BitAnd => get_constant_bits(cx, right)
47+
.unwrap_or(u64::MAX)
48+
.min(get_constant_bits(cx, left).unwrap_or(u64::MAX))
49+
.min(apply_reductions(cx, nbits, right, signed))
50+
.min(apply_reductions(cx, nbits, left, signed)),
4651
BinOpKind::Shr => apply_reductions(cx, nbits, left, signed)
4752
.saturating_sub(constant_int(cx, right).map_or(0, |s| u64::try_from(s).unwrap_or_default())),
4853
_ => nbits,

tests/ui/cast.rs

+20-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@
1313
clippy::cast_abs_to_unsigned,
1414
clippy::no_effect,
1515
clippy::unnecessary_operation,
16-
clippy::unnecessary_literal_unwrap
16+
clippy::unnecessary_literal_unwrap,
17+
clippy::identity_op
1718
)]
1819

1920
fn main() {
@@ -479,3 +480,21 @@ fn issue12506() -> usize {
479480
let bar: Result<Option<i64>, u32> = Ok(Some(10));
480481
bar.unwrap().unwrap() as usize
481482
}
483+
484+
fn issue12721() {
485+
fn x() -> u64 {
486+
u64::MAX
487+
}
488+
489+
// Don't lint.
490+
(255 & 999999u64) as u8;
491+
// Don't lint.
492+
let _ = ((x() & 255) & 999999) as u8;
493+
// Don't lint.
494+
let _ = (999999 & (x() & 255)) as u8;
495+
496+
(256 & 999999u64) as u8;
497+
//~^ ERROR: casting `u64` to `u8` may truncate the value
498+
(255 % 999999u64) as u8;
499+
//~^ ERROR: casting `u64` to `u8` may truncate the value
500+
}

0 commit comments

Comments
 (0)