]> git.lizzy.rs Git - rust.git/commitdiff
Add lint for unnecessary casts (cast to same type)
authorBood Qian <bood@glowing.com>
Wed, 15 Feb 2017 14:20:20 +0000 (22:20 +0800)
committerBood Qian <bood@glowing.com>
Wed, 15 Feb 2017 14:20:20 +0000 (22:20 +0800)
CHANGELOG.md
README.md
clippy_lints/src/lib.rs
clippy_lints/src/types.rs
tests/ui/cast.rs
tests/ui/cast.stderr

index 7ca1336afaf82b11d067de50057e941a50a9c545..a32224c1de1f75ccdc1d249a67d66bf08a8a6e44 100644 (file)
@@ -293,6 +293,7 @@ All notable changes to this project will be documented in this file.
 [`cast_possible_wrap`]: https://github.com/Manishearth/rust-clippy/wiki#cast_possible_wrap
 [`cast_precision_loss`]: https://github.com/Manishearth/rust-clippy/wiki#cast_precision_loss
 [`cast_sign_loss`]: https://github.com/Manishearth/rust-clippy/wiki#cast_sign_loss
+[`cast_unnecessary`]: https://github.com/Manishearth/rust-clippy/wiki#cast_unnecessary
 [`char_lit_as_u8`]: https://github.com/Manishearth/rust-clippy/wiki#char_lit_as_u8
 [`chars_next_cmp`]: https://github.com/Manishearth/rust-clippy/wiki#chars_next_cmp
 [`clone_double_ref`]: https://github.com/Manishearth/rust-clippy/wiki#clone_double_ref
index 0a6a62e9185212032bb566333ea18b5f6e1a1203..a402b87f079c4ef3eb3564286c31798df952a9d6 100644 (file)
--- a/README.md
+++ b/README.md
@@ -180,7 +180,7 @@ transparently:
 
 ## Lints
 
-There are 189 lints included in this crate:
+There are 190 lints included in this crate:
 
 name                                                                                                                   | default | triggers on
 -----------------------------------------------------------------------------------------------------------------------|---------|----------------------------------------------------------------------------------------------------------------------------------
@@ -201,6 +201,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`
+[cast_unnecessary](https://github.com/Manishearth/rust-clippy/wiki#cast_unnecessary)                                   | warn    | cast to the same type, e.g `x as i32` 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
 [clone_double_ref](https://github.com/Manishearth/rust-clippy/wiki#clone_double_ref)                                   | warn    | using `clone` on `&&T`
index 80a369513e2c8c1d478ac24e931999e4928f47a1..93eb449ebe0667b35a627c11df550475324dc02f 100644 (file)
@@ -488,6 +488,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry) {
         transmute::WRONG_TRANSMUTE,
         types::ABSURD_EXTREME_COMPARISONS,
         types::BOX_VEC,
+        types::CAST_UNNECESSARY,
         types::CHAR_LIT_AS_U8,
         types::LET_UNIT_VALUE,
         types::LINKEDLIST,
index b1581127c3250333b3fc8c6afe71e8be86b1370e..161b2a1226cd8abbed0c17fa24ad5befc5d167d9 100644 (file)
@@ -379,6 +379,22 @@ fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) {
      and `x > i32::MAX`"
 }
 
+/// **What it does:** Checks for casts to the same type
+///
+/// **Why is this bad?** It's just unnecessary
+///
+/// **Known problems:** None.
+///
+/// **Example:**
+/// ```rust
+/// let _ = 2i32 as i32
+/// ```
+declare_lint! {
+    pub CAST_UNNECESSARY,
+    Warn,
+    "cast to the same type, e.g `x as i32` where `x: i32`"
+}
+
 /// Returns the size in bits of an integral type.
 /// Will return 0 if the type is not an int or uint variant
 fn int_ty_to_nbits(typ: &ty::TyS) -> usize {
@@ -503,7 +519,8 @@ fn get_lints(&self) -> LintArray {
         lint_array!(CAST_PRECISION_LOSS,
                     CAST_SIGN_LOSS,
                     CAST_POSSIBLE_TRUNCATION,
-                    CAST_POSSIBLE_WRAP)
+                    CAST_POSSIBLE_WRAP,
+                    CAST_UNNECESSARY)
     }
 }
 
@@ -511,6 +528,12 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for CastPass {
     fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) {
         if let ExprCast(ref ex, _) = expr.node {
             let (cast_from, cast_to) = (cx.tables.expr_ty(ex), cx.tables.expr_ty(expr));
+            if cast_from.sty == cast_to.sty && !in_external_macro(cx, expr.span) {
+                span_lint(cx,
+                          CAST_UNNECESSARY,
+                          expr.span,
+                          &format!("casting to the same type is unnecessary ({} -> {})", cast_from, cast_to));
+            }
             if cast_from.is_numeric() && cast_to.is_numeric() && !in_external_macro(cx, expr.span) {
                 match (cast_from.is_integral(), cast_to.is_integral()) {
                     (true, false) => {
index ca5106102e9cc4255f9d064259fa4942595a8b60..7b64b50a1caf2a0a8e93046e6af334b54411141f 100644 (file)
@@ -61,4 +61,15 @@ fn main() {
     1u32 as usize; // Should not trigger any lint
     1i32 as isize; // Neither should this
     1i32 as usize;
+
+    // Test cast_unnecessary
+    1i32 as i32;
+    1f32 as f32;
+    false as bool;
+    &1i32 as &i32;
+
+    1i32 as i64;      // Should not trigger
+
+    let v = vec!(1);
+    &v as &[i32]; // Should not trigger
 }
index f4d8ec21d8d9b3263ad0e7888f9c1d7cef86a314..289d1d0ac4ffcf0698ac82058373a113e134c85c 100644 (file)
@@ -274,5 +274,37 @@ error: casting i32 to usize may lose the sign of the value
 63 |     1i32 as usize;
    |     ^^^^^^^^^^^^^
 
+warning: casting to the same type is unnecessary (i32 -> i32)
+  --> $DIR/cast.rs:66:5
+   |
+66 |     1i32 as i32;
+   |     ^^^^^^^^^^^
+   |
+   = note: #[warn(cast_unnecessary)] on by default
+
+warning: casting to the same type is unnecessary (f32 -> f32)
+  --> $DIR/cast.rs:67:5
+   |
+67 |     1f32 as f32;
+   |     ^^^^^^^^^^^
+   |
+   = note: #[warn(cast_unnecessary)] on by default
+
+warning: casting to the same type is unnecessary (bool -> bool)
+  --> $DIR/cast.rs:68:5
+   |
+68 |     false as bool;
+   |     ^^^^^^^^^^^^^
+   |
+   = note: #[warn(cast_unnecessary)] on by default
+
+warning: casting to the same type is unnecessary (&i32 -> &i32)
+  --> $DIR/cast.rs:69:5
+   |
+69 |     &1i32 as &i32;
+   |     ^^^^^^^^^^^^^
+   |
+   = note: #[warn(cast_unnecessary)] on by default
+
 error: aborting due to 42 previous errors