Skip to content

emit StorageLive and schedule StorageDead for let-else's bindings after matching #143028

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

dianne
Copy link
Contributor

@dianne dianne commented Jun 25, 2025

This PR removes special handling of let-else, so that StorageLives are emitted and StorageDeads are scheduled only after pattern-matching has succeeded. This means StorageDeads will no longer appear for all of its bindings on the else branch (because they're not live yet) and its drops&StorageDeads will happen together like they do elsewhere, rather than having all drops first, then all StorageDeads.

This fixes #142056, and is therefore a breaking change. I believe it'll need a crater run and a T-lang nomination/fcp thereafter. Specifically, this makes drop-checking slightly more restrictive for let-else to match the behavior of other variable binding forms. An alternative approach could be to change the relative order of drops and StorageDeads for other binding forms to make drop-checking more permissive, but making that consistent would be a significantly more involved change.

r? mir
cc @dingxiangfei2009

@rustbot label +T-lang +needs-crater

@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. labels Jun 25, 2025
@rustbot
Copy link
Collaborator

rustbot commented Jun 25, 2025

Some changes occurred in match lowering

cc @Nadrieril

@rustbot
Copy link
Collaborator

rustbot commented Jun 25, 2025

Error: Label needs-crater can only be set by Rust team members

Please file an issue on GitHub at triagebot if there's a problem with this bot, or reach out on #t-infra on Zulip.

@workingjubilee workingjubilee added the needs-crater This change needs a crater run to check for possible breakage in the ecosystem. label Jun 25, 2025
@workingjubilee
Copy link
Member

Building for crater:
@bors2 try

@rust-bors
Copy link

rust-bors bot commented Jun 25, 2025

⌛ Trying commit c6a97d3 with merge 8a03786

To cancel the try build, run the command @bors2 try cancel.

rust-bors bot added a commit that referenced this pull request Jun 25, 2025
emit `StorageLive` and schedule `StorageDead` for `let`-`else`'s bindings after matching

This PR removes special handling of `let`-`else`, so that `StorageLive`s are emitted and `StorageDead`s are scheduled only after pattern-matching has succeeded. This means `StorageDead`s will no longer appear for all of its bindings on the `else` branch (because they're not live yet) and its drops&`StorageDead`s will happen together like they do elsewhere, rather than having all drops first, then all `StorageDead`s.

This fixes #142056, and is therefore a breaking change. I believe it'll need a crater run and a T-lang nomination/fcp thereafter. Specifically, this makes drop-checking slightly more restrictive for `let`-`else` to match the behavior of other variable binding forms. An alternative approach could be to change the relative order of drops and `StorageDead`s for other binding forms to make drop-checking more permissive, but making that consistent would be a significantly more involved change.

r? mir
cc `@dingxiangfei2009`

`@rustbot` label +T-lang +needs-crater
@rust-bors
Copy link

rust-bors bot commented Jun 26, 2025

☀️ Try build successful (CI)
Build commit: 8a03786 (8a0378607d6b34c242e3bfa75554871be641864b, parent: d14d202262d13df896b0c624b0cec6e4bfde631a)

@workingjubilee
Copy link
Member

@craterbot check

@craterbot
Copy link
Collaborator

👌 Experiment pr-143028 created and queued.
🤖 Automatically detected try build 8a03786
🔍 You can check out the queue and this experiment's details.

ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more

@craterbot craterbot added S-waiting-on-crater Status: Waiting on a crater run to be completed. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jun 26, 2025
@craterbot
Copy link
Collaborator

🚧 Experiment pr-143028 is now running

ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more

@craterbot
Copy link
Collaborator

🎉 Experiment pr-143028 is completed!
📊 6 regressed and 3 fixed (653904 total)
📰 Open the full report.

⚠️ If you notice any spurious failure please add them to the denylist!
ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more

@craterbot craterbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-crater Status: Waiting on a crater run to be completed. labels Jun 27, 2025
@Kivooeo
Copy link
Contributor

Kivooeo commented Jun 29, 2025

Since crater finished it's experiment, how's overall results? I've opened a link with a full report but it seems more complicated

@dianne
Copy link
Contributor Author

dianne commented Jun 29, 2025

The regressed and fixed crates look wholly unrelated to this PR. I'm not too surprised, since this is a very niche breakage. It doesn't look like there will be any ecosystem impact if this is merged.

There's a few failures to download/access dependencies, what looks like an failure in a perl build script1, and a couple docker errors. I'm not too knowledgeable about crater's infrastructure so I couldn't say why any of it is happening or whether those crates should be put on the denylist, but none of that sounds like the fault of let-else's MIR changing.

Footnotes

  1. This was as part of building OpenSSL as a dependency. Nothing else depending on OpenSSL had this issue, and it's not written in Rust to begin with.

@Kivooeo
Copy link
Contributor

Kivooeo commented Jun 29, 2025

@est31, I believe you should be interested in this changes, also if you are familiar with the mir building part could you please review this?

@dianne
Copy link
Contributor Author

dianne commented Jun 29, 2025

To be clear, the potential breakage from this PR should only be to let-else's static semantics (in particular, the drop check) and to other analyses that take StorageLive/StorageDead statements into account. It shouldn't affect runtime-observable drop order.

I intend to open some PRs for drop order changes as well, including for let guards if we don't intend to stabilize their current behavior, but I haven't gotten around to those just yet.

@est31
Copy link
Member

est31 commented Jun 30, 2025

This is done in the name of consistency, right? Naively, I'd tend towards making things more permissible rather than more restrictive, and change the existing constructs instead. But probably this way, the rules are easier to describe, and it is less surprising that this code stops compiling the moment becomes non-Copy.

I suppose a crater run in the other run wouldn't bring up any breakages either because it'd strictly make more things compile, rather than less? Otherwise I'd have suggested doing it, but I suppose it's not going to bring up any results either.

if you are familiar with the mir building part could you please review this?

Actually not that familiar with it, but I can still take a look. I see @dingxiangfei2009 is already in the zulip thread, he is definitely quite familiar with it.

none of that sounds like the fault of let-else's MIR changing.

Yeah it's a bit noisy, or at least was a while ago when I was looking at results. It's entirely possible that it shows only noise. That's a good sign, meaning that it really has low impact.

@dianne
Copy link
Contributor Author

dianne commented Jun 30, 2025

This is done in the name of consistency, right? Naively, I'd tend towards making things more permissible rather than more restrictive, and change the existing constructs instead.

I'd prefer to make it more permissive too, but the inconsistencies are indeed tougher to iron out in that direction. Though maybe it's not an issue? The big inconsistency I can think of is that without sorting the StorageDeads for multiple patterns to be after all their drops, introducing bindings with one pattern would be more permissive than using multiple patterns. e.g.:

  • let (mut needs_drop, dropless); would be more permissive than let mut needs_drop; let dropless;
  • |(mut needs_drop, dropless)| ... would be more permissive than |mut needs_drop, dropless| ...

If that's not an issue, I could see about opening an alternative PR implementing that relaxed behavior instead. Having all the StorageDeads last would also be nice for an or-pattern drop order experiment I'm considering.

But probably this way, the rules are easier to describe, and it is less surprising that this code stops compiling the moment becomes non-Copy.

I don't think it'd be too much harder to describe if the drops and StorageDeads were fully de-tangled. Unless its lifetime is otherwise restricted, anything without a significant drop would live until after everything needing to be dropped is dropped (vs. the current model where everything is treated as dropped in-order even if it doesn't need to be). I guess if they're still partially tangled, locals with insignificant drops would outlive locals with significant drops introduced by the same pattern. Partial tangling would limit equational reasoning about pattern bindings, as in the examples above, but I don't know if that's a priority.

edit: actually, doing all drops before StorageDeads might be easier than I thought. I'll consider that option too.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
needs-crater This change needs a crater run to check for possible breakage in the ecosystem. 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.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

drop-checking is more permissive when let statements have an else block
7 participants