diff options
| author | llogiq <bogusandre@gmail.com> | 2016-01-27 22:22:43 +0100 |
|---|---|---|
| committer | llogiq <bogusandre@gmail.com> | 2016-01-27 22:23:21 +0100 |
| commit | 291b73b8e89c20e72d0e16da150fc6a8a1e8d188 (patch) | |
| tree | d4ce76be5cbbbc67220e0a3fbc441cd00cb8e659 | |
| parent | a1ac3125de6ae7cb0ffffd845df28b3ba3872a19 (diff) | |
| parent | 148667ce05d718105d91b7b91b31893150d4f121 (diff) | |
| download | rust-291b73b8e89c20e72d0e16da150fc6a8a1e8d188.tar.gz rust-291b73b8e89c20e72d0e16da150fc6a8a1e8d188.zip | |
Merge master and re-run update_lints.py
| -rw-r--r-- | README.md | 3 | ||||
| -rw-r--r-- | src/lib.rs | 2 | ||||
| -rw-r--r-- | src/types.rs | 40 | ||||
| -rw-r--r-- | tests/compile-fail/char_lit_as_u8.rs | 8 | ||||
| -rwxr-xr-x | util/update_lints.py | 2 |
5 files changed, 53 insertions, 2 deletions
diff --git a/README.md b/README.md index 290684d3bad..04b0bd0e384 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ A collection of lints to catch common mistakes and improve your Rust code. [Jump to usage instructions](#usage) ##Lints -There are 99 lints included in this crate: +There are 100 lints included in this crate: name | default | meaning ---------------------------------------------------------------------------------------------------------------|---------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ @@ -20,6 +20,7 @@ name [cast_possible_wrap](https://github.com/Manishearth/rust-clippy/wiki#cast_possible_wrap) | allow | casts that may cause wrapping around the value, e.g `x as i32` where `x: u32` and `x > i32::MAX` [cast_precision_loss](https://github.com/Manishearth/rust-clippy/wiki#cast_precision_loss) | allow | casts that cause loss of precision, e.g `x as f32` where `x: u64` [cast_sign_loss](https://github.com/Manishearth/rust-clippy/wiki#cast_sign_loss) | allow | casts from signed types to unsigned types, e.g `x as u32` where `x: i32` +[char_lit_as_u8](https://github.com/Manishearth/rust-clippy/wiki#char_lit_as_u8) | warn | Casting a character literal to u8 [chars_next_cmp](https://github.com/Manishearth/rust-clippy/wiki#chars_next_cmp) | warn | using `.chars().next()` to check if a string starts with a char [cmp_nan](https://github.com/Manishearth/rust-clippy/wiki#cmp_nan) | deny | comparisons to NAN (which will always return false, which is probably not intended) [cmp_owned](https://github.com/Manishearth/rust-clippy/wiki#cmp_owned) | warn | creating owned instances for comparing with others, e.g. `x == "foo".to_string()` diff --git a/src/lib.rs b/src/lib.rs index f44191b562d..6d706888fc3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -140,6 +140,7 @@ pub fn plugin_registrar(reg: &mut Registry) { reg.register_late_lint_pass(box panic::PanicPass); reg.register_late_lint_pass(box strings::StringLitAsBytes); reg.register_late_lint_pass(box derive::Derive); + reg.register_late_lint_pass(box types::CharLitAsU8); reg.register_lint_group("clippy_pedantic", vec![ @@ -239,6 +240,7 @@ pub fn plugin_registrar(reg: &mut Registry) { temporary_assignment::TEMPORARY_ASSIGNMENT, transmute::USELESS_TRANSMUTE, types::BOX_VEC, + types::CHAR_LIT_AS_U8, types::LET_UNIT_VALUE, types::LINKEDLIST, types::TYPE_COMPLEXITY, diff --git a/src/types.rs b/src/types.rs index 427b695d385..d41896cd490 100644 --- a/src/types.rs +++ b/src/types.rs @@ -517,3 +517,43 @@ impl<'v> Visitor<'v> for TypeComplexityVisitor { self.nest -= sub_nest; } } + +/// **What it does:** This lint points out expressions where a character literal is casted to u8 and suggests using a byte literal instead. +/// +/// **Why is this bad?** In general, casting values to smaller types is error-prone and should be avoided where possible. In the particular case of converting a character literal to u8, it is easy to avoid by just using a byte literal instead. As an added bonus, `b'a'` is even slightly shorter than `'a' as u8`. +/// +/// **Known problems:** None +/// +/// **Example:** `'x' as u8` +declare_lint!(pub CHAR_LIT_AS_U8, Warn, + "Casting a character literal to u8"); + +pub struct CharLitAsU8; + +impl LintPass for CharLitAsU8 { + fn get_lints(&self) -> LintArray { + lint_array!(CHAR_LIT_AS_U8) + } +} + +impl LateLintPass for CharLitAsU8 { + fn check_expr(&mut self, cx: &LateContext, expr: &Expr) { + use syntax::ast::{Lit_, UintTy}; + + if let ExprCast(ref e, _) = expr.node { + if let ExprLit(ref l) = e.node { + if let Lit_::LitChar(_) = l.node { + if ty::TyUint(UintTy::TyU8) == cx.tcx.expr_ty(expr).sty && !in_macro(cx, expr.span) { + let msg = "casting character literal to u8. `char`s \ + are 4 bytes wide in rust, so casting to u8 \ + truncates them"; + let help = format!("Consider using a byte literal \ + instead:\nb{}", + snippet(cx, e.span, "'x'")); + span_help_and_lint(cx, CHAR_LIT_AS_U8, expr.span, msg, &help); + } + } + } + } + } +} diff --git a/tests/compile-fail/char_lit_as_u8.rs b/tests/compile-fail/char_lit_as_u8.rs new file mode 100644 index 00000000000..4fca878c4da --- /dev/null +++ b/tests/compile-fail/char_lit_as_u8.rs @@ -0,0 +1,8 @@ +#![feature(plugin)] +#![plugin(clippy)] + +#![deny(char_lit_as_u8)] +#![allow(unused_variables)] +fn main() { + let c = 'a' as u8; //~ERROR casting character literal +} diff --git a/util/update_lints.py b/util/update_lints.py index 94b2a3a57ba..6a59abcdc15 100755 --- a/util/update_lints.py +++ b/util/update_lints.py @@ -9,7 +9,7 @@ import sys declare_lint_re = re.compile(r''' declare_lint! \s* [{(] \s* - pub \s+ (?P<name>[A-Z_]+) \s*,\s* + pub \s+ (?P<name>[A-Z_][A-Z_0-9]*) \s*,\s* (?P<level>Forbid|Deny|Warn|Allow) \s*,\s* " (?P<desc>(?:[^"\\]+|\\.)*) " \s* [})] ''', re.X | re.S) |
