drop-checking is more permissive when let
statements have an else
block
#142056
Labels
A-MIR
Area: Mid-level IR (MIR) - https://blog.rust-lang.org/2016/04/19/MIR.html
C-bug
Category: This is a bug.
I-lang-nominated
Nominated for discussion during a lang team meeting.
P-lang-drag-1
Lang team prioritization drag level 1. https://rust-lang.zulipchat.com/#narrow/channel/410516-t-lang
T-compiler
Relevant to the compiler team, which will review and decide on the PR/issue.
T-lang
Relevant to the language team
Uh oh!
There was an error while loading. Please reload this page.
When pattern bindings are lowered to MIR, they're dropped in reverse order of declaration1. Normally, for each binding, this means running any necessary drop glue, then dropping its storage. However, with
let
-else
, the drop glue is run for all bindings first, then all their storages are dropped. As a result of not interleaving the drops and theStorageDead
s, bindings without meaningful drops live slightly longer than bindings with meaningful drops declared at the same time, regardless of declaration order. Example (playground link):Implementation-wise, this arises because storage for a
let
-else
's bindings is initialized all at once before match lowering (at which point theStorageDead
s are scheduled), but their drops are scheduled afterwards by match lowering. Also of note: the order in which match lowering schedules drops isn't the order in which patterns are normally visited1, so if special treatment is still needed forlet
-else
, care needs to be taken to make sure drop order doesn't change.Zulip stream with details on implementation history: https://rust-lang.zulipchat.com/#narrow/channel/213817-t-lang/topic/dropck.20inconsistency.20between.20.60let.60.20and.20.60let.60-.60else.60/with/522465186
Related: #142057
cc @rust-lang/lang since fixing this in any direction would change what programs are valid. I imagine that needs a T-lang decision?
cc @dingxiangfei2009, though I'd be happy to try implementing a fix myself once a decision is made on what the proper behavior should be.
@rustbot label: +T-compiler +T-lang +A-MIR
Footnotes
Match lowering treats bindings in or-patterns as occurring after bindings outside of or-patterns and differs between
let
andmatch
(example). Additionally, it treats bindings in avar @ subpattern
'ssubpattern
as occurring before thevar
(Unnecessary 'cannot bind by-move with sub-bindings' withbindings_after_at
#69971). ↩ ↩2The text was updated successfully, but these errors were encountered: