@@ -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 ( ) ;
@@ -1487,29 +1486,40 @@ declare_clippy_lint! {
1487
1486
/// ```
1488
1487
pub CHAR_LIT_AS_U8 ,
1489
1488
complexity,
1490
- "casting a character literal to u8"
1489
+ "casting a character literal to u8 truncates "
1491
1490
}
1492
1491
1493
1492
declare_lint_pass ! ( CharLitAsU8 => [ CHAR_LIT_AS_U8 ] ) ;
1494
1493
1495
1494
impl < ' a , ' tcx > LateLintPass < ' a , ' tcx > for CharLitAsU8 {
1496
1495
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
+ } ) ;
1513
1523
}
1514
1524
}
1515
1525
}
0 commit comments