@@ -4,6 +4,7 @@ use clippy_utils::std_or_core;
4
4
use rustc_errors:: Applicability ;
5
5
use rustc_hir:: { BinOpKind , Expr , ExprKind } ;
6
6
use rustc_lint:: LateContext ;
7
+ use rustc_middle:: ty:: { self , Ty } ;
7
8
8
9
use super :: PTR_EQ ;
9
10
@@ -15,14 +16,21 @@ pub(super) fn check<'tcx>(
15
16
right : & ' tcx Expr < ' _ > ,
16
17
) {
17
18
if BinOpKind :: Eq == op {
19
+ // Remove one level of usize conversion if any
18
20
let ( left, right) = match ( expr_as_cast_to_usize ( cx, left) , expr_as_cast_to_usize ( cx, right) ) {
19
21
( Some ( lhs) , Some ( rhs) ) => ( lhs, rhs) ,
20
22
_ => ( left, right) ,
21
23
} ;
22
24
23
- if let Some ( left_var) = expr_as_cast_to_raw_pointer ( cx, left)
24
- && let Some ( right_var) = expr_as_cast_to_raw_pointer ( cx, right)
25
- && let Some ( left_snip) = left_var. span . get_source_text ( cx)
25
+ // This lint concerns raw pointers
26
+ let ( left_ty, right_ty) = ( cx. typeck_results ( ) . expr_ty ( left) , cx. typeck_results ( ) . expr_ty ( right) ) ;
27
+ if !left_ty. is_raw_ptr ( ) || !right_ty. is_raw_ptr ( ) {
28
+ return ;
29
+ }
30
+
31
+ let ( left_var, right_var) = ( peel_raw_casts ( cx, left, left_ty) , peel_raw_casts ( cx, right, right_ty) ) ;
32
+
33
+ if let Some ( left_snip) = left_var. span . get_source_text ( cx)
26
34
&& let Some ( right_snip) = right_var. span . get_source_text ( cx)
27
35
{
28
36
let Some ( top_crate) = std_or_core ( cx) else { return } ;
@@ -50,13 +58,16 @@ fn expr_as_cast_to_usize<'tcx>(cx: &LateContext<'tcx>, cast_expr: &'tcx Expr<'_>
50
58
None
51
59
}
52
60
53
- // If the given expression is a cast to a `*const` pointer, return the lhs of the cast
54
- // E.g., `foo as *const _` returns `foo`.
55
- fn expr_as_cast_to_raw_pointer < ' tcx > ( cx : & LateContext < ' tcx > , cast_expr : & ' tcx Expr < ' _ > ) -> Option < & ' tcx Expr < ' tcx > > {
56
- if cx. typeck_results ( ) . expr_ty ( cast_expr) . is_raw_ptr ( ) {
57
- if let ExprKind :: Cast ( expr, _) = cast_expr. kind {
58
- return Some ( expr) ;
59
- }
61
+ // Peel raw casts if the remaining expression can be coerced to it
62
+ fn peel_raw_casts < ' tcx > ( cx : & LateContext < ' tcx > , expr : & ' tcx Expr < ' tcx > , expr_ty : Ty < ' tcx > ) -> & ' tcx Expr < ' tcx > {
63
+ if let ExprKind :: Cast ( inner, _) = expr. kind
64
+ && let ty:: RawPtr ( target_ty, _) = expr_ty. kind ( )
65
+ && let inner_ty = cx. typeck_results ( ) . expr_ty ( inner)
66
+ && let ty:: RawPtr ( inner_target_ty, _) | ty:: Ref ( _, inner_target_ty, _) = inner_ty. kind ( )
67
+ && target_ty == inner_target_ty
68
+ {
69
+ peel_raw_casts ( cx, inner, inner_ty)
70
+ } else {
71
+ expr
60
72
}
61
- None
62
73
}
0 commit comments