4 ms·
This is going to be fixed in Rust 2024: https://github.com/rust-lang/rust/issues/124085 https://github.com/rust-lang/rust/issues/124085
by sunshowers 2y ago
This is going to be fixed in Rust 2024:
https://github.com/rust-lang/rust/issues/124085 https://github.com/rust-lang/rust/issues/124085
- dgfitz 2y agoDid they just miss this in the spec?
- sunshowers 2y agoFrom my understanding: The original implementation is consistent with the behavior of `match`. However it was realized that it is both less intuitive than early dropping (as this post suggests) and also gets in the way of understandable semantics for if let chains, so the decision was made to change it in the next edition. match still retains the old behavior.
- acjohnson55 2y agoWhy does the behavior make sense in match?
- sunshowers 2y agohttps://github.com/rust-lang/rust/issues/131154 https://github.com/rust-lang/rust/issues/131154 has some discussion about all the possibilities. It's pretty subtle, but I think everyone agrees that the current behavior of if let is unintuitive. Beyond that there are a bunch of possibilities none of which is clearly superior.
- GolDDranks 2y agohttps://github.com/rust-lang/rust/issues/131154#issuecomment-2444591506 https://github.com/rust-lang/rust/issues/131154#issuecomment... Especially this matrix was helpful! The behaviour that's going to be adopted in Rust 2024 is the Rust2024.1 one. They were having doubts about the rules becoming too complex/non-uniform, but at least dropping early means compiler errors rather than deadlocks.
- GolDDranks 2y agoMatch has multiple branches, and some or all of them can bind variables, (borrowed from the value matched against), defined in that branch. For that to be possible, it means that the temporary lifetime of the matched value must encompass all the branches. Compared to that, if let - else has only two branches: one where matching (and possible variable binding) happens, and one where it doesn't. You couldn't have anything borrowed from the matched value in the else branch, so the lifetime extending to encompass the else branch is not strictly necessary.
- NobodyNada 2y agoAlso, from a pure syntax perspective, an if let block reads like it creates a binding that exists within the scope of the braces after the if, and a match block reads like it creates a binding that exists within the "scope" of the braces surrounding the entire match block. These all read the same to me from a scoping perspective: if let Some(x) = expr { // expr is live here } while let Some(x) = expr { // expr is live here } match expr { // expr is live here Some(x) => {}, _ => { /* expr is still live, doesn't matter that x is inaccessible */ } fn foo(x: i32) { // same idea, the variable x belongs to the scope it's declared alongside } For the scope of an if-let expression to extend into the else block afterwards violates the principle of least surprise for me -- and clearly the author of the OP too! if let Some(x) = expr { // expr is live here } else { // ??? why is expr live here? the if is clearly "out of scope!" }