-
Notifications
You must be signed in to change notification settings - Fork 13.4k
match arm bindings have weird lifetimes #46525
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Comments
I think that it will be hard to fix this in a way AST borrowck and region inference will understand, but afterwards this is fair game. |
I think that this fits into what @pnkfelix is doing in overhauling how we handle match arms? |
I guess this is just a matter of generating better code...? |
Re-triaging for #56754. NLL-complete. P-medium. Assigning to self. |
In terms of observable semantics with implementations of So like @nikomatsakis, I think this is just a matter of generating better code. But I would like to actually be sure of that before we e.g. turn off NLL migrate more (and subsequently stabilize Increasing priority of this issue to P-high. |
Nominating for some discussion on today's lang meeting. Also, here's an example of observable drop order: #![feature(bind_by_move_pattern_guards)]
#[derive(Debug)]
struct A;
impl A {
fn foo(&self) -> bool { dbg!(2); false }
}
impl Drop for A {
fn drop(&mut self) { dbg!(3); }
}
fn main() {
dbg!(0);
match dbg!(A) {
a if a.foo() => { dbg!(4); }
_ => { dbg!(5); }
}
dbg!(6);
} prints:
showing that 5 happens before 3. |
Fixing this issue, would not change the order there, or any observable runtime behaviour at all. |
triage: @matthewjasper do you think this actually warrants P-high? I know we want to do it eventually, but if things are working okay thus far, it seems like we can continue to coast? |
It's not really p-high, but I hope to create a PR for this once migrate mode is enabled on all editions. |
… r=pnkfelix Add match arm scopes and other scope fixes * Add drop and lint scopes for match arms. * Lint attributes are now respected on match arms. * Make sure we emit a StorageDead if we diverge when initializing a temporary. * Adjust MIR pretty printing of scopes for locals. * Don't generate duplicate lint scopes for `let statements`. * Add some previously missing fake borrows for matches. closes rust-lang#46525 cc @rust-lang/compiler
… r=pnkfelix Add match arm scopes and other scope fixes * Add drop and lint scopes for match arms. * Lint attributes are now respected on match arms. * Make sure we emit a StorageDead if we diverge when initializing a temporary. * Adjust MIR pretty printing of scopes for locals. * Don't generate duplicate lint scopes for `let statements`. * Add some previously missing fake borrows for matches. closes rust-lang#46525 cc @rust-lang/compiler
Add match arm scopes and other scope fixes * Add drop and lint scopes for match arms. * Lint attributes are now respected on match arms. * Make sure we emit a StorageDead if we diverge when initializing a temporary. * Adjust MIR pretty printing of scopes for locals. * Don't generate duplicate lint scopes for `let statements`. * Add some previously missing fake borrows for matches. closes #46525 cc @rust-lang/compiler
Add match arm scopes and other scope fixes * Add drop and lint scopes for match arms. * Lint attributes are now respected on match arms. * Make sure we emit a StorageDead if we diverge when initializing a temporary. * Adjust MIR pretty printing of scopes for locals. * Don't generate duplicate lint scopes for `let statements`. * Add some previously missing fake borrows for matches. closes #46525 cc @rust-lang/compiler
I should have opened this issue a long while ago, but now I have a place in the code I want to link it to.
Match bindings have weird lifetime, especially when guards are involved: instead of the destructors executing when the bindings go out of scope, all of the destructors of all match bindings are run just after the match ends.
e.g. I think this causes unnecessary drop elaboration and etc. load on big functions with many-armed matches.
One very weird case is this:
Here, the guard is executed twice, and
a
is only storage-killed after the match ends, so we have storage-live -> storage-live -> storage-dead, which might annoy some things.FIXME: remember more weird cases and clean them up.
The text was updated successfully, but these errors were encountered: