@@ -15,7 +15,7 @@ use rustc::{declare_lint_pass, declare_tool_lint, impl_lint_pass};
15
15
use rustc_errors:: Applicability ;
16
16
use rustc_target:: spec:: abi:: Abi ;
17
17
use rustc_typeck:: hir_ty_to_ty;
18
- use syntax:: ast:: { FloatTy , IntTy , UintTy } ;
18
+ use syntax:: ast:: { FloatTy , IntTy , LitIntType , LitKind , UintTy } ;
19
19
use syntax:: errors:: DiagnosticBuilder ;
20
20
use syntax:: source_map:: Span ;
21
21
use syntax:: symbol:: sym;
@@ -1122,7 +1122,6 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Casts {
1122
1122
let ( cast_from, cast_to) = ( cx. tables . expr_ty ( ex) , cx. tables . expr_ty ( expr) ) ;
1123
1123
lint_fn_to_numeric_cast ( cx, expr, ex, cast_from, cast_to) ;
1124
1124
if let ExprKind :: Lit ( ref lit) = ex. node {
1125
- use syntax:: ast:: { LitIntType , LitKind } ;
1126
1125
if let LitKind :: Int ( n, _) = lit. node {
1127
1126
if cast_to. is_floating_point ( ) {
1128
1127
let from_nbits = 128 - n. leading_zeros ( ) ;
@@ -1473,29 +1472,40 @@ declare_clippy_lint! {
1473
1472
/// ```
1474
1473
pub CHAR_LIT_AS_U8 ,
1475
1474
complexity,
1476
- "casting a character literal to u8"
1475
+ "casting a character literal to u8 truncates "
1477
1476
}
1478
1477
1479
1478
declare_lint_pass ! ( CharLitAsU8 => [ CHAR_LIT_AS_U8 ] ) ;
1480
1479
1481
1480
impl < ' a , ' tcx > LateLintPass < ' a , ' tcx > for CharLitAsU8 {
1482
1481
fn check_expr ( & mut self , cx : & LateContext < ' a , ' tcx > , expr : & ' tcx Expr ) {
1483
- use syntax:: ast:: LitKind ;
1484
-
1485
- if let ExprKind :: Cast ( ref e, _) = expr. node {
1486
- if let ExprKind :: Lit ( ref l) = e. node {
1487
- if let LitKind :: Char ( _) = l. node {
1488
- if ty:: Uint ( UintTy :: U8 ) == cx. tables . expr_ty ( expr) . sty && !expr. span . from_expansion ( ) {
1489
- let msg = "casting character literal to u8. `char`s \
1490
- are 4 bytes wide in rust, so casting to u8 \
1491
- truncates them";
1492
- let help = format ! (
1493
- "Consider using a byte literal instead:\n b{}" ,
1494
- snippet( cx, e. span, "'x'" )
1495
- ) ;
1496
- span_help_and_lint ( cx, CHAR_LIT_AS_U8 , expr. span , msg, & help) ;
1497
- }
1498
- }
1482
+ if_chain ! {
1483
+ if !expr. span. from_expansion( ) ;
1484
+ if let ExprKind :: Cast ( e, _) = & expr. node;
1485
+ if let ExprKind :: Lit ( l) = & e. node;
1486
+ if let LitKind :: Char ( c) = l. node;
1487
+ if ty:: Uint ( UintTy :: U8 ) == cx. tables. expr_ty( expr) . sty;
1488
+ then {
1489
+ let mut applicability = Applicability :: MachineApplicable ;
1490
+ let snippet = snippet_with_applicability( cx, e. span, "'x'" , & mut applicability) ;
1491
+
1492
+ span_lint_and_then(
1493
+ cx,
1494
+ CHAR_LIT_AS_U8 ,
1495
+ expr. span,
1496
+ "casting a character literal to `u8` truncates" ,
1497
+ |db| {
1498
+ db. note( "`char` is four bytes wide, but `u8` is a single byte" ) ;
1499
+
1500
+ if c. is_ascii( ) {
1501
+ db. span_suggestion(
1502
+ expr. span,
1503
+ "use a byte literal instead" ,
1504
+ format!( "b{}" , snippet) ,
1505
+ applicability,
1506
+ ) ;
1507
+ }
1508
+ } ) ;
1499
1509
}
1500
1510
}
1501
1511
}
0 commit comments