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} ;
2
+ use clippy_utils:: ty:: { is_must_use_ty, match_type} ;
3
3
use clippy_utils:: { is_must_use_func_call, paths} ;
4
- use if_chain:: if_chain;
5
4
use rustc_hir:: { Local , PatKind } ;
6
5
use rustc_lint:: { LateContext , LateLintPass } ;
7
6
use rustc_middle:: lint:: in_external_macro;
8
7
use rustc_middle:: ty:: subst:: GenericArgKind ;
9
8
use rustc_session:: { declare_lint_pass, declare_tool_lint} ;
10
- use rustc_span:: { sym, Symbol } ;
11
9
12
10
declare_clippy_lint ! {
13
11
/// ### What it does
@@ -35,8 +33,9 @@ declare_clippy_lint! {
35
33
36
34
declare_clippy_lint ! {
37
35
/// ### What it does
38
- /// Checks for `let _ = sync_lock`.
39
- /// This supports `mutex` and `rwlock` in `std::sync` and `parking_lot`.
36
+ /// Checks for `let _ = sync_lock`. This supports `mutex` and `rwlock` in
37
+ /// `parking_lot`. For `std` locks see the `rustc` lint
38
+ /// [`let_underscore_lock`](https://doc.rust-lang.org/nightly/rustc/lints/listing/deny-by-default.html#let-underscore-lock)
40
39
///
41
40
/// ### Why is this bad?
42
41
/// This statement immediately drops the lock instead of
@@ -60,47 +59,7 @@ declare_clippy_lint! {
60
59
"non-binding let on a synchronization lock"
61
60
}
62
61
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 ] ;
62
+ declare_lint_pass ! ( LetUnderscore => [ LET_UNDERSCORE_MUST_USE , LET_UNDERSCORE_LOCK ] ) ;
104
63
105
64
const SYNC_GUARD_PATHS : [ & [ & str ] ; 3 ] = [
106
65
& paths:: PARKING_LOT_MUTEX_GUARD ,
@@ -110,64 +69,43 @@ const SYNC_GUARD_PATHS: [&[&str]; 3] = [
110
69
111
70
impl < ' tcx > LateLintPass < ' tcx > for LetUnderscore {
112
71
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 \
72
+ if !in_external_macro ( cx. tcx . sess , local. span )
73
+ && let PatKind :: Wild = local. pat . kind
74
+ && let Some ( init) = local. init
75
+ {
76
+ let init_ty = cx. typeck_results ( ) . expr_ty ( init) ;
77
+ let contains_sync_guard = init_ty. walk ( ) . any ( |inner| match inner. unpack ( ) {
78
+ GenericArgKind :: Type ( inner_ty) => SYNC_GUARD_PATHS . iter ( ) . any ( |path| match_type ( cx, inner_ty, path) ) ,
79
+ GenericArgKind :: Lifetime ( _) | GenericArgKind :: Const ( _) => false ,
80
+ } ) ;
81
+ if contains_sync_guard {
82
+ span_lint_and_help (
83
+ cx,
84
+ LET_UNDERSCORE_LOCK ,
85
+ local. span ,
86
+ "non-binding let on a synchronization lock" ,
87
+ None ,
88
+ "consider using an underscore-prefixed named \
150
89
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
- }
90
+ ) ;
91
+ } else if is_must_use_ty ( cx, cx. typeck_results ( ) . expr_ty ( init) ) {
92
+ span_lint_and_help (
93
+ cx,
94
+ LET_UNDERSCORE_MUST_USE ,
95
+ local. span ,
96
+ "non-binding let on an expression with `#[must_use]` type" ,
97
+ None ,
98
+ "consider explicitly using expression value" ,
99
+ ) ;
100
+ } else if is_must_use_func_call ( cx, init) {
101
+ span_lint_and_help (
102
+ cx,
103
+ LET_UNDERSCORE_MUST_USE ,
104
+ local. span ,
105
+ "non-binding let on a result of a `#[must_use]` function" ,
106
+ None ,
107
+ "consider explicitly using function result" ,
108
+ ) ;
171
109
}
172
110
}
173
111
}
0 commit comments