1
1
use clippy_utils:: consts:: { constant, Constant } ;
2
2
use clippy_utils:: diagnostics:: span_lint_and_help;
3
3
use clippy_utils:: { is_integer_literal, is_path_diagnostic_item} ;
4
- use if_chain:: if_chain;
5
4
use rustc_hir:: { BinOpKind , Expr , ExprKind , TyKind } ;
6
5
use rustc_lint:: { LateContext , LateLintPass } ;
7
6
use rustc_session:: { declare_lint_pass, declare_tool_lint} ;
@@ -33,40 +32,37 @@ declare_clippy_lint! {
33
32
}
34
33
declare_lint_pass ! ( FnNullCheck => [ FN_NULL_CHECK ] ) ;
35
34
36
- const LINT_MSG : & str = "function pointer assumed to be nullable, even though it isn't" ;
37
- const HELP_MSG : & str = "try wrapping your function pointer type in `Option<T>` instead, and using `is_none` to check for null pointer value" ;
35
+ fn lint_expr ( cx : & LateContext < ' _ > , expr : & Expr < ' _ > ) {
36
+ span_lint_and_help (
37
+ cx,
38
+ FN_NULL_CHECK ,
39
+ expr. span ,
40
+ "function pointer assumed to be nullable, even though it isn't" ,
41
+ None ,
42
+ "try wrapping your function pointer type in `Option<T>` instead, and using `is_none` to check for null pointer value" ,
43
+ )
44
+ }
38
45
39
46
fn is_fn_ptr_cast ( cx : & LateContext < ' _ > , expr : & Expr < ' _ > ) -> bool {
40
- if_chain ! {
41
- if let ExprKind :: Cast ( cast_expr, cast_ty) = expr. kind;
42
- if let TyKind :: Ptr ( _) = cast_ty. kind;
43
- if cx. typeck_results( ) . expr_ty_adjusted( cast_expr) . is_fn( ) ;
44
- then {
45
- true
46
- } else {
47
- false
48
- }
47
+ if let ExprKind :: Cast ( cast_expr, cast_ty) = expr. kind
48
+ && let TyKind :: Ptr ( _) = cast_ty. kind
49
+ {
50
+ cx. typeck_results ( ) . expr_ty_adjusted ( cast_expr) . is_fn ( )
51
+ } else {
52
+ false
49
53
}
50
54
}
51
55
52
56
impl < ' tcx > LateLintPass < ' tcx > for FnNullCheck {
53
57
fn check_expr ( & mut self , cx : & LateContext < ' tcx > , expr : & ' tcx Expr < ' _ > ) {
54
58
// Catching:
55
59
// (fn_ptr as *<const/mut> <ty>).is_null()
56
- if_chain ! {
57
- if let ExprKind :: MethodCall ( method_name, receiver, _, _) = expr. kind;
58
- if method_name. ident. as_str( ) == "is_null" ;
59
- if is_fn_ptr_cast( cx, receiver) ;
60
- then {
61
- span_lint_and_help(
62
- cx,
63
- FN_NULL_CHECK ,
64
- expr. span,
65
- LINT_MSG ,
66
- None ,
67
- HELP_MSG
68
- ) ;
69
- }
60
+ if let ExprKind :: MethodCall ( method_name, receiver, _, _) = expr. kind
61
+ && method_name. ident . as_str ( ) == "is_null"
62
+ && is_fn_ptr_cast ( cx, receiver)
63
+ {
64
+ lint_expr ( cx, expr) ;
65
+ return ;
70
66
}
71
67
72
68
if let ExprKind :: Binary ( op, left, right) = expr. kind
@@ -85,28 +81,14 @@ impl<'tcx> LateLintPass<'tcx> for FnNullCheck {
85
81
// (fn_ptr as *<const/mut> <ty>) == <const that evaluates to null_ptr>
86
82
let c = constant ( cx, cx. typeck_results ( ) , to_check) ;
87
83
if let Some ( ( Constant :: RawPtr ( 0 ) , _) ) = c {
88
- span_lint_and_help (
89
- cx,
90
- FN_NULL_CHECK ,
91
- expr. span ,
92
- LINT_MSG ,
93
- None ,
94
- HELP_MSG
95
- ) ;
84
+ lint_expr ( cx, expr) ;
96
85
return ;
97
86
}
98
87
99
88
// Catching:
100
89
// (fn_ptr as *<const/mut> <ty>) == (0 as <ty>)
101
90
if let ExprKind :: Cast ( cast_expr, _) = to_check. kind && is_integer_literal ( cast_expr, 0 ) {
102
- span_lint_and_help (
103
- cx,
104
- FN_NULL_CHECK ,
105
- expr. span ,
106
- LINT_MSG ,
107
- None ,
108
- HELP_MSG
109
- ) ;
91
+ lint_expr ( cx, expr) ;
110
92
return ;
111
93
}
112
94
@@ -115,14 +97,7 @@ impl<'tcx> LateLintPass<'tcx> for FnNullCheck {
115
97
if let ExprKind :: Call ( func, [ ] ) = to_check. kind &&
116
98
is_path_diagnostic_item ( cx, func, sym:: ptr_null)
117
99
{
118
- span_lint_and_help (
119
- cx,
120
- FN_NULL_CHECK ,
121
- expr. span ,
122
- LINT_MSG ,
123
- None ,
124
- HELP_MSG
125
- ) ;
100
+ lint_expr ( cx, expr) ;
126
101
}
127
102
}
128
103
}
0 commit comments