[`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
## Lints
-There are 189 lints included in this crate:
+There are 190 lints included in this crate:
name | default | triggers on
-----------------------------------------------------------------------------------------------------------------------|---------|----------------------------------------------------------------------------------------------------------------------------------
[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`
transmute::WRONG_TRANSMUTE,
types::ABSURD_EXTREME_COMPARISONS,
types::BOX_VEC,
+ types::CAST_UNNECESSARY,
types::CHAR_LIT_AS_U8,
types::LET_UNIT_VALUE,
types::LINKEDLIST,
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 {
lint_array!(CAST_PRECISION_LOSS,
CAST_SIGN_LOSS,
CAST_POSSIBLE_TRUNCATION,
- CAST_POSSIBLE_WRAP)
+ CAST_POSSIBLE_WRAP,
+ CAST_UNNECESSARY)
}
}
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) => {
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
}
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