@@ -8,22 +8,17 @@ mod cast_sign_loss;
88mod char_lit_as_u8;
99mod fn_to_numeric_cast;
1010mod fn_to_numeric_cast_with_truncation;
11+ mod ptr_as_ptr;
1112mod unnecessary_cast;
1213mod utils;
1314
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 } ;
1916use rustc_lint:: { LateContext , LateLintPass , LintContext } ;
2017use rustc_middle:: lint:: in_external_macro;
21- use rustc_middle:: ty:: { self , TypeAndMut } ;
2218use 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} ;
2420
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;
2722
2823declare_clippy_lint ! {
2924 /// **What it does:** Checks for casts from any numerical to a float type where
@@ -315,58 +310,6 @@ declare_clippy_lint! {
315310 "casting a character literal to `u8` truncates"
316311}
317312
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-
370313declare_clippy_lint ! {
371314 /// **What it does:**
372315 /// Checks for `as` casts between raw pointers without changing its mutability,
@@ -398,58 +341,66 @@ declare_clippy_lint! {
398341 "casting using `as` from and to raw pointers that doesn't change its mutability, where `pointer::cast` could take the place of `as`"
399342}
400343
401- pub struct PtrAsPtr {
344+ pub struct Casts {
402345 msrv : Option < RustcVersion > ,
403346}
404347
405- impl PtrAsPtr {
348+ impl Casts {
406349 #[ must_use]
407350 pub fn new ( msrv : Option < RustcVersion > ) -> Self {
408351 Self { msrv }
409352 }
410353}
411354
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+ ] ) ;
413369
414- impl < ' tcx > LateLintPass < ' tcx > for PtrAsPtr {
370+ impl < ' tcx > LateLintPass < ' tcx > for Casts {
415371 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-
420372 if expr. span . from_expansion ( ) {
421373 return ;
422374 }
423375
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) ;
451397 }
452398 }
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 ) ;
453404 }
454405
455406 extract_msrv_attr ! ( LateContext ) ;
0 commit comments