Repository navigation
Tracking Issue for RFC 3137: let-else statements #87335
Copy link
Copy link
Closed
Labels
C-tracking-issueCategory: An issue tracking the progress of sth. like the implementation of an RFCCategory: An issue tracking the progress of sth. like the implementation of an RFCF-let_elseIssues related to let-else statements (RFC 3137)Issues related to let-else statements (RFC 3137)S-tracking-impl-incompleteStatus: The implementation is incomplete.Status: The implementation is incomplete.T-langRelevant to the language teamRelevant to the language team
Description
This is a tracking issue for RFC 3137: let-else statements.
The feature gate for the issue is #![feature(let_else)].
About tracking issues
Tracking issues are used to record the overall progress of implementation.
They are also used as hubs connecting to other relevant issues, e.g., bugs or open design questions.
A tracking issue is however not meant for large scale discussion, questions, or bug reports about a feature.
Instead, open a dedicated issue for the specific matter and add the relevant feature gate label.
Steps
- Implement the RFC (Introduce
let...else#87688) - Adjust documentation: reference PR at Document let else statements reference#1156
- Stabilization PR: Stabilize
let else#93628
Unresolved Questions
- Readability in practice: Will
let ... else { ... };be clear enough to humans in practical code, or will some introducer syntax be desirable? - Conflicts with if-let-chains: Does this conflict too much with the if-let-chains RFC or vice-versa? Neither this feature nor that feature should be stabilized without considering the other.
- Amount of special cases: Are there too many special-case interactions with other features?
- Grammar clarity: Does the grammar need to be clarified? This RFC has some slightly unusual grammar requirements.
Implementation history
- Introduce
let...else#87688 implemented let-else. - Implement let-else type annotations natively #89841 adds support for type annotations in let-else (
let x: Type = ... else { ... })
Reacted by Jacob Pratt, Sebastian Malton, inquisitivecrystal, Jeremiah Senkpiel, Qyriad, Gustav Sörnäs, Benoit de Chezelles, Xùdōng Yáng, Léo Lanteri Thauvin, Laine Taffin Altman and 107 more
Reacted by Iron-E, Hüseyin Yiğit, İrem, kk, Celthi, Vinícius Miguel, Anton Melnyk and Armin Schäfer
Reacted by Xùdōng Yáng, Laine Taffin Altman, Mahdi, Scott Olson, Jason Miller, Mateusz Czapliński, Jan Špaček, Anders Musikka, Rogério Almeida, Daniel Henry-Mantilla and 14 more
Reacted by İrem and Matthew Radcliffe
Reacted by Laine Taffin Altman, Mahdi, Scott Olson, Maxim Vorobjov, Jason Miller, Alex.F, Marcelina Kościelnicka, Alexander Irbis, max, David Laban and 33 more
Reacted by Felipe S. S. Schneider
Reacted by Originalimoc
Metadata
Metadata
Assignees
Labels
C-tracking-issueCategory: An issue tracking the progress of sth. like the implementation of an RFCCategory: An issue tracking the progress of sth. like the implementation of an RFCF-let_elseIssues related to let-else statements (RFC 3137)Issues related to let-else statements (RFC 3137)S-tracking-impl-incompleteStatus: The implementation is incomplete.Status: The implementation is incomplete.T-langRelevant to the language teamRelevant to the language team
Type
Projects
- StatusShow more project fieldsFeature Complete
Activity
inquisitivecrystal commentedon Jul 21, 2021
LeSeulArtichaut commentedon Jul 21, 2021
Is there already someone who wants to implement the RFC? Otherwise I could maybe take a stab at it
camsteffen commentedon Jul 21, 2021
I volunteered on Zulip to implement a while ago and I have a start on it. @Fishrock123 are you still okay with me taking it since you were also interested?
Fishrock123 commentedon Jul 21, 2021
I'm interested but I'm clueless and pretty busy. I'd say you should just take it.
matklad commentedon Aug 18, 2021
An interesting example which I didn't see come up in the RFC text/thread (quick search for
mut). In today's Rust,let-elsewon't work for a case of updating variables. An example here is computing a path in a graph after DFS returns a map of parents:Here,
letwon't re-bind curr, it'll shadow it instead.Just as an observation, Kotlin-style elvis operator would avoid this issue, as it doesn't require a pattern:
joshtriplett commentedon Aug 18, 2021
matklad commentedon Aug 18, 2021
matklad commentedon Aug 18, 2021
Hypothetically, we can allow the following (else without let):
This would be a natural combination of let-else and #71126. While #71126 is still unstable, it might be worth is to think about the interactions between the two. Will the above example just work, or are there any problems with it?
camsteffen commentedon Aug 18, 2021
I also mentioned this in the RFC. Probably no technical limitation but just readability concerns. I think we can safely wait until let-else and destructuring-assignment have matured before expecting them to procreate (forgive me).
Fishrock123 commentedon Aug 18, 2021
Ah, I seem to have missed that thing about
destructuring_assignment, yes that seems like a future possibility, with the above mentioned caveats.Auto merge of rust-lang#87688 - camsteffen:let-else, r=cjgillot
Fishrock123 commentedon Sep 1, 2021
@joshtriplett #87688 has been merged, can you tick off "implement the RFC"?
77 remaining items
Fishrock123 commentedon Jul 23, 2022
@wmstack Please see the “Future Possibilities: Fallback Assignment” section of the RFC.
The RFC leaves this open as a possible addition by using some additional syntax. See the “
else-block fall-back assignment” rationale section for why.kevincox commentedon Jul 23, 2022
Strong agree. Let's start with the simple case and we can consider options like that in a new RFC with some real-world experience under our belt.
est31 commentedon Jul 28, 2022
In theory there are some scenarios where we could drop earlier. E.g. in this one:
It prints:
The first example makes sense:
vis not moved out ofDroppybecause we only have it by reference. In the second example, however, no binding is created, we only do pattern matching on Droppy. Basically we could replace it with a use ofmatches!().Note that this is similar however to what we do with irrefutable patterns already. They drop immediately when it's a by-val pattern match but live on if it's a by-ref pattern match, even if no bindings are being created.
Prints:
Should I open a new issue for discussion?
est31 commentedon Aug 30, 2022
Answering myself: I think this comment by @joshtriplett resolves this: We should just do whatever
letis doing. As the current behaviour matcheslet, I think we can stabilize it this way (although tests for it would be good, reminder that I add them to #99291).Rollup merge of rust-lang#99291 - est31:let_else_tests, r=joshtriplett
Rollup merge of rust-lang#99291 - est31:let_else_tests, r=joshtriplett
Rollup merge of rust-lang#99291 - est31:let_else_tests, r=joshtriplett
oxalica commentedon Sep 7, 2022
The current proposal-ed syntax accepts no pattern in the
elsebranch. This makes it unhelpful with another common pattern,We may workaround by
let Ok(val) = (...).map_err(|e| /* use e */) else { return; }but it is 1. ugly, 2. fail to compile if bothOkandErrbranches take ownership of some variables.Note that Idris has a similar syntax which supports "else-arms" in case of failed let binding.
This reminds me that general
let-elseshould be a specialmatchwith one arm binding to current scope.Could we do better in this case? Syntax like
let Ok(e) = ... else match { Err(e) => { ... } }could work but seems a bit too complicated.Eugeny commentedon Sep 7, 2022
IMO at that point it's easier to just
let x = match ...with a deviating Err branchRollup merge of rust-lang#93628 - est31:stabilize_let_else, r=joshtri…
Rollup merge of rust-lang#93628 - est31:stabilize_let_else, r=joshtri…
Depend on rust 1.65.0
Rust: Work around 'error[E0658]: `let...else` statements are unstable'