about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorFlorian Hartwig <florian.j.hartwig@gmail.com>2016-01-27 20:23:59 +0100
committerFlorian Hartwig <florian.j.hartwig@gmail.com>2016-01-27 20:23:59 +0100
commit04f9d35f64b0a08a6ea2ff6ce8ceab358526cade (patch)
treee66df6f70b8832dab0e85878a23bfb1ad0f1c68c /src
parent5f17b38bf26a2124c7c8ae9695c20abafafd53b9 (diff)
downloadrust-04f9d35f64b0a08a6ea2ff6ce8ceab358526cade.tar.gz
rust-04f9d35f64b0a08a6ea2ff6ce8ceab358526cade.zip
Add a lint for casts from char literals to u8
Diffstat (limited to 'src')
-rw-r--r--src/lib.rs1
-rw-r--r--src/types.rs38
2 files changed, 39 insertions, 0 deletions
diff --git a/src/lib.rs b/src/lib.rs
index c43c01268fe..731778db606 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![
diff --git a/src/types.rs b/src/types.rs
index 427b695d385..42824c36ec6 100644
--- a/src/types.rs
+++ b/src/types.rs
@@ -517,3 +517,41 @@ 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.";
+                        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);
+                    }
+                }
+            }
+        }
+    }
+}