Skip to content

Commit ab58331

Browse files
committed
Lint inconsistent casing in hex literals (closes #703)
1 parent 78fa1ab commit ab58331

File tree

5 files changed

+59
-4
lines changed

5 files changed

+59
-4
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,7 @@ All notable changes to this project will be documented in this file.
211211
[`mem_forget`]: https://github.com/Manishearth/rust-clippy/wiki#mem_forget
212212
[`min_max`]: https://github.com/Manishearth/rust-clippy/wiki#min_max
213213
[`misrefactored_assign_op`]: https://github.com/Manishearth/rust-clippy/wiki#misrefactored_assign_op
214+
[`mixed_case_hex_literals`]: https://github.com/Manishearth/rust-clippy/wiki#mixed_case_hex_literals
214215
[`modulo_one`]: https://github.com/Manishearth/rust-clippy/wiki#modulo_one
215216
[`mut_mut`]: https://github.com/Manishearth/rust-clippy/wiki#mut_mut
216217
[`mutex_atomic`]: https://github.com/Manishearth/rust-clippy/wiki#mutex_atomic

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ Table of contents:
1717

1818
## Lints
1919

20-
There are 160 lints included in this crate:
20+
There are 161 lints included in this crate:
2121

2222
name | default | meaning
2323
---------------------------------------------------------------------------------------------------------------------|---------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
@@ -98,6 +98,7 @@ name
9898
[mem_forget](https://github.com/Manishearth/rust-clippy/wiki#mem_forget) | allow | `mem::forget` usage on `Drop` types is likely to cause memory leaks
9999
[min_max](https://github.com/Manishearth/rust-clippy/wiki#min_max) | warn | `min(_, max(_, _))` (or vice versa) with bounds clamping the result to a constant
100100
[misrefactored_assign_op](https://github.com/Manishearth/rust-clippy/wiki#misrefactored_assign_op) | warn | having a variable on both sides of an assign op
101+
[mixed_case_hex_literals](https://github.com/Manishearth/rust-clippy/wiki#mixed_case_hex_literals) | warn | letter digits in hex literals should be either completely upper- or lowercased
101102
[modulo_one](https://github.com/Manishearth/rust-clippy/wiki#modulo_one) | warn | taking a number modulo 1, which always returns 0
102103
[mut_mut](https://github.com/Manishearth/rust-clippy/wiki#mut_mut) | allow | usage of double-mut refs, e.g. `&mut &mut ...`
103104
[mutex_atomic](https://github.com/Manishearth/rust-clippy/wiki#mutex_atomic) | warn | using a mutex where an atomic value could be used instead

clippy_lints/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry) {
377377
misc::TOPLEVEL_REF_ARG,
378378
misc_early::DOUBLE_NEG,
379379
misc_early::DUPLICATE_UNDERSCORE_ARGUMENT,
380+
misc_early::MIXED_CASE_HEX_LITERALS,
380381
misc_early::REDUNDANT_CLOSURE_CALL,
381382
misc_early::UNNEEDED_FIELD_PATTERN,
382383
mut_reference::UNNECESSARY_MUT_PASSED,

clippy_lints/src/misc_early.rs

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use std::collections::HashMap;
33
use syntax::ast::*;
44
use syntax::codemap::Span;
55
use syntax::visit::FnKind;
6-
use utils::{span_lint, span_help_and_lint, snippet, span_lint_and_then};
6+
use utils::{span_lint, span_help_and_lint, snippet, snippet_opt, span_lint_and_then};
77
/// **What it does:** This lint checks for structure field patterns bound to wildcards.
88
///
99
/// **Why is this bad?** Using `..` instead is shorter and leaves the focus on the fields that are actually bound.
@@ -64,13 +64,29 @@ declare_lint! {
6464
"`--x` is a double negation of `x` and not a pre-decrement as in C or C++"
6565
}
6666

67+
/// **What it does:** Warns on hexadecimal literals with mixed-case letter digits.
68+
///
69+
/// **Why is this bad?** It looks confusing.
70+
///
71+
/// **Known problems:** None.
72+
///
73+
/// **Example:**
74+
/// ```rust
75+
/// let y = 0x1a9BAcD;
76+
/// ```
77+
declare_lint! {
78+
pub MIXED_CASE_HEX_LITERALS, Warn,
79+
"letter digits in hex literals should be either completely upper- or lowercased"
80+
}
81+
6782

6883
#[derive(Copy, Clone)]
6984
pub struct MiscEarly;
7085

7186
impl LintPass for MiscEarly {
7287
fn get_lints(&self) -> LintArray {
73-
lint_array!(UNNEEDED_FIELD_PATTERN, DUPLICATE_UNDERSCORE_ARGUMENT, REDUNDANT_CLOSURE_CALL, DOUBLE_NEG)
88+
lint_array!(UNNEEDED_FIELD_PATTERN, DUPLICATE_UNDERSCORE_ARGUMENT, REDUNDANT_CLOSURE_CALL,
89+
DOUBLE_NEG, MIXED_CASE_HEX_LITERALS)
7490
}
7591
}
7692

@@ -174,7 +190,28 @@ impl EarlyLintPass for MiscEarly {
174190
DOUBLE_NEG,
175191
expr.span,
176192
"`--x` could be misinterpreted as pre-decrement by C programmers, is usually a no-op");
177-
}
193+
}
194+
}
195+
ExprKind::Lit(ref lit) => {
196+
if_let_chain! {[
197+
let LitKind::Int(..) = lit.node,
198+
let Some(src) = snippet_opt(cx, lit.span),
199+
src.starts_with("0x")
200+
], {
201+
let mut seen = (false, false);
202+
for ch in src.chars() {
203+
match ch {
204+
'a' ... 'f' => seen.0 = true,
205+
'A' ... 'F' => seen.1 = true,
206+
'i' | 'u' => break, // start of suffix already
207+
_ => ()
208+
}
209+
}
210+
if seen.0 && seen.1 {
211+
span_lint(cx, MIXED_CASE_HEX_LITERALS, lit.span,
212+
"inconsistent casing in hexadecimal literal");
213+
}
214+
}}
178215
}
179216
_ => ()
180217
}

tests/compile-fail/literals.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#![feature(plugin)]
2+
#![plugin(clippy)]
3+
#![deny(mixed_case_hex_literals)]
4+
#![allow(dead_code)]
5+
6+
fn main() {
7+
let ok1 = 0xABCD;
8+
let ok3 = 0xab_cd;
9+
let ok4 = 0xab_cd_i32;
10+
let ok5 = 0xAB_CD_u32;
11+
let ok5 = 0xAB_CD_isize;
12+
let fail1 = 0xabCD; //~ERROR inconsistent casing in hexadecimal literal
13+
let fail2 = 0xabCD_u32; //~ERROR inconsistent casing in hexadecimal literal
14+
let fail2 = 0xabCD_isize; //~ERROR inconsistent casing in hexadecimal literal
15+
}

0 commit comments

Comments
 (0)