-
-
Notifications
You must be signed in to change notification settings - Fork 14.7k
assert_eq/assert_matches vs debug_assert_eq/debug_assert_matches have different temporary scoping behavior #154406
Copy link
Copy link
Open
Labels
A-destructorsArea: Destructors (`Drop`, …)Area: Destructors (`Drop`, …)A-macrosArea: All kinds of macros (custom derive, macro_rules!, proc macros, ..)Area: All kinds of macros (custom derive, macro_rules!, proc macros, ..)A-temporary-lifetime-extensionArea: temporary lifetime extensionArea: temporary lifetime extensionC-bugCategory: This is a bug.Category: This is a bug.I-libs-api-nominatedNominated for discussion during a libs-api team meeting.Nominated for discussion during a libs-api team meeting.T-libs-apiRelevant to the library API team, which will review and decide on the PR/issue.Relevant to the library API team, which will review and decide on the PR/issue.
Metadata
Metadata
Assignees
Labels
A-destructorsArea: Destructors (`Drop`, …)Area: Destructors (`Drop`, …)A-macrosArea: All kinds of macros (custom derive, macro_rules!, proc macros, ..)Area: All kinds of macros (custom derive, macro_rules!, proc macros, ..)A-temporary-lifetime-extensionArea: temporary lifetime extensionArea: temporary lifetime extensionC-bugCategory: This is a bug.Category: This is a bug.I-libs-api-nominatedNominated for discussion during a libs-api team meeting.Nominated for discussion during a libs-api team meeting.T-libs-apiRelevant to the library API team, which will review and decide on the PR/issue.Relevant to the library API team, which will review and decide on the PR/issue.
Type
Fields
Give feedbackNo fields configured for issues without a type.
I tried this code:
I expected the temporary scopes to be the same regardless of whether I use the
debug_variant of the macros or not. Instead, the code outputs the following:That is,
debug_assert_eq,debug_assert_matches,assert, anddebug_asserteach introduces a temporary scope, causing temporaries to be dropped as soon as execution of the macro call finishes. However,assert_eqandassert_matcheseach does not introduce a temporary scope, causing temporaries to only be dropped at the next surrounding temporary scope, potentially after other code has executed outside the macro call. This seems inconsistent, although I'm not sure if this could affect real code in practice.(Note:
assert_matchesanddebug_assert_matchesare stable in 1.95.0 beta.)The reason
assert_eqdoes not introduce a temporary scope is because,assert_eq!(expr1, expr2)expands tomatch (&expr1, &expr2) { .... }. Andmatchdoes not introduce a temporary scope for the scrutinee. Similarly,assert_matches!(expr, pat)expands tomatch expr { .... }.In contrast,
assert!(expr)expands toif !expr { .... }. Andifintroduces a temporary scope for the condition expression.The reference documents this difference in behavior between
matchandif.The reason
debug_assert_eqintroduces a temporary scope is because,debug_assert_eq!(expr1, expr2)expands toif cfg!(debug_assertions) { assert_eq!(expr1, expr2); }. And the semicolon introduces a temporary scope.cc @dianne
Meta
Reproducible on the playground with version
1.96.0-nightly (2026-03-24 362211dc29abc4e8f8cf)