about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorllogiq <bogusandre@gmail.com>2016-01-27 22:22:43 +0100
committerllogiq <bogusandre@gmail.com>2016-01-27 22:23:21 +0100
commit291b73b8e89c20e72d0e16da150fc6a8a1e8d188 (patch)
treed4ce76be5cbbbc67220e0a3fbc441cd00cb8e659 /src
parenta1ac3125de6ae7cb0ffffd845df28b3ba3872a19 (diff)
parent148667ce05d718105d91b7b91b31893150d4f121 (diff)
downloadrust-291b73b8e89c20e72d0e16da150fc6a8a1e8d188.tar.gz
rust-291b73b8e89c20e72d0e16da150fc6a8a1e8d188.zip
Merge master and re-run update_lints.py
Diffstat (limited to 'src')
-rw-r--r--src/lib.rs2
-rw-r--r--src/types.rs40
2 files changed, 42 insertions, 0 deletions
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);
+                    }
+                }
+            }
+        }
+    }
+}