Skip to content

Mark more locals as moved to avoid building drops for them. - #158281

Open
cjgillot wants to merge 5 commits into
rust-lang:mainfrom
cjgillot:drop-moved-locals
Open

Mark more locals as moved to avoid building drops for them.#158281
cjgillot wants to merge 5 commits into
rust-lang:mainfrom
cjgillot:drop-moved-locals

Conversation

@cjgillot

@cjgillotcjgillot commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

View all comments

MIR building skips generating drops for moved-from locals in the topmost scope. This was only used for call terminators, but can be generalized to many other moves. This PR generalizes this to aggregate construction and many other assignments.

This avoids generating drops that would then be removed by drop elaboration.

This PR changes borrowck behaviour: some programs that were rejected are now accepted, see the last commit. That particular case was wrongly rejected.

Fixes#156713

Based on #158279 to remove a lint false-positive

@rustbot

Copy link
Copy Markdown
Collaborator

Some changes occurred to MIR optimizations

cc @rust-lang/wg-mir-opt

@rustbotrustbot 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 Jun 23, 2026
@rustbot

Copy link
Copy Markdown
Collaborator

r? @JohnTitor

rustbot has assigned @JohnTitor.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

Why was this reviewer chosen?

The reviewer was selected based on:

  • Owners of files modified in this PR: compiler
  • compiler expanded to 73 candidates
  • Random selection from 21 candidates

@theemathas

Copy link
Copy Markdown
Contributor

Does this have user-visible behavior changes? e.g., see #156713

@cjgillot

Copy link
Copy Markdown
ContributorAuthor

Yes. With this change, both cases in #156713 pass. We also have a few user-visible consequences with the drop order lint.

@theemathastheemathas added T-lang Relevant to the language team needs-fcp This change is insta-stable, or significant enough to need a team FCP to proceed. and removed T-libs Relevant to the library team, which will review and decide on the PR/issue. labels Jun 23, 2026
@JohnTitor

Copy link
Copy Markdown
Member

@rustbot reroll

@rustbotrustbot assigned jackh726 and unassigned JohnTitorJun 27, 2026
@rustbot

This comment has been minimized.

@cjgillotcjgillot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jul 2, 2026
@cjgillotcjgillot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Jul 5, 2026
@rust-log-analyzer

This comment has been minimized.

@rust-bors

This comment has been minimized.

@rustbot

This comment has been minimized.

@cjgillot

Copy link
Copy Markdown
ContributorAuthor

@bors try @rust-timer queue

@rust-timer

This comment has been minimized.

@rustbotrustbot added the S-waiting-on-perf Status: Waiting on a perf run to be completed. label Jul 9, 2026
@rust-bors

This comment has been minimized.

@rustbot

This comment has been minimized.

@jackh726

Copy link
Copy Markdown
Member

I'm not personally very familiar with when we are allowed to avoid building drops (specifically, which are these truly count as moves from an opsem perspective).

cc both @rust-lang/opsem and @rust-lang/types

I would be far more comfortable if there was a small and specific test demonstrating the difference from marking each individual site that we record as moved.

@RalfJung

RalfJung commented Aug 8, 2026

Copy link
Copy Markdown
Member

I'm afraid MIR building is mostly outside my wheelhouse.
But Cc @Amanieu since you said "move".

@RalfJung

Copy link
Copy Markdown
Member

Is there somewhere a high-level description of the algorithm implemented here and how it defines "move"?
It seems like this first builds MIR and then looks at the just-built MIR to determine what the "moves" are?

@cjgillot

Copy link
Copy Markdown
ContributorAuthor

Is there somewhere a high-level description of the algorithm implemented here and how it defines "move"?

At high level, the doc-comment on record_operand_moved is quite good.
There is also the definition by @nikomatsakis here: rust-lang/compiler-team#558

It seems like this first builds MIR and then looks at the just-built MIR to determine what the "moves" are?

This is on the "built" MIR phase. In short, a "move" is an occurrence of Operand::Move, which deinitializes the moved-from place. In that MIR dialect, drop actually means drop-if-initialized, so drops of moved-from locals is a no-op, and can be elided. (See the section on "drops" here: https://doc.rust-lang.org/beta/nightly-rustc/rustc_middle/mir/enum.MirPhase.html)

@rustbot

This comment has been minimized.

@cjgillot

Copy link
Copy Markdown
ContributorAuthor

I would be far more comfortable if there was a small and specific test demonstrating the difference from marking each individual site that we record as moved.

Latest push adds a mir-opt test file with the different cases, and shows what changes. Not all calls to record_operand_moved have an effect, as it is very conservative, in particular when locals are declared in different scopes.

@RalfJung

Copy link
Copy Markdown
Member

a "move" is an occurrence of Operand::Move, which deinitializes the moved-from place

"de-initialize" here refers to the initialization state tracked for drop flags, right?
We don't currently have a MIR semantics where this actually changes the contents of memory to be uninitialized.

@rust-log-analyzer

This comment has been minimized.

@cjgillot

Copy link
Copy Markdown
ContributorAuthor

"de-initialize" here refers to the initialization state tracked for drop flags, right?

Yes

@rust-log-analyzer

This comment has been minimized.

@RalfJung

Copy link
Copy Markdown
Member

"de-initialize" here refers to the initialization state tracked for drop flags, right?

Yes

This should probably be mentioned in the Operand::Move doc comment.

@rustbot

Copy link
Copy Markdown
Collaborator

This PR changes MIR

cc @oli-obk, @RalfJung, @JakobDegen, @vakaras

Comment threadcompiler/rustc_middle/src/mir/syntax.rs Outdated
Comment threadcompiler/rustc_middle/src/mir/syntax.rs Outdated
Comment threadcompiler/rustc_middle/src/mir/syntax.rs
Comment threadcompiler/rustc_middle/src/mir/syntax.rs Outdated
@rust-bors

This comment has been minimized.

And some more cases along the way.
We have a specific optimization to avoid generating useless drops, use it.
In particular, aggregate construction are very similar to function calls
for which this is designed.
@rustbot

Copy link
Copy Markdown
Collaborator

This PR was rebased onto a different main 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.

@rust-bors

rust-borsBot commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

☔ The latest upstream changes made this pull request unmergeable. Please resolve the merge conflicts by rebasing.

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

Labels

needs-fcpThis change is insta-stable, or significant enough to need a team FCP to proceed.perf-regressionPerformance regression.S-waiting-on-reviewStatus: Awaiting review from the assignee but also interested parties.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.T-langRelevant to the language team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Inconsistent and nonsensical borrow-checking error from unwind path of destructor of moved-out variable

9 participants

@cjgillot@rustbot@theemathas@JohnTitor@rust-log-analyzer@rust-timer@jackh726@RalfJung@dianne