@@ -8,22 +8,17 @@ mod cast_sign_loss;
8
8
mod char_lit_as_u8;
9
9
mod fn_to_numeric_cast;
10
10
mod fn_to_numeric_cast_with_truncation;
11
+ mod ptr_as_ptr;
11
12
mod unnecessary_cast;
12
13
mod utils;
13
14
14
- use std:: borrow:: Cow ;
15
-
16
- use if_chain:: if_chain;
17
- use rustc_errors:: Applicability ;
18
- use rustc_hir:: { Expr , ExprKind , Mutability , TyKind } ;
15
+ use rustc_hir:: { Expr , ExprKind } ;
19
16
use rustc_lint:: { LateContext , LateLintPass , LintContext } ;
20
17
use rustc_middle:: lint:: in_external_macro;
21
- use rustc_middle:: ty:: { self , TypeAndMut } ;
22
18
use rustc_semver:: RustcVersion ;
23
- use rustc_session:: { declare_lint_pass , declare_tool_lint, impl_lint_pass} ;
19
+ use rustc_session:: { declare_tool_lint, impl_lint_pass} ;
24
20
25
- use crate :: utils:: sugg:: Sugg ;
26
- use crate :: utils:: { is_hir_ty_cfg_dependant, meets_msrv, span_lint_and_sugg} ;
21
+ use crate :: utils:: is_hir_ty_cfg_dependant;
27
22
28
23
declare_clippy_lint ! {
29
24
/// **What it does:** Checks for casts from any numerical to a float type where
@@ -315,58 +310,6 @@ declare_clippy_lint! {
315
310
"casting a character literal to `u8` truncates"
316
311
}
317
312
318
- declare_lint_pass ! ( Casts => [
319
- CAST_PRECISION_LOSS ,
320
- CAST_SIGN_LOSS ,
321
- CAST_POSSIBLE_TRUNCATION ,
322
- CAST_POSSIBLE_WRAP ,
323
- CAST_LOSSLESS ,
324
- CAST_REF_TO_MUT ,
325
- CAST_PTR_ALIGNMENT ,
326
- UNNECESSARY_CAST ,
327
- FN_TO_NUMERIC_CAST ,
328
- FN_TO_NUMERIC_CAST_WITH_TRUNCATION ,
329
- CHAR_LIT_AS_U8 ,
330
- ] ) ;
331
-
332
- impl < ' tcx > LateLintPass < ' tcx > for Casts {
333
- fn check_expr ( & mut self , cx : & LateContext < ' tcx > , expr : & ' tcx Expr < ' _ > ) {
334
- cast_ref_to_mut:: check ( cx, expr) ;
335
-
336
- if expr. span . from_expansion ( ) {
337
- return ;
338
- }
339
- if let ExprKind :: Cast ( ref cast_expr, cast_to) = expr. kind {
340
- if is_hir_ty_cfg_dependant ( cx, cast_to) {
341
- return ;
342
- }
343
- let ( cast_from, cast_to) = (
344
- cx. typeck_results ( ) . expr_ty ( cast_expr) ,
345
- cx. typeck_results ( ) . expr_ty ( expr) ,
346
- ) ;
347
-
348
- if unnecessary_cast:: check ( cx, expr, cast_expr, cast_from, cast_to) {
349
- return ;
350
- }
351
-
352
- fn_to_numeric_cast:: check ( cx, expr, cast_expr, cast_from, cast_to) ;
353
- fn_to_numeric_cast_with_truncation:: check ( cx, expr, cast_expr, cast_from, cast_to) ;
354
- if cast_from. is_numeric ( ) && cast_to. is_numeric ( ) && !in_external_macro ( cx. sess ( ) , expr. span ) {
355
- cast_possible_truncation:: check ( cx, expr, cast_from, cast_to) ;
356
- cast_possible_wrap:: check ( cx, expr, cast_from, cast_to) ;
357
- cast_precision_loss:: check ( cx, expr, cast_from, cast_to) ;
358
- cast_lossless:: check ( cx, expr, cast_expr, cast_from, cast_to) ;
359
- cast_sign_loss:: check ( cx, expr, cast_expr, cast_from, cast_to) ;
360
- }
361
- }
362
-
363
- cast_ptr_alignment:: check ( cx, expr) ;
364
- char_lit_as_u8:: check ( cx, expr) ;
365
- }
366
- }
367
-
368
- const PTR_AS_PTR_MSRV : RustcVersion = RustcVersion :: new ( 1 , 38 , 0 ) ;
369
-
370
313
declare_clippy_lint ! {
371
314
/// **What it does:**
372
315
/// Checks for `as` casts between raw pointers without changing its mutability,
@@ -398,58 +341,66 @@ declare_clippy_lint! {
398
341
"casting using `as` from and to raw pointers that doesn't change its mutability, where `pointer::cast` could take the place of `as`"
399
342
}
400
343
401
- pub struct PtrAsPtr {
344
+ pub struct Casts {
402
345
msrv : Option < RustcVersion > ,
403
346
}
404
347
405
- impl PtrAsPtr {
348
+ impl Casts {
406
349
#[ must_use]
407
350
pub fn new ( msrv : Option < RustcVersion > ) -> Self {
408
351
Self { msrv }
409
352
}
410
353
}
411
354
412
- impl_lint_pass ! ( PtrAsPtr => [ PTR_AS_PTR ] ) ;
355
+ impl_lint_pass ! ( Casts => [
356
+ CAST_PRECISION_LOSS ,
357
+ CAST_SIGN_LOSS ,
358
+ CAST_POSSIBLE_TRUNCATION ,
359
+ CAST_POSSIBLE_WRAP ,
360
+ CAST_LOSSLESS ,
361
+ CAST_REF_TO_MUT ,
362
+ CAST_PTR_ALIGNMENT ,
363
+ UNNECESSARY_CAST ,
364
+ FN_TO_NUMERIC_CAST ,
365
+ FN_TO_NUMERIC_CAST_WITH_TRUNCATION ,
366
+ CHAR_LIT_AS_U8 ,
367
+ PTR_AS_PTR ,
368
+ ] ) ;
413
369
414
- impl < ' tcx > LateLintPass < ' tcx > for PtrAsPtr {
370
+ impl < ' tcx > LateLintPass < ' tcx > for Casts {
415
371
fn check_expr ( & mut self , cx : & LateContext < ' tcx > , expr : & ' tcx Expr < ' _ > ) {
416
- if !meets_msrv ( self . msrv . as_ref ( ) , & PTR_AS_PTR_MSRV ) {
417
- return ;
418
- }
419
-
420
372
if expr. span . from_expansion ( ) {
421
373
return ;
422
374
}
423
375
424
- if_chain ! {
425
- if let ExprKind :: Cast ( cast_expr, cast_to_hir_ty) = expr. kind;
426
- let ( cast_from, cast_to) = ( cx. typeck_results( ) . expr_ty( cast_expr) , cx. typeck_results( ) . expr_ty( expr) ) ;
427
- if let ty:: RawPtr ( TypeAndMut { mutbl: from_mutbl, .. } ) = cast_from. kind( ) ;
428
- if let ty:: RawPtr ( TypeAndMut { ty: to_pointee_ty, mutbl: to_mutbl } ) = cast_to. kind( ) ;
429
- if matches!( ( from_mutbl, to_mutbl) ,
430
- ( Mutability :: Not , Mutability :: Not ) | ( Mutability :: Mut , Mutability :: Mut ) ) ;
431
- // The `U` in `pointer::cast` have to be `Sized`
432
- // as explained here: https://github.com/rust-lang/rust/issues/60602.
433
- if to_pointee_ty. is_sized( cx. tcx. at( expr. span) , cx. param_env) ;
434
- then {
435
- let mut applicability = Applicability :: MachineApplicable ;
436
- let cast_expr_sugg = Sugg :: hir_with_applicability( cx, cast_expr, "_" , & mut applicability) ;
437
- let turbofish = match & cast_to_hir_ty. kind {
438
- TyKind :: Infer => Cow :: Borrowed ( "" ) ,
439
- TyKind :: Ptr ( mut_ty) if matches!( mut_ty. ty. kind, TyKind :: Infer ) => Cow :: Borrowed ( "" ) ,
440
- _ => Cow :: Owned ( format!( "::<{}>" , to_pointee_ty) ) ,
441
- } ;
442
- span_lint_and_sugg(
443
- cx,
444
- PTR_AS_PTR ,
445
- expr. span,
446
- "`as` casting between raw pointers without changing its mutability" ,
447
- "try `pointer::cast`, a safer alternative" ,
448
- format!( "{}.cast{}()" , cast_expr_sugg. maybe_par( ) , turbofish) ,
449
- applicability,
450
- ) ;
376
+ if let ExprKind :: Cast ( ref cast_expr, cast_to) = expr. kind {
377
+ if is_hir_ty_cfg_dependant ( cx, cast_to) {
378
+ return ;
379
+ }
380
+ let ( cast_from, cast_to) = (
381
+ cx. typeck_results ( ) . expr_ty ( cast_expr) ,
382
+ cx. typeck_results ( ) . expr_ty ( expr) ,
383
+ ) ;
384
+
385
+ if unnecessary_cast:: check ( cx, expr, cast_expr, cast_from, cast_to) {
386
+ return ;
387
+ }
388
+
389
+ fn_to_numeric_cast:: check ( cx, expr, cast_expr, cast_from, cast_to) ;
390
+ fn_to_numeric_cast_with_truncation:: check ( cx, expr, cast_expr, cast_from, cast_to) ;
391
+ if cast_from. is_numeric ( ) && cast_to. is_numeric ( ) && !in_external_macro ( cx. sess ( ) , expr. span ) {
392
+ cast_possible_truncation:: check ( cx, expr, cast_from, cast_to) ;
393
+ cast_possible_wrap:: check ( cx, expr, cast_from, cast_to) ;
394
+ cast_precision_loss:: check ( cx, expr, cast_from, cast_to) ;
395
+ cast_lossless:: check ( cx, expr, cast_expr, cast_from, cast_to) ;
396
+ cast_sign_loss:: check ( cx, expr, cast_expr, cast_from, cast_to) ;
451
397
}
452
398
}
399
+
400
+ cast_ref_to_mut:: check ( cx, expr) ;
401
+ cast_ptr_alignment:: check ( cx, expr) ;
402
+ char_lit_as_u8:: check ( cx, expr) ;
403
+ ptr_as_ptr:: check ( cx, expr, & self . msrv ) ;
453
404
}
454
405
455
406
extract_msrv_attr ! ( LateContext ) ;
0 commit comments