diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index f893a3d45e3..f57092b7ff5 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -354,7 +354,9 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry) { reg.register_late_lint_pass(box explicit_write::Pass); reg.register_late_lint_pass(box needless_pass_by_value::NeedlessPassByValue); reg.register_early_lint_pass(box literal_representation::LiteralDigitGrouping); - reg.register_early_lint_pass(box literal_representation::LiteralRepresentation); + reg.register_early_lint_pass(box literal_representation::LiteralRepresentation::new( + conf.literal_representation_threshold + )); reg.register_late_lint_pass(box use_self::UseSelf); reg.register_late_lint_pass(box bytecount::ByteCount); reg.register_late_lint_pass(box infinite_iter::Pass); diff --git a/clippy_lints/src/literal_representation.rs b/clippy_lints/src/literal_representation.rs index 91f01bae257..0d0e985f994 100644 --- a/clippy_lints/src/literal_representation.rs +++ b/clippy_lints/src/literal_representation.rs @@ -394,7 +394,9 @@ impl LiteralDigitGrouping { } #[derive(Copy, Clone)] -pub struct LiteralRepresentation; +pub struct LiteralRepresentation { + threshold: u64, +} impl LintPass for LiteralRepresentation { fn get_lints(&self) -> LintArray { @@ -415,6 +417,11 @@ impl EarlyLintPass for LiteralRepresentation { } impl LiteralRepresentation { + pub fn new(threshold: u64) -> Self { + Self { + threshold: threshold, + } + } fn check_lit(&self, cx: &EarlyContext, lit: &Lit) { // Lint integral literals. if_chain! { @@ -425,11 +432,15 @@ impl LiteralRepresentation { then { let digit_info = DigitInfo::new(&src, false); if digit_info.radix == Radix::Decimal { - let hex = format!("{:#X}", digit_info.digits - .chars() - .filter(|&c| c != '_') - .collect::() - .parse::().unwrap()); + let val = digit_info.digits + .chars() + .filter(|&c| c != '_') + .collect::() + .parse::().unwrap(); + if val < self.threshold as u128 { + return + } + let hex = format!("{:#X}", val); let digit_info = DigitInfo::new(&hex[..], false); let _ = Self::do_lint(digit_info.digits).map_err(|warning_type| { warning_type.display(&digit_info.grouping_hint(), cx, &lit.span) @@ -440,22 +451,30 @@ impl LiteralRepresentation { } fn do_lint(digits: &str) -> Result<(), WarningType> { - if digits.len() == 2 && digits == "FF" { - return Err(WarningType::BadRepresentation); - } else if digits.len() == 3 { - // Lint for Literals with a hex-representation of 3 digits - let f = &digits[0..1]; // first digit - let s = &digits[1..]; // suffix - // Powers of 2 minus 1 - if (f.eq("1") || f.eq("3") || f.eq("7") || f.eq("F")) && s.eq("FF") { + if digits.len() == 1 { + // Lint for 1 digit literals, if someone really sets the threshold that low + if digits == "1" || digits == "2" || digits == "4" || digits == "8" || digits == "3" || digits == "7" + || digits == "F" + { return Err(WarningType::BadRepresentation); } - } else if digits.len() > 3 { + } else if digits.len() < 4 { + // Lint for Literals with a hex-representation of 2 or 3 digits + let f = &digits[0..1]; // first digit + let s = &digits[1..]; // suffix + // Powers of 2 + if ((f.eq("1") || f.eq("2") || f.eq("4") || f.eq("8")) && s.chars().all(|c| c == '0')) + // Powers of 2 minus 1 + || ((f.eq("1") || f.eq("3") || f.eq("7") || f.eq("F")) && s.chars().all(|c| c == 'F')) + { + return Err(WarningType::BadRepresentation); + } + } else { // Lint for Literals with a hex-representation of 4 digits or more let f = &digits[0..1]; // first digit let m = &digits[1..digits.len() - 1]; // middle digits, except last let s = &digits[1..]; // suffix - // Powers of 2 with a margin of +15/-16 + // Powers of 2 with a margin of +15/-16 if ((f.eq("1") || f.eq("2") || f.eq("4") || f.eq("8")) && m.chars().all(|c| c == '0')) || ((f.eq("1") || f.eq("3") || f.eq("7") || f.eq("F")) && m.chars().all(|c| c == 'F')) // Lint for representations with only 0s and Fs, while allowing 7 as the first diff --git a/clippy_lints/src/utils/conf.rs b/clippy_lints/src/utils/conf.rs index b13ceb8692a..e1298be81e5 100644 --- a/clippy_lints/src/utils/conf.rs +++ b/clippy_lints/src/utils/conf.rs @@ -177,6 +177,8 @@ define_Conf! { (enum_variant_size_threshold, "enum_variant_size_threshold", 200 => u64), /// Lint: VERBOSE_BIT_MASK. The maximum allowed size of a bit mask before suggesting to use 'trailing_zeros' (verbose_bit_mask_threshold, "verbose_bit_mask_threshold", 1 => u64), + /// Lint: BAD_LITERAL_REPRESENTATION. The lower bound for linting decimal literals + (literal_representation_threshold, "literal_representation_threshold", 4096 => u64), } /// Search for the configuration file. diff --git a/tests/ui/bad_literal_representation.rs b/tests/ui/bad_literal_representation.rs index 00126152fe1..ab12d605596 100644 --- a/tests/ui/bad_literal_representation.rs +++ b/tests/ui/bad_literal_representation.rs @@ -4,14 +4,9 @@ #[warn(bad_literal_representation)] #[allow(unused_variables)] fn main() { - // Hex: 7F, 80, 100, 800, FFA, F0F3, 7F0F_F00D - let good = (127, 128, 256, 2048, 4090, 61_683, 2_131_750_925); + // Hex: 7F, 80, 100, 1FF, 800, FFA, F0F3, 7F0F_F00D + let good = (127, 128, 256, 511, 2048, 4090, 61_683, 2_131_750_925); let bad = ( // Hex: - 255, // 0xFF - 511, // 0x1FF - 1023, // 0x3FF - 2047, // 0x7FF - 4095, // 0xFFF 4096, // 0x1000 16_371, // 0x3FF3 32_773, // 0x8005 diff --git a/tests/ui/bad_literal_representation.stderr b/tests/ui/bad_literal_representation.stderr index f57956c23d6..68e66ef1cee 100644 --- a/tests/ui/bad_literal_representation.stderr +++ b/tests/ui/bad_literal_representation.stderr @@ -1,96 +1,56 @@ error: bad representation of integer literal --> $DIR/bad_literal_representation.rs:10:9 | -10 | 255, // 0xFF - | ^^^ +10 | 4096, // 0x1000 + | ^^^^ | = note: `-D bad-literal-representation` implied by `-D warnings` - = help: consider: 0xFF + = help: consider: 0x1000 error: bad representation of integer literal --> $DIR/bad_literal_representation.rs:11:9 | -11 | 511, // 0x1FF - | ^^^ - | - = help: consider: 0x1FF - -error: bad representation of integer literal - --> $DIR/bad_literal_representation.rs:12:9 - | -12 | 1023, // 0x3FF - | ^^^^ - | - = help: consider: 0x3FF - -error: bad representation of integer literal - --> $DIR/bad_literal_representation.rs:13:9 - | -13 | 2047, // 0x7FF - | ^^^^ - | - = help: consider: 0x7FF - -error: bad representation of integer literal - --> $DIR/bad_literal_representation.rs:14:9 - | -14 | 4095, // 0xFFF - | ^^^^ - | - = help: consider: 0xFFF - -error: bad representation of integer literal - --> $DIR/bad_literal_representation.rs:15:9 - | -15 | 4096, // 0x1000 - | ^^^^ - | - = help: consider: 0x1000 - -error: bad representation of integer literal - --> $DIR/bad_literal_representation.rs:16:9 - | -16 | 16_371, // 0x3FF3 +11 | 16_371, // 0x3FF3 | ^^^^^^ | = help: consider: 0x3FF3 error: bad representation of integer literal - --> $DIR/bad_literal_representation.rs:17:9 + --> $DIR/bad_literal_representation.rs:12:9 | -17 | 32_773, // 0x8005 +12 | 32_773, // 0x8005 | ^^^^^^ | = help: consider: 0x8005 error: bad representation of integer literal - --> $DIR/bad_literal_representation.rs:18:9 + --> $DIR/bad_literal_representation.rs:13:9 | -18 | 65_280, // 0xFF00 +13 | 65_280, // 0xFF00 | ^^^^^^ | = help: consider: 0xFF00 error: bad representation of integer literal - --> $DIR/bad_literal_representation.rs:19:9 + --> $DIR/bad_literal_representation.rs:14:9 | -19 | 2_131_750_927, // 0x7F0F_F00F +14 | 2_131_750_927, // 0x7F0F_F00F | ^^^^^^^^^^^^^ | = help: consider: 0x7F0F_F00F error: bad representation of integer literal - --> $DIR/bad_literal_representation.rs:20:9 + --> $DIR/bad_literal_representation.rs:15:9 | -20 | 2_147_483_647, // 0x7FFF_FFFF +15 | 2_147_483_647, // 0x7FFF_FFFF | ^^^^^^^^^^^^^ | = help: consider: 0x7FFF_FFFF error: bad representation of integer literal - --> $DIR/bad_literal_representation.rs:21:9 + --> $DIR/bad_literal_representation.rs:16:9 | -21 | 4_042_322_160, // 0xF0F0_F0F0 +16 | 4_042_322_160, // 0xF0F0_F0F0 | ^^^^^^^^^^^^^ | = help: consider: 0xF0F0_F0F0