@@ -37,35 +37,39 @@ declare_lint_pass!(InvalidReferenceCasting => [INVALID_REFERENCE_CASTING]);
37
37
38
38
impl < ' tcx > LateLintPass < ' tcx > for InvalidReferenceCasting {
39
39
fn check_expr ( & mut self , cx : & LateContext < ' tcx > , expr : & ' tcx Expr < ' tcx > ) {
40
- let Some ( ( is_assignment, e) ) = is_operation_we_care_about ( cx, expr) else {
41
- return ;
42
- } ;
43
-
44
- let init = cx. expr_or_init ( e) ;
45
-
46
- let Some ( ty_has_interior_mutability) = is_cast_from_const_to_mut ( cx, init) else {
47
- return ;
48
- } ;
49
- let orig_cast = if init. span != e. span { Some ( init. span ) } else { None } ;
50
- let ty_has_interior_mutability = ty_has_interior_mutability. then_some ( ( ) ) ;
51
-
52
- cx. emit_spanned_lint (
53
- INVALID_REFERENCE_CASTING ,
54
- expr. span ,
55
- if is_assignment {
56
- InvalidReferenceCastingDiag :: AssignToRef { orig_cast, ty_has_interior_mutability }
57
- } else {
58
- InvalidReferenceCastingDiag :: BorrowAsMut { orig_cast, ty_has_interior_mutability }
59
- } ,
60
- ) ;
40
+ if let Some ( ( e, is_assignment) ) = deref_or_borrow ( cx, expr) {
41
+ let init = cx. expr_or_init ( e) ;
42
+
43
+ let Some ( ty_has_interior_mutability) = is_cast_from_ref_to_mut_ptr ( cx, init) else {
44
+ return ;
45
+ } ;
46
+ let orig_cast = if init. span != e. span { Some ( init. span ) } else { None } ;
47
+ let ty_has_interior_mutability = ty_has_interior_mutability. then_some ( ( ) ) ;
48
+
49
+ cx. emit_spanned_lint (
50
+ INVALID_REFERENCE_CASTING ,
51
+ expr. span ,
52
+ if is_assignment {
53
+ InvalidReferenceCastingDiag :: AssignToRef {
54
+ orig_cast,
55
+ ty_has_interior_mutability,
56
+ }
57
+ } else {
58
+ InvalidReferenceCastingDiag :: BorrowAsMut {
59
+ orig_cast,
60
+ ty_has_interior_mutability,
61
+ }
62
+ } ,
63
+ ) ;
64
+ }
61
65
}
62
66
}
63
67
64
- fn is_operation_we_care_about < ' tcx > (
68
+ fn deref_or_borrow < ' tcx > (
65
69
cx : & LateContext < ' tcx > ,
66
70
e : & ' tcx Expr < ' tcx > ,
67
- ) -> Option < ( bool , & ' tcx Expr < ' tcx > ) > {
68
- fn deref_assign_or_addr_of < ' tcx > ( expr : & ' tcx Expr < ' tcx > ) -> Option < ( bool , & ' tcx Expr < ' tcx > ) > {
71
+ ) -> Option < ( & ' tcx Expr < ' tcx > , bool ) > {
72
+ fn deref_assign_or_addr_of < ' tcx > ( expr : & ' tcx Expr < ' tcx > ) -> Option < ( & ' tcx Expr < ' tcx > , bool ) > {
69
73
// &mut <expr>
70
74
let inner = if let ExprKind :: AddrOf ( _, Mutability :: Mut , expr) = expr. kind {
71
75
expr
@@ -80,7 +84,7 @@ fn is_operation_we_care_about<'tcx>(
80
84
} ;
81
85
82
86
if let ExprKind :: Unary ( UnOp :: Deref , e) = & inner. kind {
83
- Some ( ( !matches ! ( expr. kind, ExprKind :: AddrOf ( ..) ) , e ) )
87
+ Some ( ( e , !matches ! ( expr. kind, ExprKind :: AddrOf ( ..) ) ) )
84
88
} else {
85
89
None
86
90
}
@@ -89,7 +93,7 @@ fn is_operation_we_care_about<'tcx>(
89
93
fn ptr_write < ' tcx > (
90
94
cx : & LateContext < ' tcx > ,
91
95
e : & ' tcx Expr < ' tcx > ,
92
- ) -> Option < ( bool , & ' tcx Expr < ' tcx > ) > {
96
+ ) -> Option < ( & ' tcx Expr < ' tcx > , bool ) > {
93
97
if let ExprKind :: Call ( path, [ arg_ptr, _arg_val] ) = e. kind
94
98
&& let ExprKind :: Path ( ref qpath) = path. kind
95
99
&& let Some ( def_id) = cx. qpath_res ( qpath, path. hir_id ) . opt_def_id ( )
@@ -98,7 +102,7 @@ fn is_operation_we_care_about<'tcx>(
98
102
Some ( sym:: ptr_write | sym:: ptr_write_volatile | sym:: ptr_write_unaligned)
99
103
)
100
104
{
101
- Some ( ( true , arg_ptr ) )
105
+ Some ( ( arg_ptr , true ) )
102
106
} else {
103
107
None
104
108
}
@@ -107,7 +111,7 @@ fn is_operation_we_care_about<'tcx>(
107
111
deref_assign_or_addr_of ( e) . or_else ( || ptr_write ( cx, e) )
108
112
}
109
113
110
- fn is_cast_from_const_to_mut < ' tcx > (
114
+ fn is_cast_from_ref_to_mut_ptr < ' tcx > (
111
115
cx : & LateContext < ' tcx > ,
112
116
orig_expr : & ' tcx Expr < ' tcx > ,
113
117
) -> Option < bool > {
0 commit comments