match lowering: consistently lower bindings deepest-first by Nadrieril · Pull Request #120214 · rust-lang/rust (original) (raw)
Currently when lowering match expressions to MIR, we do a funny little dance with the order of bindings. I attempt to explain it in the third commit: we handle refutable (i.e. needing a test) patterns differently than irrefutable ones. This leads to inconsistencies, as reported in #120210. The reason we need a dance at all is for situations like:
fn foo1(x: NonCopyStruct) { let y @ NonCopyStruct { copy_field: z } = x; // the above should turn into let z = x.copy_field; let y = x; }
Here the y @
binding will move out of x
, so we need to copy the field first.
I believe that the inconsistency came about when we fixed #69971, and didn't notice that the fix didn't extend to refutable patterns. My guess then is that ordering bindings by "deepest-first, otherwise source order" is a sound choice. This PR implements that (at least I hope, match lowering is hard to follow 🥲).
Fixes #120210
r? @oli-obk since you merged the original fix to #69971
cc @matthewjasper