1- use std:: borrow:: Cow ;
2-
31use clippy_utils:: diagnostics:: span_lint_and_sugg;
42use clippy_utils:: msrvs:: { self , Msrv } ;
3+ use clippy_utils:: source:: snippet_with_applicability;
54use clippy_utils:: sugg:: Sugg ;
6- use if_chain:: if_chain;
75use rustc_errors:: Applicability ;
86use rustc_hir:: { Expr , ExprKind , Mutability , TyKind } ;
97use rustc_lint:: LateContext ;
@@ -16,33 +14,41 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, msrv: &Msrv) {
1614 return ;
1715 }
1816
19- if_chain ! {
20- if let ExprKind :: Cast ( cast_expr, cast_to_hir_ty) = expr. kind;
21- let ( cast_from, cast_to) = ( cx. typeck_results( ) . expr_ty( cast_expr) , cx. typeck_results( ) . expr_ty( expr) ) ;
22- if let ty:: RawPtr ( TypeAndMut { mutbl: from_mutbl, .. } ) = cast_from. kind( ) ;
23- if let ty:: RawPtr ( TypeAndMut { ty: to_pointee_ty, mutbl: to_mutbl } ) = cast_to. kind( ) ;
24- if matches!( ( from_mutbl, to_mutbl) ,
25- ( Mutability :: Not , Mutability :: Not ) | ( Mutability :: Mut , Mutability :: Mut ) ) ;
17+ if let ExprKind :: Cast ( cast_expr, cast_to_hir_ty) = expr. kind
18+ && let ( cast_from, cast_to) = ( cx. typeck_results ( ) . expr_ty ( cast_expr) , cx. typeck_results ( ) . expr_ty ( expr) )
19+ && let ty:: RawPtr ( TypeAndMut { mutbl : from_mutbl, .. } ) = cast_from. kind ( )
20+ && let ty:: RawPtr ( TypeAndMut { ty : to_pointee_ty, mutbl : to_mutbl } ) = cast_to. kind ( )
21+ && matches ! ( ( from_mutbl, to_mutbl) ,
22+ ( Mutability :: Not , Mutability :: Not ) | ( Mutability :: Mut , Mutability :: Mut ) )
2623 // The `U` in `pointer::cast` have to be `Sized`
2724 // as explained here: https://github.com/rust-lang/rust/issues/60602.
28- if to_pointee_ty. is_sized( cx. tcx, cx. param_env) ;
29- then {
30- let mut applicability = Applicability :: MachineApplicable ;
31- let cast_expr_sugg = Sugg :: hir_with_applicability( cx, cast_expr, "_" , & mut applicability) ;
32- let turbofish = match & cast_to_hir_ty. kind {
33- TyKind :: Infer => Cow :: Borrowed ( "" ) ,
34- TyKind :: Ptr ( mut_ty) if matches!( mut_ty. ty. kind, TyKind :: Infer ) => Cow :: Borrowed ( "" ) ,
35- _ => Cow :: Owned ( format!( "::<{to_pointee_ty}>" ) ) ,
36- } ;
37- span_lint_and_sugg(
38- cx,
39- PTR_AS_PTR ,
40- expr. span,
41- "`as` casting between raw pointers without changing its mutability" ,
42- "try `pointer::cast`, a safer alternative" ,
43- format!( "{}.cast{turbofish}()" , cast_expr_sugg. maybe_par( ) ) ,
44- applicability,
45- ) ;
46- }
25+ && to_pointee_ty. is_sized ( cx. tcx , cx. param_env )
26+ {
27+ let mut app = Applicability :: MachineApplicable ;
28+ let cast_expr_sugg = Sugg :: hir_with_applicability ( cx, cast_expr, "_" , & mut app) ;
29+ let turbofish = match & cast_to_hir_ty. kind {
30+ TyKind :: Infer => String :: new ( ) ,
31+ TyKind :: Ptr ( mut_ty) => {
32+ if matches ! ( mut_ty. ty. kind, TyKind :: Infer ) {
33+ String :: new ( )
34+ } else {
35+ format ! (
36+ "::<{}>" ,
37+ snippet_with_applicability( cx, mut_ty. ty. span, "/* type */" , & mut app)
38+ )
39+ }
40+ } ,
41+ _ => return ,
42+ } ;
43+
44+ span_lint_and_sugg (
45+ cx,
46+ PTR_AS_PTR ,
47+ expr. span ,
48+ "`as` casting between raw pointers without changing its mutability" ,
49+ "try `pointer::cast`, a safer alternative" ,
50+ format ! ( "{}.cast{turbofish}()" , cast_expr_sugg. maybe_par( ) ) ,
51+ app,
52+ ) ;
4753 }
4854}
0 commit comments