3
3
use std:: borrow:: Cow ;
4
4
use std:: cmp:: Ordering ;
5
5
use std:: collections:: BTreeMap ;
6
- use std:: fmt:: Display ;
7
6
8
7
use if_chain:: if_chain;
9
8
use rustc_ast:: { FloatTy , IntTy , LitFloatType , LitIntType , LitKind , UintTy } ;
@@ -13,7 +12,7 @@ use rustc_hir::intravisit::{walk_body, walk_expr, walk_ty, FnKind, NestedVisitor
13
12
use rustc_hir:: {
14
13
BinOpKind , Block , Body , Expr , ExprKind , FnDecl , FnRetTy , FnSig , GenericArg , GenericParamKind , HirId , ImplItem ,
15
14
ImplItemKind , Item , ItemKind , Lifetime , Local , MatchSource , MutTy , Mutability , Node , QPath , Stmt , StmtKind ,
16
- TraitFn , TraitItem , TraitItemKind , TyKind , UnOp ,
15
+ TraitFn , TraitItem , TraitItemKind , TyKind , UnOp , Lit ,
17
16
} ;
18
17
use rustc_lint:: { LateContext , LateLintPass , LintContext } ;
19
18
use rustc_middle:: hir:: map:: Map ;
@@ -1225,7 +1224,8 @@ declare_clippy_lint! {
1225
1224
}
1226
1225
1227
1226
declare_clippy_lint ! {
1228
- /// **What it does:** Checks for casts to the same type.
1227
+ /// **What it does:** Checks for casts to the same type, casts of int literals to integer types
1228
+ /// and casts of float literals to float types.
1229
1229
///
1230
1230
/// **Why is this bad?** It's just unnecessary.
1231
1231
///
@@ -1234,6 +1234,7 @@ declare_clippy_lint! {
1234
1234
/// **Example:**
1235
1235
/// ```rust
1236
1236
/// let _ = 2i32 as i32;
1237
+ /// let _ = 0.5 as f32;
1237
1238
/// ```
1238
1239
pub UNNECESSARY_CAST ,
1239
1240
complexity,
@@ -1599,7 +1600,9 @@ impl<'tcx> LateLintPass<'tcx> for Casts {
1599
1600
if let ExprKind :: Cast ( ref ex, _) = expr. kind {
1600
1601
let ( cast_from, cast_to) = ( cx. typeck_results ( ) . expr_ty ( ex) , cx. typeck_results ( ) . expr_ty ( expr) ) ;
1601
1602
lint_fn_to_numeric_cast ( cx, expr, ex, cast_from, cast_to) ;
1602
- if let ExprKind :: Lit ( ref lit) = ex. kind {
1603
+ if let Some ( lit) = get_numeric_literal ( ex) {
1604
+ let literal_str = snippet_opt ( cx, lit. span ) . unwrap_or_default ( ) ;
1605
+
1603
1606
if_chain ! {
1604
1607
if let LitKind :: Int ( n, _) = lit. node;
1605
1608
if let Some ( src) = snippet_opt( cx, lit. span) ;
@@ -1609,25 +1612,19 @@ impl<'tcx> LateLintPass<'tcx> for Casts {
1609
1612
let to_nbits = fp_ty_mantissa_nbits( cast_to) ;
1610
1613
if from_nbits != 0 && to_nbits != 0 && from_nbits <= to_nbits && num_lit. is_decimal( ) ;
1611
1614
then {
1612
- show_unnecessary_cast( cx, expr, n , cast_from, cast_to) ;
1615
+ show_unnecessary_cast( cx, expr, num_lit . integer , cast_from, cast_to) ;
1613
1616
return ;
1614
1617
}
1615
1618
}
1616
1619
1617
1620
match lit. node {
1618
- LitKind :: Int ( num, LitIntType :: Unsuffixed ) if cast_to. is_integral ( ) => {
1619
- show_unnecessary_cast ( cx, expr, num, cast_from, cast_to) ;
1620
- return ;
1621
+ LitKind :: Int ( _, LitIntType :: Unsuffixed ) if cast_to. is_integral ( ) => {
1622
+ show_unnecessary_cast ( cx, expr, & literal_str, cast_from, cast_to) ;
1621
1623
} ,
1622
- LitKind :: Float ( num, LitFloatType :: Unsuffixed ) if cast_to. is_floating_point ( ) => {
1623
- show_unnecessary_cast ( cx, expr, num, cast_from, cast_to) ;
1624
- return ;
1624
+ LitKind :: Float ( _, LitFloatType :: Unsuffixed ) if cast_to. is_floating_point ( ) => {
1625
+ show_unnecessary_cast ( cx, expr, & literal_str, cast_from, cast_to) ;
1625
1626
} ,
1626
- _ => ( ) ,
1627
- } ;
1628
-
1629
- match lit. node {
1630
- LitKind :: Int ( _, LitIntType :: Unsuffixed ) | LitKind :: Float ( _, LitFloatType :: Unsuffixed ) => { } ,
1627
+ LitKind :: Int ( _, LitIntType :: Unsuffixed ) | LitKind :: Float ( _, LitFloatType :: Unsuffixed ) => ( ) ,
1631
1628
_ => {
1632
1629
if cast_from. kind ( ) == cast_to. kind ( ) && !in_external_macro ( cx. sess ( ) , expr. span ) {
1633
1630
span_lint (
@@ -1640,7 +1637,7 @@ impl<'tcx> LateLintPass<'tcx> for Casts {
1640
1637
) ,
1641
1638
) ;
1642
1639
}
1643
- } ,
1640
+ }
1644
1641
}
1645
1642
}
1646
1643
if cast_from. is_numeric ( ) && cast_to. is_numeric ( ) && !in_external_macro ( cx. sess ( ) , expr. span ) {
@@ -1652,10 +1649,24 @@ impl<'tcx> LateLintPass<'tcx> for Casts {
1652
1649
}
1653
1650
}
1654
1651
1655
- fn show_unnecessary_cast < Num : Display > (
1652
+ fn get_numeric_literal < ' e > ( expr : & ' e Expr < ' e > ) -> Option < & ' e Lit > {
1653
+ match expr. kind {
1654
+ ExprKind :: Lit ( ref lit) => Some ( lit) ,
1655
+ ExprKind :: Unary ( UnOp :: UnNeg , e) => {
1656
+ if let ExprKind :: Lit ( ref lit) = e. kind {
1657
+ Some ( lit)
1658
+ } else {
1659
+ None
1660
+ }
1661
+ } ,
1662
+ _ => None ,
1663
+ }
1664
+ }
1665
+
1666
+ fn show_unnecessary_cast (
1656
1667
cx : & LateContext < ' _ > ,
1657
1668
expr : & Expr < ' _ > ,
1658
- num : Num ,
1669
+ literal_str : & str ,
1659
1670
cast_from : Ty < ' _ > ,
1660
1671
cast_to : Ty < ' _ > ,
1661
1672
) {
@@ -1666,7 +1677,7 @@ fn show_unnecessary_cast<Num: Display>(
1666
1677
expr. span ,
1667
1678
& format ! ( "casting {} literal to `{}` is unnecessary" , literal_kind_name, cast_to) ,
1668
1679
"try" ,
1669
- format ! ( "{}_{}" , num , cast_to) ,
1680
+ format ! ( "{}_{}" , literal_str , cast_to) ,
1670
1681
Applicability :: MachineApplicable ,
1671
1682
) ;
1672
1683
}
0 commit comments