@@ -3,7 +3,7 @@ use clippy_utils::source::snippet_with_applicability;
33use clippy_utils:: { fn_def_id, match_def_path} ;
44use rustc_errors:: Applicability ;
55use rustc_hir:: def:: Res ;
6- use rustc_hir:: { Block , Closure , Expr , ExprKind , FnDecl , HirId , Node , Pat , Path , QPath , Ty , Param , Body } ;
6+ use rustc_hir:: { Block , Body , Closure , Expr , ExprKind , FnDecl , HirId , Node , Param , Pat , Path , QPath , Ty } ;
77use rustc_lint:: { LateContext , LateLintPass } ;
88use rustc_session:: declare_lint_pass;
99use rustc_span:: Span ;
@@ -65,11 +65,19 @@ fn then_some_closure_arg<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'tcx>) -> Opt
6565 body,
6666 ..
6767 } ) => {
68- if let Node :: Expr ( expr) = cx. tcx . hir_node ( body. hir_id ) &&
69- let Body { params : [ Param { hir_id : arg_id, pat : Pat { span, .. } , .. } ] , .. } =
70- cx. tcx . hir ( ) . body ( * body)
71- {
72-
68+ if let Node :: Expr ( expr) = cx. tcx . hir_node ( body. hir_id )
69+ && let Body {
70+ params :
71+ [
72+ Param {
73+ hir_id : arg_id,
74+ pat : Pat { span, .. } ,
75+ ..
76+ } ,
77+ ] ,
78+ ..
79+ } = cx. tcx . hir ( ) . body ( * body)
80+ {
7381 ( peel_closure_body ( cx, expr, * arg_id) ) . map ( |body| ( * span, body) )
7482 } else {
7583 None
@@ -85,10 +93,12 @@ fn peel_closure_body<'tcx>(
8593 closure_arg_id : HirId ,
8694) -> Option < & ' tcx Expr < ' tcx > > {
8795 match expr. kind {
88- ExprKind :: Ret ( Some ( wrapped_expr) ) =>
89- // duplicated blocks because 2023 reference statements are awkward.
90- // "&" peels multiple layers of indirection instead of just one like we want.
91- peel_closure_body ( cx, wrapped_expr, closure_arg_id) ,
96+ ExprKind :: Ret ( Some ( wrapped_expr) ) =>
97+ // duplicated blocks because 2023 reference statements are awkward.
98+ // "&" peels multiple layers of indirection instead of just one like we want.
99+ {
100+ peel_closure_body ( cx, wrapped_expr, closure_arg_id)
101+ } ,
92102 // it would be nice if we could lift { x; y.a() } into { x; y }.a()
93103 ExprKind :: Block (
94104 Block {
@@ -110,13 +120,14 @@ fn peel_closure_body<'tcx>(
110120}
111121
112122fn get_pat_hid ( node : Node < ' _ > ) -> Option < HirId > {
113- match node {
114- Node :: Param ( Param { pat : Pat { hir_id, .. } , .. } ) |
115- Node :: Pat ( Pat { hir_id, .. } ) => Some ( * hir_id) ,
116- _ => {
117- None
118- } ,
119- }
123+ match node {
124+ Node :: Param ( Param {
125+ pat : Pat { hir_id, .. } ,
126+ ..
127+ } )
128+ | Node :: Pat ( Pat { hir_id, .. } ) => Some ( * hir_id) ,
129+ _ => None ,
130+ }
120131}
121132
122133fn is_local_defined_at ( cx : & LateContext < ' _ > , local : & Expr < ' _ > , arg_hid : HirId ) -> bool {
@@ -128,9 +139,8 @@ fn is_local_defined_at(cx: &LateContext<'_>, local: &Expr<'_>, arg_hid: HirId) -
128139 ..
129140 } ,
130141 ) ) => {
131- let local_pat_id = get_pat_hid ( cx. tcx . hir_node ( * local_hid) ) ;
132- local_pat_id. is_some ( ) &&
133- local_pat_id == get_pat_hid ( cx. tcx . hir_node ( arg_hid) )
142+ let local_pat_id = get_pat_hid ( cx. tcx . hir_node ( * local_hid) ) ;
143+ local_pat_id. is_some ( ) && local_pat_id == get_pat_hid ( cx. tcx . hir_node ( arg_hid) )
134144 } ,
135145 // is not local at all, so definitly isn't a local defined at the given position
136146 _ => false ,
@@ -139,10 +149,10 @@ fn is_local_defined_at(cx: &LateContext<'_>, local: &Expr<'_>, arg_hid: HirId) -
139149
140150fn show_sugg ( cx : & LateContext < ' _ > , span : Span , selfarg : & Expr < ' _ > , closure_args : Span , predicate : & Expr < ' _ > ) {
141151 let mut appl = Applicability :: MachineApplicable ;
142- // FIXME: this relies on deref coertion, which won't work correctly if the predicate involves something
143- // other than a method call. this is because `and_then` takes an argument by
144- // value, while `filter` takes an argument by reference.
145-
152+ // FIXME: this relies on deref coertion, which won't work correctly if the predicate involves
153+ // something other than a method call. this is because `and_then` takes an argument by
154+ // value, while `filter` takes an argument by reference.
155+
146156 let sugg = format ! (
147157 "{}.filter(|{}| {})" ,
148158 snippet_with_applicability( cx, selfarg. span, "<OPTION>" , & mut appl) ,
0 commit comments