1
- use std:: borrow:: Cow ;
2
-
3
1
use clippy_utils:: diagnostics:: span_lint_and_sugg;
4
2
use clippy_utils:: msrvs:: { self , Msrv } ;
3
+ use clippy_utils:: source:: snippet_with_applicability;
5
4
use clippy_utils:: sugg:: Sugg ;
6
- use if_chain:: if_chain;
7
5
use rustc_errors:: Applicability ;
8
6
use rustc_hir:: { Expr , ExprKind , Mutability , TyKind } ;
9
7
use rustc_lint:: LateContext ;
@@ -16,33 +14,41 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, msrv: &Msrv) {
16
14
return ;
17
15
}
18
16
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 ) )
26
23
// The `U` in `pointer::cast` have to be `Sized`
27
24
// 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
+ ) ;
47
53
}
48
54
}
0 commit comments