-
-
Notifications
You must be signed in to change notification settings - Fork 15k
drop-checking is more permissive when let statements have an else block #142056
Copy link
Copy link
Closed
Closed
Copy link
Labels
A-MIRArea: Mid-level IR (MIR) - https://blog.rust-lang.org/2016/04/19/MIR.htmlArea: Mid-level IR (MIR) - https://blog.rust-lang.org/2016/04/19/MIR.htmlC-bugCategory: This is a bug.Category: This is a bug.I-lang-radarItems that are on lang's radar and will need eventual work or consideration.Items that are on lang's radar and will need eventual work or consideration.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.T-langRelevant to the language teamRelevant to the language team
Metadata
Metadata
Assignees
Labels
A-MIRArea: Mid-level IR (MIR) - https://blog.rust-lang.org/2016/04/19/MIR.htmlArea: Mid-level IR (MIR) - https://blog.rust-lang.org/2016/04/19/MIR.htmlC-bugCategory: This is a bug.Category: This is a bug.I-lang-radarItems that are on lang's radar and will need eventual work or consideration.Items that are on lang's radar and will need eventual work or consideration.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.T-langRelevant to the language teamRelevant to the language team
Type
Fields
Give feedbackNo fields configured for issues without a type.
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 theStorageDeads, 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 theStorageDeads 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
letandmatch(example). Additionally, it treats bindings in avar @ subpattern'ssubpatternas occurring before thevar(Unnecessary 'cannot bind by-move with sub-bindings' withbindings_after_at#69971). ↩ ↩2