Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

handle paren in macro expand for let-init-else expr #134034

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

bvanjoi
Copy link
Contributor

@bvanjoi bvanjoi commented Dec 8, 2024

Fixes #131655

This PR modifies the codegen logic of the macro expansion within let-init-else expression:

  • Before: The expression let xxx = (mac! {}) else {} expands to let xxx = (expanded_ast) else {}.
  • After: The same expression expands to let xxx = expanded_ast else {}.

An alternative solution to this issue could involve handling the source code directly when encountering unused parentheses in let-init-else expressions. However, this approach might be more cumbersome due to the absence of the necessary data structure.

r? @petrochenkov

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Dec 8, 2024
@cjgillot
Copy link
Contributor

cjgillot commented Dec 8, 2024

This seems like a far reaching change because of a buggy lint.
Would a targeted exception on the lint itself be simpler?

@bvanjoi
Copy link
Contributor Author

bvanjoi commented Dec 9, 2024

Would a targeted exception on the lint itself be simpler?

If we follow this thought, we need to check the original AST for init_expr in let-init-else when encountering unused_paren. There are two possible approaches:

  • Parse the expression again to check if it is a macro call with braces.
  • Record the node_id if the paren expression contains a macro call with braces during expansion.

@petrochenkov
Copy link
Contributor

This is an issue with any context that restricts braces, right?
Like plain if:

fn main() {
    macro_rules! x {
        () => { true }
    }

    if (x! {}) {} // warning: unnecessary parentheses around `if` condition
}

See NO_STRUCT_LITERAL in the parser for all such contexts.
IIRC, braced macro calls like mac! {} are currently prohibited in all such contexts for consistency with other braced syntaxes (even if it's not technically necessary) due to a relatively recent lang team decision.

@dtolnay
Copy link
Member

dtolnay commented Dec 10, 2024

if (x! {}) {} is actually unnecessary parentheses. if x! {} {} is valid syntax.

@petrochenkov
Copy link
Contributor

Perhaps the lint should look at span of the expression inside the parentheses, check what macro expansion it comes from, and suppress the warning in suspicious cases.
The current implementation in this PR is certainly not the way to go.

IIRC @dtolnay was also recently working on pretty-printing / linting (un)necessary parentheses, maybe he has more suggestions.

@petrochenkov petrochenkov added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Dec 10, 2024
@bvanjoi
Copy link
Contributor Author

bvanjoi commented Dec 11, 2024

Update: It now stores the span of necessary parenthesis nodes and uses it when checking for unused_parens lint.

@bvanjoi
Copy link
Contributor Author

bvanjoi commented Dec 12, 2024

@rustbot ready

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Dec 12, 2024
@bors
Copy link
Collaborator

bors commented Dec 14, 2024

☔ The latest upstream changes (presumably #134269) made this pull request unmergeable. Please resolve the merge conflicts.

@petrochenkov
Copy link
Contributor

Sorry for the long delay.

I think the current version is still too much.
This can probably be fixed by a simpler heuristic local to compiler/rustc_lint/src/unused.rs - in if expr { ... } we look 1) at the span of expr and 2) at the span of the whole if expr { ... }, and if syntactic contexts of the spans do not match then we suppress the lint.
Something like Span::contains or similar could also be used instead of context comparison.
Other lints and diagnostics are full of checks like this.
@rustbot author

@rustbot rustbot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Mar 10, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

false positive for unused_parens in a let-else
6 participants