Skip to content

Support if-let guards in matches macros by using :guard matcher#156025

Open
SpriteOvO wants to merge 2 commits into
rust-lang:mainfrom
SpriteOvO:matches-guard
Open

Support if-let guards in matches macros by using :guard matcher#156025
SpriteOvO wants to merge 2 commits into
rust-lang:mainfrom
SpriteOvO:matches-guard

Conversation

@SpriteOvO
Copy link
Copy Markdown
Member

@SpriteOvO SpriteOvO commented May 1, 2026

Tracking issue #153104.

This PR replaces the original if $guard:expr with new matcher $guard:guard in macros matches! and assert_matches! to support the use of if-let guards syntax in these macros. This syntax is already stable in #141295 for match arms.

Please note that this PR directly applies :guard to macros that are already stable, so the support for if-let guards in these macros is instantly stable.

When using these macros that accept :guard, users will not be required to use nightly and enable #![feature(macro_guard_matcher)]. However, when defining macros with :guard, nightly and #![feature(macro_guard_matcher)] are still required. Therefore, I think a Crater run is needed.

cc @programmerjake
r? libs

@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. T-libs Relevant to the library team, which will review and decide on the PR/issue. labels May 1, 2026
@SpriteOvO
Copy link
Copy Markdown
Member Author

Please note that this PR directly applies :guard to macros that are already stable, so the support for if-let guards in these macros is instantly stable.

When using these macros that accept :guard, users will not be required to use nightly and enable #![feature(macro_guard_matcher)]. However, when defining macros with :guard, nightly and #![feature(macro_guard_matcher)] are still required. Therefore, I think a Crater run is needed.

Alternatively, to be more safe, we only provide the :guard version of macros when users activate macro_guard_matcher, otherwise falling back to the original if $e:expr version. But I couldn't find a way to write something like #[cfg(unstable_feature = "macro_guard_matcher")] in stdlib.

@Mark-Simulacrum Mark-Simulacrum added needs-fcp This change is insta-stable, or significant enough to need a team FCP to proceed. S-waiting-on-t-libs-api Status: Awaiting decision from T-libs-api and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels May 9, 2026
@nia-e
Copy link
Copy Markdown
Member

nia-e commented May 12, 2026

Hi - could you provide us some examples of where this might be a breaking change? We discussed this in the libs-api meeting but it wasn't quite clear what this might affect

@SpriteOvO
Copy link
Copy Markdown
Member Author

NonterminalKind::Guard => {
const TOKENS: &[&str] = &["`=>`", "`,`", "`{`"];
match tok {
TokenTree::Token(token) => match token.kind {
FatArrow | Comma | OpenBrace => IsInFollow::Yes,
_ => IsInFollow::No(TOKENS),
},
_ => IsInFollow::No(TOKENS),
}
}

@nia-e My main concern was in is_in_follow function, because the comment states it impacts future compatibility。 @fmease has also noted an unresolved question regarding this in the tracking issue. Let me quote it here and explain my thoughts alongside it:

  • (fmease writing) Should { really be in the follow set? I'm not quite sure it should.
    • The condition of match guards can be an "unrestricted" expressions precisely because the guard can only be followed by => contrary to the conditions of if & while expressions and the iterator of for loops which are expressions without struct expressions.
    • So while if S {} successfully parses as an expression (namely as if (S) {}), macro matcher $g:guard {} currently rejects if S {} as input because it parses if (S {}) and looks for extra { } which aren't there of course.

I took some time to rethink it, given that the original intent of this matcher was just to simplify matching match-guards, rather than to allow users to extend the syntax with custom rules. And strictly according to MatchArmGuard, { is indeed not supposed to follow it. In that case, removing it might be better, or at least a conservative choice.

The requested Crater run was also based on the potential impacts mentioned above, plus, it’s instantly stable. If we decide to remove { from the follow-set, is the Crater run still needed? (Tbh, this is my first time requesting a Crater run, I'm not quite sure if such a change is worth a run)

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

Labels

needs-fcp This change is insta-stable, or significant enough to need a team FCP to proceed. S-waiting-on-t-libs-api Status: Awaiting decision from T-libs-api T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-libs Relevant to the library team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants