You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Mention this macro in the documentation of matches!()
Unresolved Questions
Add => expr syntax?
Nope, too confusing. (See discussion below.)
Reacted by Demiu, Sebastian Pipping, Andreas Borgen Longva, Yuri Astrakhan, Michael Diamond, Mo Bitar, Misha Antonenko, sunrosa, Danny C Jones, qj and 37 more
Reacted by Felipe S. S. Schneider, Alik Send, musjj, orca and Petr Portnov | PROgrm_JARvis
Reacted by Lachezar Lechev, Shirshak, Mattias Buelens, Joel Höner, Ben, Mathias Bayon, TrolledWoods, Chris Pearce, Squirrel, Smitty and 114 more
Reacted by Andrew Ares, Benoît Cortier, Moritz Hedtke, Elichai Turkel, Roy Laurie, Cherry, Jeremiah Senkpiel, Mo Bitar, musjj, bbb651 🇮🇱 and 2 more
Reacted by Artem Diachenko, musjj, ldanko, bbb651 🇮🇱 and Felipe S. S. Schneider
Several implementations of assert_matches!() in the ecosystem also accept an => expr syntax, to do something with the matched values or even return something from the macro.
As a (almost) daily user of the assert_matches crate, I have to admit that without the additional $pat => $expr syntax, for most me it would be still impractical to use.
I.e. asserting a certain sequence of messages with a mocked context and assuring the messages have expected content (which by design may not impl {Partial,}Eq) I would usually use (super simplified):
While your approach is valid for simple cases, I disagree for the general use case. This is not very ergonomic as soon as there are various sub patterns, that have to be asserted against transformed struct member values or larger enums with multiple elements common for messaging enums.
It could still be expressed with boolean expression combinators using the current impl, yet that adds a lot visual complexity that imho should not exist in a test case.
Note that I am not saying the impl is bad or anything :) - I would very much like to see assert_matches! in std! This effort is much appreciated!
Should assert_matches accept => { .. } blocks to allow for nested asserts (and other code)? The existing assert_matches macros in the ecosystem accept that. But I personally feel it makes things a bit too complicated and unclear.
It's an interesting extension. At first it looked a bit odd to me, but after ruminating on it a bit, it does seem fairly natural to me.
In terms of moving forward:
Would adding this later be a backwards compatible addition?
How often is this extension used in practice? In theory, we could search the code on crates.io and count the ratio between uses of assert_matches! with and without this extension. If the ratio is very small, then maybe we land it without the extension if the answer to (1) is "yes."
This seems very similar, and I feel like the arguments are the same. If we have assert_matches!(x, Some(Variant(a, b)) => a == b), similar use cases would motivate if matches!(x, Some(Variant(a, b)) => a == b) { ... }.
I personally feel that in both cases the => syntax adds enough complexity to make it worth spelling out a match or if let, instead. I don't really want to see an entire block of arbitrary code embedded inside an assert_matches!. I also think this will become easier to write when we finish if let chaining.
Reacted by Andrew Gallant, Squirrel, Mikhail Zabaluev, Miraculous Owonubi, Lily, Js2xxx, Robert Bastian, Antti Korpi, Curstantine, Techcable and 3 more
assert_matches!(x, Some((a, b)) if a == b) would assert that x is a Some and a and b are equal, but assert_matches!(x, Some((a, b)) => a == b) would only assert that x is a Some, and return the value of a == b without asserting anything about it. The difference there is far too subtle for me.
We could require the => expr to be (), but I don't think that solves the problem of unclear semantics entirely.
assert_matches!(x, Some((a, b)) if a == b) would assert that x is a Some and a and b are equal, but assert_matches!(x, Some((a, b)) => a == b) would only assert that x is a Some, and return the value of a == b without asserting anything about it. The difference there is far too subtle for me.
A separate macro that always requires a => expr arm i.e. unwrap_matchesextract_matches might make it less ambiguous/more clear
Reacted by Sasha Pourcelot, Lain-dono, Daniel Henry-Mantilla, Martin Fischer, Hennadii Chernyshchyk, Bernhard Schuster, Brandon H. Gomes, Olivier FAURE, Remoun Metyas, Michael Pacheco and 1 more
While your approach is valid for simple cases, I disagree for the general use case. This is not very ergonomic as soon as there are various sub patterns, that have to be asserted against transformed struct member values or larger enums with multiple elements common for messaging enums.
It could still be expressed with boolean expression combinators using the current impl, yet that adds a lot visual complexity that imho should not exist in a test case.
Note that I am not saying the impl is bad or anything :) - I would very much like to see assert_matches! in std! This effort is much appreciated!
Your example can be rewritten to a match guard that always returns true except when it panics, like this.
-assert_matches!(rx.next(), Some(Msgs::Specific { a, b: B(b), .. }) => {+assert_matches!(rx.next(), Some(Msgs::Specific { a, b: B(b), .. }) if ({
assert_eq!(a, b);
let container = transform($container);
if container.is_empty() {
assert!(/* … */);
} else {
assert!(/* … */);
}
-});+ true+}));
Definitely non-obvious when you don't know about it, but hardly worse to write if you are adding to an existing test suite with the pattern everywhere.
Reacted by Bernhard Schuster, Remoun Metyas and Rain
Looking at release notes, it appears as though the scoping was backported to beta and will land on stable tomorrow (in 1.96).
Reacted by TeamDman, Benoit de Chezelles, Andrew Banchich, Alejandro, Iohann Rabeson, Thayne McCombs, Shahar "Dawn" Or, Wiktor Kwapisiewicz, aslowwriter, Rob Ede and 2 more
Activity
m-ou-se commentedon Mar 9, 2021
Several implementations of
assert_matches!()in the ecosystem also accept an=> exprsyntax, to do something with the matched values or even return something from the macro.This is currently not supported by
std::assert_matches!()as implemented in #82770.Adding it would allow things like:
and
drahnr commentedon Mar 11, 2021
As a (almost) daily user of the
assert_matchescrate, I have to admit that without the additional$pat => $exprsyntax, for most me it would be still impractical to use.I.e. asserting a certain sequence of messages with a mocked context and assuring the messages have expected content (which by design may not impl
{Partial,}Eq) I would usually use (super simplified):so for this the extension with
=>is required to replace the crateassert_matchesin practice from my experience.m-ou-se commentedon Mar 11, 2021
In cases like that, the
ifguard on the pattern also works, right?drahnr commentedon Mar 23, 2021
While your approach is valid for simple cases, I disagree for the general use case. This is not very ergonomic as soon as there are various sub patterns, that have to be asserted against transformed struct member values or larger enums with multiple elements common for messaging enums.
It could still be expressed with boolean expression combinators using the current impl, yet that adds a lot visual complexity that imho should not exist in a test case.
Note that I am not saying the impl is bad or anything :) - I would very much like to see
assert_matches!instd! This effort is much appreciated!m-ou-se commentedon Mar 23, 2021
@rust-lang/libs Ping for opinions.
Should
assert_matchesaccept=> { .. }blocks to allow for nested asserts (and other code)? The existingassert_matchesmacros in the ecosystem accept that. But I personally feel it makes things a bit too complicated and unclear.BurntSushi commentedon Mar 23, 2021
It's an interesting extension. At first it looked a bit odd to me, but after ruminating on it a bit, it does seem fairly natural to me.
In terms of moving forward:
assert_matches!with and without this extension. If the ratio is very small, then maybe we land it without the extension if the answer to (1) is "yes."joshtriplett commentedon Mar 23, 2021
This makes me think of the proposal to add
=>syntax tomatches!, which the libs team declined.This seems very similar, and I feel like the arguments are the same. If we have
assert_matches!(x, Some(Variant(a, b)) => a == b), similar use cases would motivateif matches!(x, Some(Variant(a, b)) => a == b) { ... }.I personally feel that in both cases the
=>syntax adds enough complexity to make it worth spelling out amatchorif let, instead. I don't really want to see an entire block of arbitrary code embedded inside anassert_matches!. I also think this will become easier to write when we finishif letchaining.m-ou-se commentedon Mar 24, 2021
assert_matches!(x, Some((a, b)) if a == b)would assert that x is a Some and a and b are equal, butassert_matches!(x, Some((a, b)) => a == b)would only assert that x is a Some, and return the value ofa == bwithout asserting anything about it. The difference there is far too subtle for me.We could require the
=> exprto be(), but I don't think that solves the problem of unclear semantics entirely.joshtriplett commentedon Mar 24, 2021
For me as well; that was not clear to me at all.
BoxyUwU commentedon Jun 4, 2021
A separate macro that always requires a
=> exprarm i.e.unwrap_matchesextract_matchesmight make it less ambiguous/more cleargilescope commentedon Jul 5, 2021
Well if we're agreed on leaving it as is then we can head towards stabilising it...
gThorondorsen commentedon Dec 1, 2021
@drahnr in #82775 (comment)
Your example can be rewritten to a match guard that always returns true except when it panics, like this.
Definitely non-obvious when you don't know about it, but hardly worse to write if you are adding to an existing test suite with the pattern everywhere.
drahnr commentedon Dec 1, 2021
Re-reading the comments, I fully support the current impl and withdraw my previous concerns.
109 remaining items
rust-rfcbot commentedon Jan 26, 2026
Error encounted:
Provided team `` is invalid
Amanieu commentedon Jan 26, 2026
@rfcbot merge libs-api
Amanieu commentedon Jan 26, 2026
@rfcbot merge libs-api
Amanieu commentedon Jan 26, 2026
Started the FCP in #137487.
Rollup merge of rust-lang#137487 - Voultapher:stabilize-assert-matche…
Unrolled build for #137487
jhpratt commentedon Apr 17, 2026
This was destabilized in #154999. Reopening. The reason for destabilization seems to be scoping, which is tracked in #154406.
jhpratt commentedon May 27, 2026
Looking at release notes, it appears as though the scoping was backported to beta and will land on stable tomorrow (in 1.96).
Rollup merge of #137487 - Voultapher:stabilize-assert-matches, r=Amanieu
rust-analyzer/20260824 package update (#268036)