11use 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;
54use rustc_hir:: { Local , PatKind } ;
65use rustc_lint:: { LateContext , LateLintPass } ;
76use rustc_middle:: lint:: in_external_macro;
8- use rustc_middle:: ty:: subst:: GenericArgKind ;
97use rustc_session:: { declare_lint_pass, declare_tool_lint} ;
10- use rustc_span:: { sym, Symbol } ;
118
129declare_clippy_lint ! {
1310 /// ### What it does
@@ -33,141 +30,32 @@ declare_clippy_lint! {
3330 "non-binding let on a `#[must_use]` expression"
3431}
3532
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 ] ) ;
11034
11135impl < ' tcx > LateLintPass < ' tcx > for LetUnderscore {
11236 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+ ) ;
17159 }
17260 }
17361 }
0 commit comments