Change:
The latest beta contains a new? l lint that triggers on macro by example code. This does not necessarily make sense because macros could be used to construct nearly arbitrary custom syntax for example something requiring to wrap a single element into a parenthesis. The strange thing here is that seems to only happen on beta, not on nightly, not on current stable. Found via Error message: rustc version:
My head can't come up with an example that requires parentheses. macros are hygenic, so there should be no problem in omitting the parentheses and just writing will be fine. Can you give me a counter example?
A real world example is the diesel  macro. Somewhere in the inner it does some clever things to support plain types and tuples by just saying where is some repeated type variable. Depending on the number of actual types there this will result in which is a single type or which is a tuple. It's probably possible to rewrite that code doing the same stuff but that would involve a lot of duplication (Because than you would need to have a special case for a single type everywhere).
So somehing like this: You're right. The question is: should we remove the lint for all macros? Only for macros that contain repetitive expansions? (Is that even possible to detect?)
modify labels: A-lint T-compiler
Would be great to get that fixed till it is part of the next stable release.
This seems to occur first on nightly-2019-11-02
nominating for discussing at T-compiler + T-lang meeting, namely to take peoples' temperature with respect to the idea of just not linting this case when the flagged code appears as part of a macro definition.
also, marking as P-high w.r.t. answer the question(s) posed here. (I personally don't think the severity of the actual impact is likely to be worth a P-high rating; the priority is likely just temporary until the discussion happens.)
The language team discussed this last week. The general consensus was that we can stop linting when the redundant parens are inside the macro (as opposed to e.g. where the spans are from the outside). We believe this is fine as the lint is mostly a style thing which does not protect from anything correctness or performance related.
I've played a bit around with this issue today. Seems like conditions need to be adjusted to also check if we are in macro expanded code. I've tried something like but that does remove more warnings that we want.
I think the questions have been basically answered in terms of what path we see best going forward. Self-assigning, removing I-nominated.

Discussion:
match value.kind { ast::ExprKind::Paren(ref inner) => { if !Self::is_expr_parens_necessary(inner, followed_by_block) && <del> value.attrs.is_empty() { </del> <ins> value.attrs.is_empty() && !value.span.from_expansion() { </ins> let expr_text = if let Ok(snippet) = cx.sess().source_map() .span_to_snippet(value.span) { snippet

macro_rules! and_the_heavens_reject_not { () => { <del> // ↓ But let's test that we still lint for unused parens around // function args inside of simple, one-deep macros. </del> #[allow(dead_code)] fn the_night_for_the_morrow() -> Option<isize> { Some((2)) } <del> //~^ WARN unnecessary parentheses around function argument </del> } }

<del> warning: unnecessary parentheses around function argument --> $DIR/issue-47775-nested-macro-unnecessary-parens-arg.rs:22:83 | LL |         #[allow(dead_code)] fn the_night_for_the_morrow() -> Option<isize> { Some((2)) } |                                                                                   ^^^ help: remove these parentheses ... LL | and_the_heavens_reject_not!(); | ------------------------------ in this macro invocation | note: lint level defined here --> $DIR/issue-47775-nested-macro-unnecessary-parens-arg.rs:3:9 | LL | #![warn(unused_parens)] |         ^^^^^^^^^^^^^ </del>

panic!() } <ins> macro_rules! baz { ($($foo:expr),+) => { ($($foo),*) } } </ins> fn main() { foo(); bar((true)); //~ ERROR unnecessary parentheses around function argument

let mut _a = (0); //~ ERROR unnecessary parentheses around assigned value _a = (0); //~ ERROR unnecessary parentheses around assigned value _a += (1); //~ ERROR unnecessary parentheses around assigned value <ins> let _a = baz!(3, 4); let _b = baz!(3); </ins> }

|                                          ^^^^^ help: remove these parentheses error: unnecessary parentheses around function argument <del> --> $DIR/lint-unnecessary-parens.rs:30:9 </del> <ins> --> $DIR/lint-unnecessary-parens.rs:36:9 </ins> | LL |     bar((true)); |         ^^^^^^ help: remove these parentheses error: unnecessary parentheses around `if` condition <del> --> $DIR/lint-unnecessary-parens.rs:32:8 </del> <ins> --> $DIR/lint-unnecessary-parens.rs:38:8 </ins> | LL |     if (true) {} |        ^^^^^^ help: remove these parentheses error: unnecessary parentheses around `while` condition <del> --> $DIR/lint-unnecessary-parens.rs:33:11 </del> <ins> --> $DIR/lint-unnecessary-parens.rs:39:11 </ins> | LL |     while (true) {} |           ^^^^^^ help: remove these parentheses warning: denote infinite loops with `loop { ... }` <del> --> $DIR/lint-unnecessary-parens.rs:33:5 </del> <ins> --> $DIR/lint-unnecessary-parens.rs:39:5 </ins> | LL |     while (true) {} |     ^^^^^^^^^^^^ help: use `loop`

= note: `#[warn(while_true)]` on by default error: unnecessary parentheses around `match` head expression <del> --> $DIR/lint-unnecessary-parens.rs:35:11 </del> <ins> --> $DIR/lint-unnecessary-parens.rs:41:11 </ins> | LL |     match (true) { |           ^^^^^^ help: remove these parentheses error: unnecessary parentheses around `let` head expression <del> --> $DIR/lint-unnecessary-parens.rs:38:16 </del> <ins> --> $DIR/lint-unnecessary-parens.rs:44:16 </ins> | LL |     if let 1 = (1) {} |                ^^^ help: remove these parentheses error: unnecessary parentheses around `let` head expression <del> --> $DIR/lint-unnecessary-parens.rs:39:19 </del> <ins> --> $DIR/lint-unnecessary-parens.rs:45:19 </ins> | LL |     while let 1 = (2) {} |                   ^^^ help: remove these parentheses error: unnecessary parentheses around method argument <del> --> $DIR/lint-unnecessary-parens.rs:53:24 </del> <ins> --> $DIR/lint-unnecessary-parens.rs:59:24 </ins> | LL |     X { y: false }.foo((true)); |                        ^^^^^^ help: remove these parentheses error: unnecessary parentheses around assigned value <del> --> $DIR/lint-unnecessary-parens.rs:55:18 </del> <ins> --> $DIR/lint-unnecessary-parens.rs:61:18 </ins> | LL |     let mut _a = (0); |                  ^^^ help: remove these parentheses error: unnecessary parentheses around assigned value <del> --> $DIR/lint-unnecessary-parens.rs:56:10 </del> <ins> --> $DIR/lint-unnecessary-parens.rs:62:10 </ins> | LL |     _a = (0); |          ^^^ help: remove these parentheses error: unnecessary parentheses around assigned value <del> --> $DIR/lint-unnecessary-parens.rs:57:11 </del> <ins> --> $DIR/lint-unnecessary-parens.rs:63:11 </ins> | LL |     _a += (1); |           ^^^ help: remove these parentheses