mirror of
https://github.com/rust-lang/rust.git
synced 2026-05-21 17:52:12 +03:00
Fix unnecessary_min_or_max for usize (#16575)
Fixes: rust-lang/rust-clippy#16555 changelog: [unnecessary_min_or_max]: Fix false negatives for usize::{MIN,MAX} by handling usize bit width correctly during constant evaluation, enabling the lint to trigger on cases like n.min(0) / n.max(usize::MAX).
This commit is contained in:
@@ -88,7 +88,17 @@ fn detect_extrema<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) -> Option<
|
||||
match (cv.int_value(cx.tcx, ty)?, ty.kind()) {
|
||||
(FullInt::S(i), &ty::Int(ity)) if i == i128::MIN >> (128 - ity.bit_width()?) => Some(Extrema::Minimum),
|
||||
(FullInt::S(i), &ty::Int(ity)) if i == i128::MAX >> (128 - ity.bit_width()?) => Some(Extrema::Maximum),
|
||||
(FullInt::U(i), &ty::Uint(uty)) if i == u128::MAX >> (128 - uty.bit_width()?) => Some(Extrema::Maximum),
|
||||
(FullInt::U(i), &ty::Uint(uty))
|
||||
if {
|
||||
let bits = match uty {
|
||||
ty::UintTy::Usize => u32::try_from(cx.tcx.data_layout.pointer_size().bits()).ok()?,
|
||||
_ => u32::try_from(uty.bit_width()?).ok()?,
|
||||
};
|
||||
i == u128::MAX >> (128 - bits)
|
||||
} =>
|
||||
{
|
||||
Some(Extrema::Maximum)
|
||||
},
|
||||
(FullInt::U(0), &ty::Uint(_)) => Some(Extrema::Minimum),
|
||||
_ => None,
|
||||
}
|
||||
|
||||
@@ -77,6 +77,32 @@ fn main() {
|
||||
let _ = (X + 1).min(12);
|
||||
let _ = 12.min(X - 1);
|
||||
let _ = 12.max(X - 1);
|
||||
|
||||
let n: usize = 42;
|
||||
|
||||
let _ = 0;
|
||||
//~^ unnecessary_min_or_max
|
||||
|
||||
let _ = 0usize;
|
||||
//~^ unnecessary_min_or_max
|
||||
|
||||
let _ = (0usize);
|
||||
//~^ unnecessary_min_or_max
|
||||
|
||||
let _ = usize::MIN;
|
||||
//~^ unnecessary_min_or_max
|
||||
|
||||
let _ = usize::MAX;
|
||||
//~^ unnecessary_min_or_max
|
||||
|
||||
let _ = (usize::MAX);
|
||||
//~^ unnecessary_min_or_max
|
||||
|
||||
let _ = !0usize;
|
||||
//~^ unnecessary_min_or_max
|
||||
|
||||
let _ = n;
|
||||
//~^ unnecessary_min_or_max
|
||||
}
|
||||
fn random_u32() -> u32 {
|
||||
// random number generator
|
||||
|
||||
@@ -77,6 +77,32 @@ fn main() {
|
||||
let _ = (X + 1).min(12);
|
||||
let _ = 12.min(X - 1);
|
||||
let _ = 12.max(X - 1);
|
||||
|
||||
let n: usize = 42;
|
||||
|
||||
let _ = n.min(0);
|
||||
//~^ unnecessary_min_or_max
|
||||
|
||||
let _ = n.min(0usize);
|
||||
//~^ unnecessary_min_or_max
|
||||
|
||||
let _ = (0usize).min(n);
|
||||
//~^ unnecessary_min_or_max
|
||||
|
||||
let _ = n.min(usize::MIN);
|
||||
//~^ unnecessary_min_or_max
|
||||
|
||||
let _ = n.max(usize::MAX);
|
||||
//~^ unnecessary_min_or_max
|
||||
|
||||
let _ = (usize::MAX).max(n);
|
||||
//~^ unnecessary_min_or_max
|
||||
|
||||
let _ = n.max(!0usize);
|
||||
//~^ unnecessary_min_or_max
|
||||
|
||||
let _ = n.max(0);
|
||||
//~^ unnecessary_min_or_max
|
||||
}
|
||||
fn random_u32() -> u32 {
|
||||
// random number generator
|
||||
|
||||
@@ -103,5 +103,53 @@ error: `x` is never smaller than `i32::MIN - 0` and has therefore no effect
|
||||
LL | let _ = x.min(i32::MIN - 0);
|
||||
| ^^^^^^^^^^^^^^^^^^^ help: try: `i32::MIN - 0`
|
||||
|
||||
error: aborting due to 17 previous errors
|
||||
error: `n` is never smaller than `0` and has therefore no effect
|
||||
--> tests/ui/unnecessary_min_or_max.rs:83:13
|
||||
|
|
||||
LL | let _ = n.min(0);
|
||||
| ^^^^^^^^ help: try: `0`
|
||||
|
||||
error: `n` is never smaller than `0usize` and has therefore no effect
|
||||
--> tests/ui/unnecessary_min_or_max.rs:86:13
|
||||
|
|
||||
LL | let _ = n.min(0usize);
|
||||
| ^^^^^^^^^^^^^ help: try: `0usize`
|
||||
|
||||
error: `(0usize)` is never greater than `n` and has therefore no effect
|
||||
--> tests/ui/unnecessary_min_or_max.rs:89:13
|
||||
|
|
||||
LL | let _ = (0usize).min(n);
|
||||
| ^^^^^^^^^^^^^^^ help: try: `(0usize)`
|
||||
|
||||
error: `n` is never smaller than `usize::MIN` and has therefore no effect
|
||||
--> tests/ui/unnecessary_min_or_max.rs:92:13
|
||||
|
|
||||
LL | let _ = n.min(usize::MIN);
|
||||
| ^^^^^^^^^^^^^^^^^ help: try: `usize::MIN`
|
||||
|
||||
error: `n` is never greater than `usize::MAX` and has therefore no effect
|
||||
--> tests/ui/unnecessary_min_or_max.rs:95:13
|
||||
|
|
||||
LL | let _ = n.max(usize::MAX);
|
||||
| ^^^^^^^^^^^^^^^^^ help: try: `usize::MAX`
|
||||
|
||||
error: `(usize::MAX)` is never smaller than `n` and has therefore no effect
|
||||
--> tests/ui/unnecessary_min_or_max.rs:98:13
|
||||
|
|
||||
LL | let _ = (usize::MAX).max(n);
|
||||
| ^^^^^^^^^^^^^^^^^^^ help: try: `(usize::MAX)`
|
||||
|
||||
error: `n` is never greater than `!0usize` and has therefore no effect
|
||||
--> tests/ui/unnecessary_min_or_max.rs:101:13
|
||||
|
|
||||
LL | let _ = n.max(!0usize);
|
||||
| ^^^^^^^^^^^^^^ help: try: `!0usize`
|
||||
|
||||
error: `n` is never smaller than `0` and has therefore no effect
|
||||
--> tests/ui/unnecessary_min_or_max.rs:104:13
|
||||
|
|
||||
LL | let _ = n.max(0);
|
||||
| ^^^^^^^^ help: try: `n`
|
||||
|
||||
error: aborting due to 25 previous errors
|
||||
|
||||
|
||||
Reference in New Issue
Block a user