@@ -25,7 +25,7 @@ use rustc_lint::{LateContext, LintContext};
2525use rustc_middle:: ty:: TyCtxt ;
2626use rustc_session:: Session ;
2727use rustc_span:: symbol:: { Ident , kw} ;
28- use rustc_span:: { Span , Symbol } ;
28+ use rustc_span:: { Span , Symbol , SyntaxContext } ;
2929use rustc_target:: spec:: abi:: Abi ;
3030
3131/// The search pattern to look for. Used by `span_matches_pat`
@@ -141,62 +141,89 @@ fn path_search_pat(path: &Path<'_>) -> (Pat, Pat) {
141141
142142/// Get the search patterns to use for the given expression
143143fn expr_search_pat ( tcx : TyCtxt < ' _ > , e : & Expr < ' _ > ) -> ( Pat , Pat ) {
144- match e. kind {
145- ExprKind :: ConstBlock ( _) => ( Pat :: Str ( "const" ) , Pat :: Str ( "}" ) ) ,
146- // Parenthesis are trimmed from the text before the search patterns are matched.
147- // See: `span_matches_pat`
148- ExprKind :: Tup ( [ ] ) => ( Pat :: Str ( ")" ) , Pat :: Str ( "(" ) ) ,
149- ExprKind :: Unary ( UnOp :: Deref , e) => ( Pat :: Str ( "*" ) , expr_search_pat ( tcx, e) . 1 ) ,
150- ExprKind :: Unary ( UnOp :: Not , e) => ( Pat :: Str ( "!" ) , expr_search_pat ( tcx, e) . 1 ) ,
151- ExprKind :: Unary ( UnOp :: Neg , e) => ( Pat :: Str ( "-" ) , expr_search_pat ( tcx, e) . 1 ) ,
152- ExprKind :: Lit ( lit) => lit_search_pat ( & lit. node ) ,
153- ExprKind :: Array ( _) | ExprKind :: Repeat ( ..) => ( Pat :: Str ( "[" ) , Pat :: Str ( "]" ) ) ,
154- ExprKind :: Call ( e, [ ] ) | ExprKind :: MethodCall ( _, e, [ ] , _) => ( expr_search_pat ( tcx, e) . 0 , Pat :: Str ( "(" ) ) ,
155- ExprKind :: Call ( first, [ .., last] )
156- | ExprKind :: MethodCall ( _, first, [ .., last] , _)
157- | ExprKind :: Binary ( _, first, last)
158- | ExprKind :: Tup ( [ first, .., last] )
159- | ExprKind :: Assign ( first, last, _)
160- | ExprKind :: AssignOp ( _, first, last) => ( expr_search_pat ( tcx, first) . 0 , expr_search_pat ( tcx, last) . 1 ) ,
161- ExprKind :: Tup ( [ e] ) | ExprKind :: DropTemps ( e) => expr_search_pat ( tcx, e) ,
162- ExprKind :: Cast ( e, _) | ExprKind :: Type ( e, _) => ( expr_search_pat ( tcx, e) . 0 , Pat :: Str ( "" ) ) ,
163- ExprKind :: Let ( let_expr) => ( Pat :: Str ( "let" ) , expr_search_pat ( tcx, let_expr. init ) . 1 ) ,
164- ExprKind :: If ( ..) => ( Pat :: Str ( "if" ) , Pat :: Str ( "}" ) ) ,
165- ExprKind :: Loop ( _, Some ( _) , _, _) | ExprKind :: Block ( _, Some ( _) ) => ( Pat :: Str ( "'" ) , Pat :: Str ( "}" ) ) ,
166- ExprKind :: Loop ( _, None , LoopSource :: Loop , _) => ( Pat :: Str ( "loop" ) , Pat :: Str ( "}" ) ) ,
167- ExprKind :: Loop ( _, None , LoopSource :: While , _) => ( Pat :: Str ( "while" ) , Pat :: Str ( "}" ) ) ,
168- ExprKind :: Loop ( _, None , LoopSource :: ForLoop , _) | ExprKind :: Match ( _, _, MatchSource :: ForLoopDesugar ) => {
169- ( Pat :: Str ( "for" ) , Pat :: Str ( "}" ) )
170- } ,
171- ExprKind :: Match ( _, _, MatchSource :: Normal ) => ( Pat :: Str ( "match" ) , Pat :: Str ( "}" ) ) ,
172- ExprKind :: Match ( e, _, MatchSource :: TryDesugar ( _) ) => ( expr_search_pat ( tcx, e) . 0 , Pat :: Str ( "?" ) ) ,
173- ExprKind :: Match ( e, _, MatchSource :: AwaitDesugar ) | ExprKind :: Yield ( e, YieldSource :: Await { .. } ) => {
174- ( expr_search_pat ( tcx, e) . 0 , Pat :: Str ( "await" ) )
175- } ,
176- ExprKind :: Closure ( & Closure { body, .. } ) => ( Pat :: Str ( "" ) , expr_search_pat ( tcx, tcx. hir ( ) . body ( body) . value ) . 1 ) ,
177- ExprKind :: Block (
178- Block {
179- rules : BlockCheckMode :: UnsafeBlock ( UnsafeSource :: UserProvided ) ,
180- ..
144+ fn expr_search_pat_inner ( tcx : TyCtxt < ' _ > , e : & Expr < ' _ > , outer_ctxt : SyntaxContext ) -> ( Pat , Pat ) {
145+ // The expression can have subexpressions in different contexts, in which case
146+ // building up a search pattern from the macro expansion would lead to false positives;
147+ // e.g. `return format!(..)` would be considered to be from a proc macro
148+ // if we build up a pattern for the macro expansion and compare it to the invocation `format!()`.
149+ // So instead we return an empty pattern such that `span_matches_pat` always returns true.
150+ if e. span . ctxt ( ) != outer_ctxt {
151+ return ( Pat :: Str ( "" ) , Pat :: Str ( "" ) ) ;
152+ }
153+
154+ match e. kind {
155+ ExprKind :: ConstBlock ( _) => ( Pat :: Str ( "const" ) , Pat :: Str ( "}" ) ) ,
156+ // Parenthesis are trimmed from the text before the search patterns are matched.
157+ // See: `span_matches_pat`
158+ ExprKind :: Tup ( [ ] ) => ( Pat :: Str ( ")" ) , Pat :: Str ( "(" ) ) ,
159+ ExprKind :: Unary ( UnOp :: Deref , e) => ( Pat :: Str ( "*" ) , expr_search_pat_inner ( tcx, e, outer_ctxt) . 1 ) ,
160+ ExprKind :: Unary ( UnOp :: Not , e) => ( Pat :: Str ( "!" ) , expr_search_pat_inner ( tcx, e, outer_ctxt) . 1 ) ,
161+ ExprKind :: Unary ( UnOp :: Neg , e) => ( Pat :: Str ( "-" ) , expr_search_pat_inner ( tcx, e, outer_ctxt) . 1 ) ,
162+ ExprKind :: Lit ( lit) => lit_search_pat ( & lit. node ) ,
163+ ExprKind :: Array ( _) | ExprKind :: Repeat ( ..) => ( Pat :: Str ( "[" ) , Pat :: Str ( "]" ) ) ,
164+ ExprKind :: Call ( e, [ ] ) | ExprKind :: MethodCall ( _, e, [ ] , _) => {
165+ ( expr_search_pat_inner ( tcx, e, outer_ctxt) . 0 , Pat :: Str ( "(" ) )
181166 } ,
182- None ,
183- ) => ( Pat :: Str ( "unsafe" ) , Pat :: Str ( "}" ) ) ,
184- ExprKind :: Block ( _, None ) => ( Pat :: Str ( "{" ) , Pat :: Str ( "}" ) ) ,
185- ExprKind :: Field ( e, name) => ( expr_search_pat ( tcx, e) . 0 , Pat :: Sym ( name. name ) ) ,
186- ExprKind :: Index ( e, _, _) => ( expr_search_pat ( tcx, e) . 0 , Pat :: Str ( "]" ) ) ,
187- ExprKind :: Path ( ref path) => qpath_search_pat ( path) ,
188- ExprKind :: AddrOf ( _, _, e) => ( Pat :: Str ( "&" ) , expr_search_pat ( tcx, e) . 1 ) ,
189- ExprKind :: Break ( Destination { label : None , .. } , None ) => ( Pat :: Str ( "break" ) , Pat :: Str ( "break" ) ) ,
190- ExprKind :: Break ( Destination { label : Some ( name) , .. } , None ) => ( Pat :: Str ( "break" ) , Pat :: Sym ( name. ident . name ) ) ,
191- ExprKind :: Break ( _, Some ( e) ) => ( Pat :: Str ( "break" ) , expr_search_pat ( tcx, e) . 1 ) ,
192- ExprKind :: Continue ( Destination { label : None , .. } ) => ( Pat :: Str ( "continue" ) , Pat :: Str ( "continue" ) ) ,
193- ExprKind :: Continue ( Destination { label : Some ( name) , .. } ) => ( Pat :: Str ( "continue" ) , Pat :: Sym ( name. ident . name ) ) ,
194- ExprKind :: Ret ( None ) => ( Pat :: Str ( "return" ) , Pat :: Str ( "return" ) ) ,
195- ExprKind :: Ret ( Some ( e) ) => ( Pat :: Str ( "return" ) , expr_search_pat ( tcx, e) . 1 ) ,
196- ExprKind :: Struct ( path, _, _) => ( qpath_search_pat ( path) . 0 , Pat :: Str ( "}" ) ) ,
197- ExprKind :: Yield ( e, YieldSource :: Yield ) => ( Pat :: Str ( "yield" ) , expr_search_pat ( tcx, e) . 1 ) ,
198- _ => ( Pat :: Str ( "" ) , Pat :: Str ( "" ) ) ,
167+ ExprKind :: Call ( first, [ .., last] )
168+ | ExprKind :: MethodCall ( _, first, [ .., last] , _)
169+ | ExprKind :: Binary ( _, first, last)
170+ | ExprKind :: Tup ( [ first, .., last] )
171+ | ExprKind :: Assign ( first, last, _)
172+ | ExprKind :: AssignOp ( _, first, last) => (
173+ expr_search_pat_inner ( tcx, first, outer_ctxt) . 0 ,
174+ expr_search_pat_inner ( tcx, last, outer_ctxt) . 1 ,
175+ ) ,
176+ ExprKind :: Tup ( [ e] ) | ExprKind :: DropTemps ( e) => expr_search_pat_inner ( tcx, e, outer_ctxt) ,
177+ ExprKind :: Cast ( e, _) | ExprKind :: Type ( e, _) => ( expr_search_pat_inner ( tcx, e, outer_ctxt) . 0 , Pat :: Str ( "" ) ) ,
178+ ExprKind :: Let ( let_expr) => ( Pat :: Str ( "let" ) , expr_search_pat_inner ( tcx, let_expr. init , outer_ctxt) . 1 ) ,
179+ ExprKind :: If ( ..) => ( Pat :: Str ( "if" ) , Pat :: Str ( "}" ) ) ,
180+ ExprKind :: Loop ( _, Some ( _) , _, _) | ExprKind :: Block ( _, Some ( _) ) => ( Pat :: Str ( "'" ) , Pat :: Str ( "}" ) ) ,
181+ ExprKind :: Loop ( _, None , LoopSource :: Loop , _) => ( Pat :: Str ( "loop" ) , Pat :: Str ( "}" ) ) ,
182+ ExprKind :: Loop ( _, None , LoopSource :: While , _) => ( Pat :: Str ( "while" ) , Pat :: Str ( "}" ) ) ,
183+ ExprKind :: Loop ( _, None , LoopSource :: ForLoop , _) | ExprKind :: Match ( _, _, MatchSource :: ForLoopDesugar ) => {
184+ ( Pat :: Str ( "for" ) , Pat :: Str ( "}" ) )
185+ } ,
186+ ExprKind :: Match ( _, _, MatchSource :: Normal ) => ( Pat :: Str ( "match" ) , Pat :: Str ( "}" ) ) ,
187+ ExprKind :: Match ( e, _, MatchSource :: TryDesugar ( _) ) => {
188+ ( expr_search_pat_inner ( tcx, e, outer_ctxt) . 0 , Pat :: Str ( "?" ) )
189+ } ,
190+ ExprKind :: Match ( e, _, MatchSource :: AwaitDesugar ) | ExprKind :: Yield ( e, YieldSource :: Await { .. } ) => {
191+ ( expr_search_pat_inner ( tcx, e, outer_ctxt) . 0 , Pat :: Str ( "await" ) )
192+ } ,
193+ ExprKind :: Closure ( & Closure { body, .. } ) => (
194+ Pat :: Str ( "" ) ,
195+ expr_search_pat_inner ( tcx, tcx. hir ( ) . body ( body) . value , outer_ctxt) . 1 ,
196+ ) ,
197+ ExprKind :: Block (
198+ Block {
199+ rules : BlockCheckMode :: UnsafeBlock ( UnsafeSource :: UserProvided ) ,
200+ ..
201+ } ,
202+ None ,
203+ ) => ( Pat :: Str ( "unsafe" ) , Pat :: Str ( "}" ) ) ,
204+ ExprKind :: Block ( _, None ) => ( Pat :: Str ( "{" ) , Pat :: Str ( "}" ) ) ,
205+ ExprKind :: Field ( e, name) => ( expr_search_pat_inner ( tcx, e, outer_ctxt) . 0 , Pat :: Sym ( name. name ) ) ,
206+ ExprKind :: Index ( e, _, _) => ( expr_search_pat_inner ( tcx, e, outer_ctxt) . 0 , Pat :: Str ( "]" ) ) ,
207+ ExprKind :: Path ( ref path) => qpath_search_pat ( path) ,
208+ ExprKind :: AddrOf ( _, _, e) => ( Pat :: Str ( "&" ) , expr_search_pat_inner ( tcx, e, outer_ctxt) . 1 ) ,
209+ ExprKind :: Break ( Destination { label : None , .. } , None ) => ( Pat :: Str ( "break" ) , Pat :: Str ( "break" ) ) ,
210+ ExprKind :: Break ( Destination { label : Some ( name) , .. } , None ) => {
211+ ( Pat :: Str ( "break" ) , Pat :: Sym ( name. ident . name ) )
212+ } ,
213+ ExprKind :: Break ( _, Some ( e) ) => ( Pat :: Str ( "break" ) , expr_search_pat_inner ( tcx, e, outer_ctxt) . 1 ) ,
214+ ExprKind :: Continue ( Destination { label : None , .. } ) => ( Pat :: Str ( "continue" ) , Pat :: Str ( "continue" ) ) ,
215+ ExprKind :: Continue ( Destination { label : Some ( name) , .. } ) => {
216+ ( Pat :: Str ( "continue" ) , Pat :: Sym ( name. ident . name ) )
217+ } ,
218+ ExprKind :: Ret ( None ) => ( Pat :: Str ( "return" ) , Pat :: Str ( "return" ) ) ,
219+ ExprKind :: Ret ( Some ( e2) ) => ( Pat :: Str ( "return" ) , expr_search_pat_inner ( tcx, e2, outer_ctxt) . 1 ) ,
220+ ExprKind :: Struct ( path, _, _) => ( qpath_search_pat ( path) . 0 , Pat :: Str ( "}" ) ) ,
221+ ExprKind :: Yield ( e, YieldSource :: Yield ) => ( Pat :: Str ( "yield" ) , expr_search_pat_inner ( tcx, e, outer_ctxt) . 1 ) ,
222+ _ => ( Pat :: Str ( "" ) , Pat :: Str ( "" ) ) ,
223+ }
199224 }
225+
226+ expr_search_pat_inner ( tcx, e, e. span . ctxt ( ) )
200227}
201228
202229fn fn_header_search_pat ( header : FnHeader ) -> Pat {
0 commit comments