@@ -15,7 +15,7 @@ use rustc::{declare_lint_pass, declare_tool_lint, impl_lint_pass};
1515use rustc_errors:: Applicability ;
1616use rustc_target:: spec:: abi:: Abi ;
1717use rustc_typeck:: hir_ty_to_ty;
18- use syntax:: ast:: { FloatTy , IntTy , UintTy } ;
18+ use syntax:: ast:: { FloatTy , IntTy , LitIntType , LitKind , UintTy } ;
1919use syntax:: errors:: DiagnosticBuilder ;
2020use syntax:: source_map:: Span ;
2121use syntax:: symbol:: sym;
@@ -1122,7 +1122,6 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Casts {
11221122 let ( cast_from, cast_to) = ( cx. tables . expr_ty ( ex) , cx. tables . expr_ty ( expr) ) ;
11231123 lint_fn_to_numeric_cast ( cx, expr, ex, cast_from, cast_to) ;
11241124 if let ExprKind :: Lit ( ref lit) = ex. node {
1125- use syntax:: ast:: { LitIntType , LitKind } ;
11261125 if let LitKind :: Int ( n, _) = lit. node {
11271126 if cast_to. is_floating_point ( ) {
11281127 let from_nbits = 128 - n. leading_zeros ( ) ;
@@ -1487,29 +1486,40 @@ declare_clippy_lint! {
14871486 /// ```
14881487 pub CHAR_LIT_AS_U8 ,
14891488 complexity,
1490- "casting a character literal to u8"
1489+ "casting a character literal to u8 truncates "
14911490}
14921491
14931492declare_lint_pass ! ( CharLitAsU8 => [ CHAR_LIT_AS_U8 ] ) ;
14941493
14951494impl < ' a , ' tcx > LateLintPass < ' a , ' tcx > for CharLitAsU8 {
14961495 fn check_expr ( & mut self , cx : & LateContext < ' a , ' tcx > , expr : & ' tcx Expr ) {
1497- use syntax:: ast:: LitKind ;
1498-
1499- if let ExprKind :: Cast ( ref e, _) = expr. node {
1500- if let ExprKind :: Lit ( ref l) = e. node {
1501- if let LitKind :: Char ( _) = l. node {
1502- if ty:: Uint ( UintTy :: U8 ) == cx. tables . expr_ty ( expr) . sty && !expr. span . from_expansion ( ) {
1503- let msg = "casting character literal to u8. `char`s \
1504- are 4 bytes wide in rust, so casting to u8 \
1505- truncates them";
1506- let help = format ! (
1507- "Consider using a byte literal instead:\n b{}" ,
1508- snippet( cx, e. span, "'x'" )
1509- ) ;
1510- span_help_and_lint ( cx, CHAR_LIT_AS_U8 , expr. span , msg, & help) ;
1511- }
1512- }
1496+ if_chain ! {
1497+ if !expr. span. from_expansion( ) ;
1498+ if let ExprKind :: Cast ( e, _) = & expr. node;
1499+ if let ExprKind :: Lit ( l) = & e. node;
1500+ if let LitKind :: Char ( c) = l. node;
1501+ if ty:: Uint ( UintTy :: U8 ) == cx. tables. expr_ty( expr) . sty;
1502+ then {
1503+ let mut applicability = Applicability :: MachineApplicable ;
1504+ let snippet = snippet_with_applicability( cx, e. span, "'x'" , & mut applicability) ;
1505+
1506+ span_lint_and_then(
1507+ cx,
1508+ CHAR_LIT_AS_U8 ,
1509+ expr. span,
1510+ "casting a character literal to `u8` truncates" ,
1511+ |db| {
1512+ db. note( "`char` is four bytes wide, but `u8` is a single byte" ) ;
1513+
1514+ if c. is_ascii( ) {
1515+ db. span_suggestion(
1516+ expr. span,
1517+ "use a byte literal instead" ,
1518+ format!( "b{}" , snippet) ,
1519+ applicability,
1520+ ) ;
1521+ }
1522+ } ) ;
15131523 }
15141524 }
15151525 }
0 commit comments