Skip to content

Conversation

@dianne
Copy link
Contributor

@dianne dianne commented Aug 12, 2025

This is based on #1823 by @Kivooeo and @ehuss, rebased to resolve conflicts. Per rust-lang/rust#141295 (comment), I'm opening this as a separate PR to contribute an updated specification of if let guards' drop-scoping rules. The new spec is based on the compiler's implementation1, accounting for the changes in rust-lang/rust#143376 and additional corner-cases in examples. I've also done some minor edits to the sections on lexical scope and match expressions, but for the most part they're the same as in #1823.

Tracking issue: rust-lang/rust#51114
Stabilization: rust-lang/rust#141295

Footnotes

  1. As with the rules for other syntactic constructs (e.g. let statements and if expressions), this is slightly simplified. Due to implementation details, the compiler's notion of drop scopes is more fine-grained than is necessary for the language spec.

@rustbot rustbot added the S-waiting-on-review Status: The marked PR is awaiting review from a maintainer label Aug 12, 2025
@dianne dianne force-pushed the if-let-guard branch 3 times, most recently from 7eb684c to 9add291 Compare August 12, 2025 09:21
or a `match` guard.
* The body expression for a match arm.
* The non-pattern matching condition expression of an `if` or `while` expression or a non-pattern-matching `match` guard condition operand.
* The pattern-matching guard, if present, and body expression for a `match` arm.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

To address #1823 (comment) (cc @theemathas), the temporary lifetime of an if let guard scrutinee is always extended, like for if let expressions. There aren't lifetime extension rules like there are for let statements. This rule should hopefully cover that (similar to how the analogous rule for "The pattern-matching condition(s) and consequent body of if" does below). There's an example further down too showing that the scrutinee lives until the end of the arm. Do you think this is sufficient, or would this benefit from additional clarification?

This comment was marked as resolved.

Copy link
Contributor

@theemathas theemathas Aug 12, 2025

Choose a reason for hiding this comment

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

Oh, are you saying that both the guard and the body expression together count as a single temporary scope (and not two)? I find that unintuitive, but I suppose that works.

Copy link
Contributor Author

@dianne dianne Aug 12, 2025

Choose a reason for hiding this comment

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

There's a single temporary scope for the arm, which encompasses the guard and body expression, so that if let scrutinees' temporaries live through the body, yes; if let scrutinees aren't temporary destruction scopes by default. Maybe it would be clearer to phrase the temporary scope as being as for the whole arm, with a clarifying note that it includes the guard. Something like "* The arm of a match expression. This includes the arm's guard, if present."

Personally, I'd like stricter scoping rules for if let, but this is consistent with if let/while let expressions. Making their scrutinees be temporary drop scopes by default with lifetime extension rules (like let statements have) would be a larger change requiring an edition break.

@ehuss ehuss added the S-waiting-on-stabilization Waiting for a stabilization PR to be merged in the main Rust repository label Sep 2, 2025
@theemathas
Copy link
Contributor

Is this waiting on anything in particular?

@rustbot

This comment has been minimized.

@rustbot

This comment has been minimized.

@dianne
Copy link
Contributor Author

dianne commented Jan 28, 2026

It looks like my removal of the "Match Guards and Pattern Binding" section was undone? I've re-removed it. I wanted to leave commits before my own mostly untouched, but I can clean up the commit history to remove anything that I'm not preserving in this PR if that'd help keep what's actually meant to be here clearer.

Kivooeo and others added 5 commits January 28, 2026 02:11
This applies some editorial rework, mainly to match the style of `if`
conditions.
- Removes specification of `if let` guards' bindings "only" being valid
if the guard succeeds. The arm body is only executed if the guard
succeeds, so the bindings are always usable within the arm body when
it's executed.

- Makes terminology slightly more consistent (replaces some remaining
uses of "`if let` guard" with "`let` pattern")

- Other small wording and punctuation tweaks.
@rustbot
Copy link
Collaborator

rustbot commented Jan 28, 2026

This PR was rebased onto a different master commit. Here's a range-diff highlighting what actually changed.

Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers.

@ehuss
Copy link
Contributor

ehuss commented Jan 28, 2026

Sorry about that @dianne! I had double-checked the reflog when I was fixing that, and I'm not sure how it got missed.

Copy link
Contributor

@traviscross traviscross left a comment

Choose a reason for hiding this comment

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

Looks good to me.

@traviscross traviscross removed the S-waiting-on-review Status: The marked PR is awaiting review from a maintainer label Jan 28, 2026
In our PEG-style grammar, the order matters, and in this case, we need
`MatchGuardChain` to come after `Expression`.

Thanks-to: Eric Huss <eric@huss.org>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

S-waiting-on-stabilization Waiting for a stabilization PR to be merged in the main Rust repository

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants