Skip to content

fix: Nail destructuring assignment once and for all#18254

Merged
Veykril merged 4 commits into
rust-lang:masterfrom
ChayimFriedman2:fix-mut
Oct 22, 2024
Merged

fix: Nail destructuring assignment once and for all#18254
Veykril merged 4 commits into
rust-lang:masterfrom
ChayimFriedman2:fix-mut

Conversation

@ChayimFriedman2

Copy link
Copy Markdown
Contributor

By lowering it into patterns instead of expressions.

This is a large PR (phew!) but it also removes a lot of code, almost as much as it inserts. All present and probably even future code dedicated to handling destructuring assignments is thrown out of the window. Besides fixing a bunch of bugs, this also means that any future expansion is going to work much less to work with destructuring assignments, and is much more likely to not have bugs/rough edges/forgotten cases.

rustc goes even more than this and desugars destructuring assignment completely; coming to the HIR it vanishes. But we cannot do that, because this will severely affect our ability to map destructuring assignments up and down the lowering chain (for instance, consider what happens when a macro expands to the "pattern". With rustc's approach, the macro expansion will be split, and we have no way to represent that).

Fixes #18209.

@rustbot rustbot added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Oct 6, 2024
@bors

bors commented Oct 14, 2024

Copy link
Copy Markdown
Contributor

☔ The latest upstream changes (presumably #18252) made this pull request unmergeable. Please resolve the merge conflicts.

@bors

bors commented Oct 15, 2024

Copy link
Copy Markdown
Contributor

☔ The latest upstream changes (presumably #18278) made this pull request unmergeable. Please resolve the merge conflicts.

@bors

bors commented Oct 20, 2024

Copy link
Copy Markdown
Contributor

☔ The latest upstream changes (presumably #18350) made this pull request unmergeable. Please resolve the merge conflicts.

Because our lint infra *can* handle allows from within macro expansions!

(Also, what did this reason have to do with something that is a hard error and not a lint? I'm puzzled).

I wonder how many such diagnostics we have...

Maybe that also mean we can change `unused_mut` to no-longer-experimental? But this is a change I'm afraid to do without checking.
Instead of lowering them to `<expr> = <expr>`, then hacking on-demand to resolve them, we lower them to `<pat> = <expr>`, and use the pattern infrastructure to handle them. It turns out, destructuring assignments are surprisingly similar to pattern bindings, and so only minor modifications are needed.

This fixes few bugs that arose because of the non-uniform handling (for example, MIR lowering not handling slice and record patterns, and closure capture calculation not handling destructuring assignments at all), and furthermore, guarantees we won't have such bugs in the future, since the programmer will always have to explicitly handle `Expr::Assignment`.

Tests don't pass yet; that's because the generated patterns do not exist in the source map. The next commit will fix that.
And few more fixups.

I was worried this will lead to more memory usage since `ExprOrPatId` is double the size of `ExprId`, but this does not regress `analysis-stats .`. If this turns out to be a problem, we can easily use the high bit to encode this information.

@Veykril Veykril left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is a great change!

Comment thread crates/hir-def/src/body/lower.rs
(res, is_unsafe)
}

pub struct UnsafeExpr {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Reading this made me realize we have yet to add checking patterns for unsafety here

union U {
    a: u8,
    b: u32,
}
fn f(U { a }: U) {}

for example doesn't trigger a warning (given the changes here I imagine that should be doable in a nicer way than before even). That struct should also be renamed then to UnsafeOp or so

Either way not to be done in this PR given its size.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Ah I just realiezd there is a FIXME on line 47 regarding patterns

};

/// Used to generalize patterns and assignee expressions.
pub(super) trait PatLike: Into<ExprOrPatId> + Copy {

@Veykril Veykril Oct 22, 2024

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Seeing this go is great 🙂

@ChayimFriedman2

Copy link
Copy Markdown
Contributor Author

@Veykril Added a test as requested.

@Veykril Veykril enabled auto-merge October 22, 2024 17:29
@Veykril Veykril added this pull request to the merge queue Oct 22, 2024
Merged via the queue into rust-lang:master with commit c286786 Oct 22, 2024
@ChayimFriedman2 ChayimFriedman2 deleted the fix-mut branch October 22, 2024 18:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

S-waiting-on-review Status: Awaiting review from the assignee but also interested parties.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

false positive "variable does not need to be mutable" report when mutating a variable with a pattern in a closure

4 participants