Skip to content

Explicit refutable let: let..else #373

Closed
@glaebhoerl

Description

@glaebhoerl

Our lets are currently irrefutable. This is good. We could also have refutable lets with an explicit else clause:

let Ok(foo) = do_thing(...) else panic!();

In the simplest formulation, there would be a single else clause with the argument being anything of type ! (break, return, panic!, etc.). More sophistication is possible with chained else clauses, where multiple RHSs are tried in succession, with only the last one required to be of type !; and by also allowing a literal or constant which definitely matches rather than just an ! (so in the above example, else Ok(9), for instance).

The use case for this overlaps with if let, but not completely. if let involves rightward drift, and is appropriate if you want access to e.g. the value in an Option for a short period, and then to do other things afterwards, or if you want to handle the else case by something other than exiting. let..else avoids rightwards drift and is appropriate if you want to early-escape from the whole computation when the pattern doesn't match.

The potential for syntactic ambiguity with if..else needs to be thought through. But I don't believe there is an actual problem:

let PAT = if { EXPR } else { EXPR };

If we interpret this as being an if expression without an else block, and the else block as belonging to the let, that ends up being contradictory: if expressions have type (), which is never refutable, and so doesn't make any sense as the type of PAT in a refutable let. So the only sensible way to interpret this is as an if-else expression on the RHS.

Earlier discussion on the mailing list.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-control-flowProposals relating to control flow.A-expressionsTerm language related proposals & ideasA-syntaxSyntax related proposals & ideasT-langRelevant to the language team, which will review and decide on the RFC.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions