1
1
use clippy_utils:: diagnostics:: span_lint_and_help;
2
- use clippy_utils:: ty:: { is_must_use_ty, is_type_diagnostic_item, match_type} ;
3
- use clippy_utils:: { is_must_use_func_call, paths} ;
4
- use if_chain:: if_chain;
2
+ use clippy_utils:: is_must_use_func_call;
3
+ use clippy_utils:: ty:: is_must_use_ty;
5
4
use rustc_hir:: { Local , PatKind } ;
6
5
use rustc_lint:: { LateContext , LateLintPass } ;
7
6
use rustc_middle:: lint:: in_external_macro;
8
- use rustc_middle:: ty:: subst:: GenericArgKind ;
9
7
use rustc_session:: { declare_lint_pass, declare_tool_lint} ;
10
- use rustc_span:: { sym, Symbol } ;
11
8
12
9
declare_clippy_lint ! {
13
10
/// ### What it does
@@ -33,141 +30,32 @@ declare_clippy_lint! {
33
30
"non-binding let on a `#[must_use]` expression"
34
31
}
35
32
36
- declare_clippy_lint ! {
37
- /// ### What it does
38
- /// Checks for `let _ = sync_lock`.
39
- /// This supports `mutex` and `rwlock` in `std::sync` and `parking_lot`.
40
- ///
41
- /// ### Why is this bad?
42
- /// This statement immediately drops the lock instead of
43
- /// extending its lifetime to the end of the scope, which is often not intended.
44
- /// To extend lock lifetime to the end of the scope, use an underscore-prefixed
45
- /// name instead (i.e. _lock). If you want to explicitly drop the lock,
46
- /// `std::mem::drop` conveys your intention better and is less error-prone.
47
- ///
48
- /// ### Example
49
- /// ```rust,ignore
50
- /// let _ = mutex.lock();
51
- /// ```
52
- ///
53
- /// Use instead:
54
- /// ```rust,ignore
55
- /// let _lock = mutex.lock();
56
- /// ```
57
- #[ clippy:: version = "1.43.0" ]
58
- pub LET_UNDERSCORE_LOCK ,
59
- correctness,
60
- "non-binding let on a synchronization lock"
61
- }
62
-
63
- declare_clippy_lint ! {
64
- /// ### What it does
65
- /// Checks for `let _ = <expr>`
66
- /// where expr has a type that implements `Drop`
67
- ///
68
- /// ### Why is this bad?
69
- /// This statement immediately drops the initializer
70
- /// expression instead of extending its lifetime to the end of the scope, which
71
- /// is often not intended. To extend the expression's lifetime to the end of the
72
- /// scope, use an underscore-prefixed name instead (i.e. _var). If you want to
73
- /// explicitly drop the expression, `std::mem::drop` conveys your intention
74
- /// better and is less error-prone.
75
- ///
76
- /// ### Example
77
- /// ```rust
78
- /// # struct DroppableItem;
79
- /// {
80
- /// let _ = DroppableItem;
81
- /// // ^ dropped here
82
- /// /* more code */
83
- /// }
84
- /// ```
85
- ///
86
- /// Use instead:
87
- /// ```rust
88
- /// # struct DroppableItem;
89
- /// {
90
- /// let _droppable = DroppableItem;
91
- /// /* more code */
92
- /// // dropped at end of scope
93
- /// }
94
- /// ```
95
- #[ clippy:: version = "1.50.0" ]
96
- pub LET_UNDERSCORE_DROP ,
97
- pedantic,
98
- "non-binding let on a type that implements `Drop`"
99
- }
100
-
101
- declare_lint_pass ! ( LetUnderscore => [ LET_UNDERSCORE_MUST_USE , LET_UNDERSCORE_LOCK , LET_UNDERSCORE_DROP ] ) ;
102
-
103
- const SYNC_GUARD_SYMS : [ Symbol ; 3 ] = [ sym:: MutexGuard , sym:: RwLockReadGuard , sym:: RwLockWriteGuard ] ;
104
-
105
- const SYNC_GUARD_PATHS : [ & [ & str ] ; 3 ] = [
106
- & paths:: PARKING_LOT_MUTEX_GUARD ,
107
- & paths:: PARKING_LOT_RWLOCK_READ_GUARD ,
108
- & paths:: PARKING_LOT_RWLOCK_WRITE_GUARD ,
109
- ] ;
33
+ declare_lint_pass ! ( LetUnderscore => [ LET_UNDERSCORE_MUST_USE ] ) ;
110
34
111
35
impl < ' tcx > LateLintPass < ' tcx > for LetUnderscore {
112
36
fn check_local ( & mut self , cx : & LateContext < ' _ > , local : & Local < ' _ > ) {
113
- if in_external_macro ( cx. tcx . sess , local. span ) {
114
- return ;
115
- }
116
-
117
- if_chain ! {
118
- if let PatKind :: Wild = local. pat. kind;
119
- if let Some ( init) = local. init;
120
- then {
121
- let init_ty = cx. typeck_results( ) . expr_ty( init) ;
122
- let contains_sync_guard = init_ty. walk( ) . any( |inner| match inner. unpack( ) {
123
- GenericArgKind :: Type ( inner_ty) => {
124
- SYNC_GUARD_SYMS
125
- . iter( )
126
- . any( |& sym| is_type_diagnostic_item( cx, inner_ty, sym) )
127
- || SYNC_GUARD_PATHS . iter( ) . any( |path| match_type( cx, inner_ty, path) )
128
- } ,
129
-
130
- GenericArgKind :: Lifetime ( _) | GenericArgKind :: Const ( _) => false ,
131
- } ) ;
132
- if contains_sync_guard {
133
- span_lint_and_help(
134
- cx,
135
- LET_UNDERSCORE_LOCK ,
136
- local. span,
137
- "non-binding let on a synchronization lock" ,
138
- None ,
139
- "consider using an underscore-prefixed named \
140
- binding or dropping explicitly with `std::mem::drop`",
141
- ) ;
142
- } else if init_ty. needs_drop( cx. tcx, cx. param_env) {
143
- span_lint_and_help(
144
- cx,
145
- LET_UNDERSCORE_DROP ,
146
- local. span,
147
- "non-binding `let` on a type that implements `Drop`" ,
148
- None ,
149
- "consider using an underscore-prefixed named \
150
- binding or dropping explicitly with `std::mem::drop`",
151
- ) ;
152
- } else if is_must_use_ty( cx, cx. typeck_results( ) . expr_ty( init) ) {
153
- span_lint_and_help(
154
- cx,
155
- LET_UNDERSCORE_MUST_USE ,
156
- local. span,
157
- "non-binding let on an expression with `#[must_use]` type" ,
158
- None ,
159
- "consider explicitly using expression value" ,
160
- ) ;
161
- } else if is_must_use_func_call( cx, init) {
162
- span_lint_and_help(
163
- cx,
164
- LET_UNDERSCORE_MUST_USE ,
165
- local. span,
166
- "non-binding let on a result of a `#[must_use]` function" ,
167
- None ,
168
- "consider explicitly using function result" ,
169
- ) ;
170
- }
37
+ if !in_external_macro ( cx. tcx . sess , local. span )
38
+ && let PatKind :: Wild = local. pat . kind
39
+ && let Some ( init) = local. init
40
+ {
41
+ if is_must_use_ty ( cx, cx. typeck_results ( ) . expr_ty ( init) ) {
42
+ span_lint_and_help (
43
+ cx,
44
+ LET_UNDERSCORE_MUST_USE ,
45
+ local. span ,
46
+ "non-binding let on an expression with `#[must_use]` type" ,
47
+ None ,
48
+ "consider explicitly using expression value" ,
49
+ ) ;
50
+ } else if is_must_use_func_call ( cx, init) {
51
+ span_lint_and_help (
52
+ cx,
53
+ LET_UNDERSCORE_MUST_USE ,
54
+ local. span ,
55
+ "non-binding let on a result of a `#[must_use]` function" ,
56
+ None ,
57
+ "consider explicitly using function result" ,
58
+ ) ;
171
59
}
172
60
}
173
61
}
0 commit comments