@@ -5,6 +5,7 @@ mod cast_precision_loss;
5
5
mod cast_ptr_alignment;
6
6
mod cast_ref_to_mut;
7
7
mod cast_sign_loss;
8
+ mod char_lit_as_u8;
8
9
mod fn_to_numeric_cast;
9
10
mod fn_to_numeric_cast_with_truncation;
10
11
mod unnecessary_cast;
@@ -13,19 +14,16 @@ mod utils;
13
14
use std:: borrow:: Cow ;
14
15
15
16
use if_chain:: if_chain;
16
- use rustc_ast:: LitKind ;
17
17
use rustc_errors:: Applicability ;
18
18
use rustc_hir:: { Expr , ExprKind , Mutability , TyKind } ;
19
19
use rustc_lint:: { LateContext , LateLintPass , LintContext } ;
20
20
use rustc_middle:: lint:: in_external_macro;
21
- use rustc_middle:: ty:: { self , TypeAndMut , UintTy } ;
21
+ use rustc_middle:: ty:: { self , TypeAndMut } ;
22
22
use rustc_semver:: RustcVersion ;
23
23
use rustc_session:: { declare_lint_pass, declare_tool_lint, impl_lint_pass} ;
24
24
25
25
use crate :: utils:: sugg:: Sugg ;
26
- use crate :: utils:: {
27
- is_hir_ty_cfg_dependant, meets_msrv, snippet_with_applicability, span_lint_and_sugg, span_lint_and_then,
28
- } ;
26
+ use crate :: utils:: { is_hir_ty_cfg_dependant, meets_msrv, span_lint_and_sugg} ;
29
27
30
28
declare_clippy_lint ! {
31
29
/// **What it does:** Checks for casts from any numerical to a float type where
@@ -290,17 +288,45 @@ declare_clippy_lint! {
290
288
"a cast of reference to a mutable pointer"
291
289
}
292
290
291
+ declare_clippy_lint ! {
292
+ /// **What it does:** Checks for expressions where a character literal is cast
293
+ /// to `u8` and suggests using a byte literal instead.
294
+ ///
295
+ /// **Why is this bad?** In general, casting values to smaller types is
296
+ /// error-prone and should be avoided where possible. In the particular case of
297
+ /// converting a character literal to u8, it is easy to avoid by just using a
298
+ /// byte literal instead. As an added bonus, `b'a'` is even slightly shorter
299
+ /// than `'a' as u8`.
300
+ ///
301
+ /// **Known problems:** None.
302
+ ///
303
+ /// **Example:**
304
+ /// ```rust,ignore
305
+ /// 'x' as u8
306
+ /// ```
307
+ ///
308
+ /// A better version, using the byte literal:
309
+ ///
310
+ /// ```rust,ignore
311
+ /// b'x'
312
+ /// ```
313
+ pub CHAR_LIT_AS_U8 ,
314
+ complexity,
315
+ "casting a character literal to `u8` truncates"
316
+ }
317
+
293
318
declare_lint_pass ! ( Casts => [
294
319
CAST_PRECISION_LOSS ,
295
320
CAST_SIGN_LOSS ,
296
321
CAST_POSSIBLE_TRUNCATION ,
297
322
CAST_POSSIBLE_WRAP ,
298
323
CAST_LOSSLESS ,
299
324
CAST_REF_TO_MUT ,
300
- UNNECESSARY_CAST ,
301
325
CAST_PTR_ALIGNMENT ,
326
+ UNNECESSARY_CAST ,
302
327
FN_TO_NUMERIC_CAST ,
303
328
FN_TO_NUMERIC_CAST_WITH_TRUNCATION ,
329
+ CHAR_LIT_AS_U8 ,
304
330
] ) ;
305
331
306
332
impl < ' tcx > LateLintPass < ' tcx > for Casts {
@@ -335,74 +361,12 @@ impl<'tcx> LateLintPass<'tcx> for Casts {
335
361
}
336
362
337
363
cast_ptr_alignment:: check ( cx, expr) ;
364
+ char_lit_as_u8:: check ( cx, expr) ;
338
365
}
339
366
}
340
367
341
368
const PTR_AS_PTR_MSRV : RustcVersion = RustcVersion :: new ( 1 , 38 , 0 ) ;
342
369
343
- declare_clippy_lint ! {
344
- /// **What it does:** Checks for expressions where a character literal is cast
345
- /// to `u8` and suggests using a byte literal instead.
346
- ///
347
- /// **Why is this bad?** In general, casting values to smaller types is
348
- /// error-prone and should be avoided where possible. In the particular case of
349
- /// converting a character literal to u8, it is easy to avoid by just using a
350
- /// byte literal instead. As an added bonus, `b'a'` is even slightly shorter
351
- /// than `'a' as u8`.
352
- ///
353
- /// **Known problems:** None.
354
- ///
355
- /// **Example:**
356
- /// ```rust,ignore
357
- /// 'x' as u8
358
- /// ```
359
- ///
360
- /// A better version, using the byte literal:
361
- ///
362
- /// ```rust,ignore
363
- /// b'x'
364
- /// ```
365
- pub CHAR_LIT_AS_U8 ,
366
- complexity,
367
- "casting a character literal to `u8` truncates"
368
- }
369
-
370
- declare_lint_pass ! ( CharLitAsU8 => [ CHAR_LIT_AS_U8 ] ) ;
371
-
372
- impl < ' tcx > LateLintPass < ' tcx > for CharLitAsU8 {
373
- fn check_expr ( & mut self , cx : & LateContext < ' tcx > , expr : & ' tcx Expr < ' _ > ) {
374
- if_chain ! {
375
- if !expr. span. from_expansion( ) ;
376
- if let ExprKind :: Cast ( e, _) = & expr. kind;
377
- if let ExprKind :: Lit ( l) = & e. kind;
378
- if let LitKind :: Char ( c) = l. node;
379
- if ty:: Uint ( UintTy :: U8 ) == * cx. typeck_results( ) . expr_ty( expr) . kind( ) ;
380
- then {
381
- let mut applicability = Applicability :: MachineApplicable ;
382
- let snippet = snippet_with_applicability( cx, e. span, "'x'" , & mut applicability) ;
383
-
384
- span_lint_and_then(
385
- cx,
386
- CHAR_LIT_AS_U8 ,
387
- expr. span,
388
- "casting a character literal to `u8` truncates" ,
389
- |diag| {
390
- diag. note( "`char` is four bytes wide, but `u8` is a single byte" ) ;
391
-
392
- if c. is_ascii( ) {
393
- diag. span_suggestion(
394
- expr. span,
395
- "use a byte literal instead" ,
396
- format!( "b{}" , snippet) ,
397
- applicability,
398
- ) ;
399
- }
400
- } ) ;
401
- }
402
- }
403
- }
404
- }
405
-
406
370
declare_clippy_lint ! {
407
371
/// **What it does:**
408
372
/// Checks for `as` casts between raw pointers without changing its mutability,
0 commit comments