Skip to content

Special case matches! macro#5554

Open
ytmimi wants to merge 11 commits into
rust-lang:mainfrom
ytmimi:special_case_matches_macro
Open

Special case matches! macro#5554
ytmimi wants to merge 11 commits into
rust-lang:mainfrom
ytmimi:special_case_matches_macro

Conversation

@ytmimi
Copy link
Copy Markdown
Contributor

@ytmimi ytmimi commented Oct 1, 2022

Closes #4462
Closes #5547
Closes #5709
Closes #5860
Closes #6650
Closes #6714

Related / duplicate issues #4885 #5176

This PR adds support to parse and format the arguments of the matches! macro. Now matches! formatting more closely resembles match expressions. This update introduces breaking formatting changes and is only supported when formatting with style_edition=2027.

r? @calebcartwright

I've done my best to logically group commits and I think this PR would be best reviewed 1 commit at a time.

@ytmimi ytmimi force-pushed the special_case_matches_macro branch 2 times, most recently from 5e5c766 to e834841 Compare October 1, 2022 17:14
matches!(
something,
Some(_)
if method(
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The indentation here looks weird in my opinion. The indentation makes sense in match context because a match might contain multiple arms but the matches! macro does not.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I appreciate the feedback. My goal with this PR was to make matches! formatting consistent with match expression formatting, and this particular formatting is a result of reusing rewrite_guard to not have to reimplement guard formatting.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@calebcartwright maybe t-style would want to chime in on the guard formatting here

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Has this been discussed somewhere or yet. If so, what was the conclusion?

@calebcartwright
Copy link
Copy Markdown
Member

I feel like we discussed this a tad offline some time back, but probably worth posting here too that I think a big consideration around this is whether it needs to be version gated.

A question i've had teed up to the style team for a while is if/how macro calls should have style guide prescriptions or whether it's going to be something completely deferred to rustfmt.

In either case, I suspect it's highly likely this will need to be gated, and could perhaps become the new default as part of the 2024 style edition

Comment thread src/macros.rs Outdated
Comment on lines +235 to +238
} else if macro_name == "matches!" && context.config.version() == Version::Two {
if let success @ Some(..) = format_matches(context, shape, &macro_name, mac) {
return success;
}
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@calebcartwright per your comment #5554 (comment), I just wanted to let you know that the changes are version gated.

I don't think there's a rush to get this in, and we can definitely hold off until style_edition lands to gate this around the 2024 style edition.

@ytmimi
Copy link
Copy Markdown
Contributor Author

ytmimi commented Jul 31, 2023

note to self, add a test case for #5860

@cynecx
Copy link
Copy Markdown

cynecx commented Jun 12, 2024

Sorry for the bump, but there hasn't been any public news on this for almost a year now. Have there been any discussions or anything about whether to include this in the 2024 edition or what the next steps are here?

@ytmimi
Copy link
Copy Markdown
Contributor Author

ytmimi commented Jun 12, 2024

Sorry for the bump, but there hasn't been any public news on this for almost a year now. Have there been any discussions or anything about whether to include this in the 2024 edition or what the next steps are here?

This isn't something that the team has discussed in quite some time so I don't have any updated to share from rustfmt. To the best of my knowledge the style-team has had some discussions on the 2024 edition, and these are the tracking issues for rustfmt.

@ytmimi ytmimi force-pushed the special_case_matches_macro branch from 0c5552d to 92afb9d Compare August 31, 2025 03:15
@ytmimi ytmimi added the A-2027-style-edition Area: style edition 2027 label Aug 31, 2025
@freerig
Copy link
Copy Markdown

freerig commented Oct 25, 2025

Hi, I also found this bug, which is produced when two ranges are in a matches!, separated by |. I don't think it's a duplicate because it's specific to ranges (when you remove a range from the code, it works).

The first step in being able to format the `matches!` macro is to parse
it into ast nodes that we know how to rewrite.
The guard rewrite rules vary based on how the pattern was rewritten.
That logic was previously written in `rewrite_match_arm`, but now it's
fully encapsulates in `rewrite_guard`.
These traits will make it easier to implement rewriting matches! in terms
of `overflow::rewrite_with_*` methods.
Now that we're able to parse the TokenStream of `matches!` calls into a
 `Matches` struct and then convert that `Matches` struct into an
iterable which implments `IntoOverflowableItem` we're able to implement
`matches!` rewriting in terms of `overflow::rewrite_with_*` calls.
The unit tests cover version One and Two formatting
Since rustfmt uses version two formatting the self tests were failing
due to the new special case handling for `matches!`. various `matches!`
calls in the codebase were updated to address this issue.
@jieyouxu jieyouxu added S-waiting-on-review Status: awaiting review from the assignee but also interested parties. and removed pr-not-reviewed labels Feb 23, 2026
@bjorn3
Copy link
Copy Markdown
Member

bjorn3 commented Feb 23, 2026

Why does there need to be a special case for matches!? I don't think rustfmt should ever edit the actual tokens inside an unknown macro? It is fine to heuristically assume that the content is an expression with respect to whitespace insertion/deletion, at worst that would just result in an ugly output. Changing the actual tokens on the other hand risks changing the runtime behavior of the code or creating a compilation error if rustfmt guessed wrong.

@rustbot
Copy link
Copy Markdown
Collaborator

rustbot commented Mar 13, 2026

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

Comment thread src/macros.rs
_ => return Err(err),
},
}
} else if macro_name == "matches!"
Copy link
Copy Markdown
Contributor

@anatawa12 anatawa12 May 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel it might be better to support (debug_)assert_matches will be stabilized in 1.96 macros in similar bases.

View changes since the review

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-2027-style-edition Area: style edition 2027 S-waiting-on-review Status: awaiting review from the assignee but also interested parties.

Projects

None yet

8 participants