| #![warn(clippy::manual_clamp)] | |
| #![expect(clippy::if_same_then_else, clippy::needless_match)] | |
| use std::cmp::{max as cmp_max, min as cmp_min}; | |
| const CONST_MAX: i32 = 10; | |
| const CONST_MIN: i32 = 4; | |
| const CONST_F64_MAX: f64 = 10.0; | |
| const CONST_F64_MIN: f64 = 4.0; | |
| fn main() { | |
| let (input, min, max) = (0, -2, 3); | |
| // Min and max are not const, so this shouldn't trigger the lint. | |
| let x0 = if max < input { | |
| max | |
| } else if min > input { | |
| min | |
| } else { | |
| input | |
| }; | |
| let x1 = if input > max { | |
| max | |
| } else if input < min { | |
| min | |
| } else { | |
| input | |
| }; | |
| let x2 = if input < min { | |
| min | |
| } else if input > max { | |
| max | |
| } else { | |
| input | |
| }; | |
| let x3 = if min > input { | |
| min | |
| } else if max < input { | |
| max | |
| } else { | |
| input | |
| }; | |
| let x4 = input.max(min).min(max); | |
| let x5 = input.min(max).max(min); | |
| let x6 = match input { | |
| x if x > max => max, | |
| x if x < min => min, | |
| x => x, | |
| }; | |
| let x7 = match input { | |
| x if x < min => min, | |
| x if x > max => max, | |
| x => x, | |
| }; | |
| let x8 = match input { | |
| x if max < x => max, | |
| x if min > x => min, | |
| x => x, | |
| }; | |
| let mut x9 = input; | |
| if x9 < min { | |
| x9 = min; | |
| } | |
| if x9 > max { | |
| x9 = max; | |
| } | |
| let x10 = match input { | |
| x if min > x => min, | |
| x if max < x => max, | |
| x => x, | |
| }; | |
| let mut x11 = input; | |
| let _ = 1; | |
| if x11 > max { | |
| x11 = max; | |
| } | |
| if x11 < min { | |
| x11 = min; | |
| } | |
| let mut x12 = input; | |
| if min > x12 { | |
| x12 = min; | |
| } | |
| if max < x12 { | |
| x12 = max; | |
| } | |
| let mut x13 = input; | |
| if max < x13 { | |
| x13 = max; | |
| } | |
| if min > x13 { | |
| x13 = min; | |
| } | |
| { | |
| let (input, min, max) = (0.0f64, -2.0, 3.0); | |
| let x14 = if input > max { | |
| max | |
| } else if input < min { | |
| min | |
| } else { | |
| input | |
| }; | |
| } | |
| let mut x15 = input; | |
| if x15 < min { | |
| x15 = min; | |
| } else if x15 > max { | |
| x15 = max; | |
| } | |
| // It's important this be the last set of statements | |
| let mut x16 = input; | |
| if max < x16 { | |
| x16 = max; | |
| } | |
| if min > x16 { | |
| x16 = min; | |
| } | |
| } | |
| fn const_main() { | |
| let input = 0; | |
| // Min and max are const, so this should trigger the lint. | |
| let x0 = input.clamp(CONST_MIN, CONST_MAX); | |
| let x1 = input.clamp(CONST_MIN, CONST_MAX); | |
| let x2 = input.clamp(CONST_MIN, CONST_MAX); | |
| let x3 = input.clamp(CONST_MIN, CONST_MAX); | |
| let x4 = input.clamp(CONST_MIN, CONST_MAX); | |
| //~^ manual_clamp | |
| let x5 = input.clamp(CONST_MIN, CONST_MAX); | |
| //~^ manual_clamp | |
| let x6 = input.clamp(CONST_MIN, CONST_MAX); | |
| let x7 = input.clamp(CONST_MIN, CONST_MAX); | |
| let x8 = input.clamp(CONST_MIN, CONST_MAX); | |
| let mut x9 = input; | |
| x9 = x9.clamp(CONST_MIN, CONST_MAX); | |
| let x10 = input.clamp(CONST_MIN, CONST_MAX); | |
| let mut x11 = input; | |
| let _ = 1; | |
| x11 = x11.clamp(CONST_MIN, CONST_MAX); | |
| let mut x12 = input; | |
| x12 = x12.clamp(CONST_MIN, CONST_MAX); | |
| let mut x13 = input; | |
| x13 = x13.clamp(CONST_MIN, CONST_MAX); | |
| let x14 = input.clamp(CONST_MIN, CONST_MAX); | |
| { | |
| let input = 0.0f64; | |
| let x15 = input.clamp(CONST_F64_MIN, CONST_F64_MAX); | |
| } | |
| { | |
| let input: i32 = cmp_min_max(1); | |
| // These can only be detected if exactly one of the arguments to the inner function is const. | |
| let x16 = input.clamp(CONST_MIN, CONST_MAX); | |
| //~^ manual_clamp | |
| let x17 = input.clamp(CONST_MIN, CONST_MAX); | |
| //~^ manual_clamp | |
| let x18 = input.clamp(CONST_MIN, CONST_MAX); | |
| //~^ manual_clamp | |
| let x19 = input.clamp(CONST_MIN, CONST_MAX); | |
| //~^ manual_clamp | |
| let x20 = input.clamp(CONST_MIN, CONST_MAX); | |
| //~^ manual_clamp | |
| let x21 = input.clamp(CONST_MIN, CONST_MAX); | |
| //~^ manual_clamp | |
| let x22 = input.clamp(CONST_MIN, CONST_MAX); | |
| //~^ manual_clamp | |
| let x23 = input.clamp(CONST_MIN, CONST_MAX); | |
| //~^ manual_clamp | |
| let input: f64 = cmp_min_max(1) as f64; | |
| let x24 = input.clamp(CONST_F64_MIN, CONST_F64_MAX); | |
| //~^ manual_clamp | |
| let x25 = input.clamp(CONST_F64_MIN, CONST_F64_MAX); | |
| //~^ manual_clamp | |
| let x26 = input.clamp(CONST_F64_MIN, CONST_F64_MAX); | |
| //~^ manual_clamp | |
| let x27 = input.clamp(CONST_F64_MIN, CONST_F64_MAX); | |
| //~^ manual_clamp | |
| let x28 = input.clamp(CONST_F64_MIN, CONST_F64_MAX); | |
| //~^ manual_clamp | |
| let x29 = input.clamp(CONST_F64_MIN, CONST_F64_MAX); | |
| //~^ manual_clamp | |
| let x30 = input.clamp(CONST_F64_MIN, CONST_F64_MAX); | |
| //~^ manual_clamp | |
| let x31 = input.clamp(CONST_F64_MIN, CONST_F64_MAX); | |
| //~^ manual_clamp | |
| } | |
| let mut x32 = input; | |
| x32 = x32.clamp(CONST_MIN, CONST_MAX); | |
| // Flip the script, swap the places of min and max. Make sure this doesn't | |
| // trigger when clamp would be guaranteed to panic. | |
| let mut x33 = input; | |
| if x33 < CONST_MAX { | |
| x33 = CONST_MAX; | |
| } else if x33 > CONST_MIN { | |
| x33 = CONST_MIN; | |
| } | |
| // Do it again for NaN | |
| #[allow(invalid_nan_comparisons)] | |
| { | |
| let mut x34 = input as f64; | |
| if x34 < f64::NAN { | |
| x34 = f64::NAN; | |
| } else if x34 > CONST_F64_MAX { | |
| x34 = CONST_F64_MAX; | |
| } | |
| } | |
| // It's important this be the last set of statements | |
| let mut x35 = input; | |
| x35 = x35.clamp(CONST_MIN, CONST_MAX); | |
| } | |
| // This code intentionally nonsense. | |
| fn no_lint() { | |
| let input = 0; | |
| let x0 = if CONST_MAX < input { | |
| CONST_MAX | |
| } else if CONST_MIN > input { | |
| CONST_MAX | |
| } else { | |
| CONST_MIN | |
| }; | |
| let x1 = if input > CONST_MAX { | |
| CONST_MAX | |
| } else if input > CONST_MIN { | |
| CONST_MIN | |
| } else { | |
| CONST_MAX | |
| }; | |
| let x2 = if CONST_MAX < CONST_MIN { | |
| CONST_MIN | |
| } else if input > CONST_MAX { | |
| input | |
| } else { | |
| input | |
| }; | |
| let x3 = if CONST_MIN > input { | |
| input | |
| } else if CONST_MAX < input { | |
| CONST_MAX | |
| } else { | |
| CONST_MAX | |
| }; | |
| let x6 = match input { | |
| x if x < CONST_MAX => x, | |
| x if x < CONST_MIN => x, | |
| x => x, | |
| }; | |
| let x7 = match input { | |
| x if x < CONST_MIN => CONST_MAX, | |
| x if x > CONST_MAX => CONST_MIN, | |
| x => x, | |
| }; | |
| let x8 = match input { | |
| x if CONST_MAX > x => CONST_MAX, | |
| x if CONST_MIN > x => CONST_MIN, | |
| x => x, | |
| }; | |
| let mut x9 = input; | |
| if x9 > CONST_MIN { | |
| x9 = CONST_MIN; | |
| } | |
| if x9 > CONST_MAX { | |
| x9 = CONST_MAX; | |
| } | |
| let x10 = match input { | |
| x if CONST_MIN > x => CONST_MIN, | |
| x if CONST_MAX < x => CONST_MAX, | |
| x => CONST_MIN, | |
| }; | |
| let mut x11 = input; | |
| if x11 > CONST_MAX { | |
| x11 = CONST_MIN; | |
| } | |
| if x11 < CONST_MIN { | |
| x11 = CONST_MAX; | |
| } | |
| let mut x12 = input; | |
| if CONST_MIN > x12 { | |
| x12 = CONST_MAX * 3; | |
| } | |
| if CONST_MAX < x12 { | |
| x12 = CONST_MIN; | |
| } | |
| let mut x13 = input; | |
| if CONST_MAX < x13 { | |
| let x13 = CONST_MAX; | |
| } | |
| if CONST_MIN > x13 { | |
| x13 = CONST_MIN; | |
| } | |
| let mut x14 = input; | |
| if x14 < CONST_MIN { | |
| x14 = 3; | |
| } else if x14 > CONST_MAX { | |
| x14 = CONST_MAX; | |
| } | |
| { | |
| let input: i32 = cmp_min_max(1); | |
| // These can only be detected if exactly one of the arguments to the inner function is const. | |
| let x16 = cmp_max(cmp_max(input, CONST_MAX), CONST_MIN); | |
| let x17 = cmp_min(cmp_min(input, CONST_MIN), CONST_MAX); | |
| let x18 = cmp_max(CONST_MIN, cmp_max(input, CONST_MAX)); | |
| let x19 = cmp_min(CONST_MAX, cmp_min(input, CONST_MIN)); | |
| let x20 = cmp_max(cmp_max(CONST_MAX, input), CONST_MIN); | |
| let x21 = cmp_min(cmp_min(CONST_MIN, input), CONST_MAX); | |
| let x22 = cmp_max(CONST_MIN, cmp_max(CONST_MAX, input)); | |
| let x23 = cmp_min(CONST_MAX, cmp_min(CONST_MIN, input)); | |
| let input: f64 = cmp_min_max(1) as f64; | |
| let x24 = f64::max(f64::max(input, CONST_F64_MAX), CONST_F64_MIN); | |
| let x25 = f64::min(f64::min(input, CONST_F64_MIN), CONST_F64_MAX); | |
| let x26 = f64::max(CONST_F64_MIN, f64::max(input, CONST_F64_MAX)); | |
| let x27 = f64::min(CONST_F64_MAX, f64::min(input, CONST_F64_MIN)); | |
| let x28 = f64::max(f64::max(CONST_F64_MAX, input), CONST_F64_MIN); | |
| let x29 = f64::min(f64::min(CONST_F64_MIN, input), CONST_F64_MAX); | |
| let x30 = f64::max(CONST_F64_MIN, f64::max(CONST_F64_MAX, input)); | |
| let x31 = f64::min(CONST_F64_MAX, f64::min(CONST_F64_MIN, input)); | |
| let x32 = f64::min(CONST_F64_MAX, f64::min(CONST_F64_MIN, CONST_F64_MAX)); | |
| } | |
| } | |
| fn dont_tell_me_what_to_do() { | |
| let (input, min, max) = (0, -2, 3); | |
| let mut x_never = input; | |
| #[allow(clippy::manual_clamp)] | |
| if x_never < min { | |
| x_never = min; | |
| } | |
| if x_never > max { | |
| x_never = max; | |
| } | |
| } | |
| /// Just to ensure this isn't const evaled | |
| fn cmp_min_max(input: i32) -> i32 { | |
| input * 3 | |
| } | |
| #[clippy::msrv = "1.49"] | |
| fn msrv_1_49() { | |
| let (input, min, max) = (0, -1, 2); | |
| let _ = if input < min { | |
| min | |
| } else if input > max { | |
| max | |
| } else { | |
| input | |
| }; | |
| } | |
| #[clippy::msrv = "1.50"] | |
| fn msrv_1_50() { | |
| let input = 0; | |
| let _ = input.clamp(CONST_MIN, CONST_MAX); | |
| } | |
| const fn _const() { | |
| let (input, min, max) = (0, -1, 2); | |
| let _ = if input < min { | |
| min | |
| } else if input > max { | |
| max | |
| } else { | |
| input | |
| }; | |
| let mut x = input; | |
| if max < x { | |
| let x = max; | |
| } | |
| if min > x { | |
| x = min; | |
| } | |
| } |