@@ -302,19 +302,38 @@ impl EarlyLintPass for UnusedParens {
302
302
Assign ( _, ref value) => ( value, "assigned value" , false ) ,
303
303
AssignOp ( .., ref value) => ( value, "assigned value" , false ) ,
304
304
InPlace ( _, ref value) => ( value, "emplacement value" , false ) ,
305
- Call ( _, ref args) => {
306
- for arg in args {
307
- self . check_unused_parens_core ( cx, arg, "function argument" , false )
305
+ // either function/method call, or something this lint doesn't care about
306
+ ref call_or_other => {
307
+ let args_to_check;
308
+ let call_kind;
309
+ match * call_or_other {
310
+ Call ( _, ref args) => {
311
+ call_kind = "function" ;
312
+ args_to_check = & args[ ..] ;
313
+ } ,
314
+ MethodCall ( _, ref args) => {
315
+ call_kind = "method" ;
316
+ // first "argument" is self (which sometimes needs parens)
317
+ args_to_check = & args[ 1 ..] ;
318
+ }
319
+ // actual catch-all arm
320
+ _ => { return ; }
308
321
}
309
- return ;
310
- } ,
311
- MethodCall ( _, ref args) => {
312
- for arg in & args[ 1 ..] { // first "argument" is self (which sometimes needs parens)
313
- self . check_unused_parens_core ( cx, arg, "method argument" , false )
322
+ // Don't lint if this is a nested macro expansion: otherwise, the lint could
323
+ // trigger in situations that macro authors shouldn't have to care about, e.g.,
324
+ // when a parenthesized token tree matched in one macro expansion is matched as
325
+ // an expression in another and used as a fn/method argument (Issue #47775)
326
+ if e. span . ctxt ( ) . outer ( ) . expn_info ( )
327
+ . map_or ( false , |info| info. call_site . ctxt ( ) . outer ( )
328
+ . expn_info ( ) . is_some ( ) ) {
329
+ return ;
330
+ }
331
+ let msg = format ! ( "{} argument" , call_kind) ;
332
+ for arg in args_to_check {
333
+ self . check_unused_parens_core ( cx, arg, & msg, false ) ;
314
334
}
315
335
return ;
316
336
}
317
- _ => return ,
318
337
} ;
319
338
self . check_unused_parens_core ( cx, & value, msg, struct_lit_needs_parens) ;
320
339
}
0 commit comments