@@ -37,35 +37,39 @@ declare_lint_pass!(InvalidReferenceCasting => [INVALID_REFERENCE_CASTING]);
3737
3838impl < ' tcx > LateLintPass < ' tcx > for InvalidReferenceCasting {
3939 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+ }
6165 }
6266}
6367
64- fn is_operation_we_care_about < ' tcx > (
68+ fn deref_or_borrow < ' tcx > (
6569 cx : & LateContext < ' tcx > ,
6670 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 ) > {
6973 // &mut <expr>
7074 let inner = if let ExprKind :: AddrOf ( _, Mutability :: Mut , expr) = expr. kind {
7175 expr
@@ -80,7 +84,7 @@ fn is_operation_we_care_about<'tcx>(
8084 } ;
8185
8286 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 ( ..) ) ) )
8488 } else {
8589 None
8690 }
@@ -89,7 +93,7 @@ fn is_operation_we_care_about<'tcx>(
8993 fn ptr_write < ' tcx > (
9094 cx : & LateContext < ' tcx > ,
9195 e : & ' tcx Expr < ' tcx > ,
92- ) -> Option < ( bool , & ' tcx Expr < ' tcx > ) > {
96+ ) -> Option < ( & ' tcx Expr < ' tcx > , bool ) > {
9397 if let ExprKind :: Call ( path, [ arg_ptr, _arg_val] ) = e. kind
9498 && let ExprKind :: Path ( ref qpath) = path. kind
9599 && 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>(
98102 Some ( sym:: ptr_write | sym:: ptr_write_volatile | sym:: ptr_write_unaligned)
99103 )
100104 {
101- Some ( ( true , arg_ptr ) )
105+ Some ( ( arg_ptr , true ) )
102106 } else {
103107 None
104108 }
@@ -107,7 +111,7 @@ fn is_operation_we_care_about<'tcx>(
107111 deref_assign_or_addr_of ( e) . or_else ( || ptr_write ( cx, e) )
108112}
109113
110- fn is_cast_from_const_to_mut < ' tcx > (
114+ fn is_cast_from_ref_to_mut_ptr < ' tcx > (
111115 cx : & LateContext < ' tcx > ,
112116 orig_expr : & ' tcx Expr < ' tcx > ,
113117) -> Option < bool > {
0 commit comments