Second draft: Sum Type by Struct

Nick Treleaven nick at geany.org
Wed Sep 9 10:16:04 UTC 2026


On Saturday, 5 September 2026 at 16:51:20 UTC, Meta wrote:
> On Saturday, 5 September 2026 at 16:02:08 UTC, Nick Treleaven 
> wrote:
>> Not being able to use `return` in a match *expression* is 
>> understandable. Not having a match *statement* which can use 
>> `return` seems like a big omission IMO.
>
> You can have arms with return, break, continue, throw, etc. if 
> you allow their type to resolve to noreturn, and they would 
> refer to the innermost enclosing control flow construct (or 
> otherwise it's an error - match/switch expressions themselves 
> cannot break out early).

When `match` is used as a statement it is fine to `break` out of 
the `match`. Also, supporting statement arm matching is important 
even when `match` is an expression, otherwise you can't 
conditionally return in an arm:

```d
E3 foo()
{
     E4 result = e1.match {
         (T v) {
             statements;
             if (e2)
                 return e3; // return from `foo`
             else
                 break e4; // e4 is the result of this arm
         }
         // more cases
     }
     statements;
}
```

> It's basically saying "execution will not continue past this 
> point, so this expression does not need to have a value". This 
> isn't in Rikki's proposal, but it's perfectly sound from a type 
> theory perspective. I imagine in DMD it'd require the creating 
> of a "DivergeExpression" AST node or something.

But would that allow arbitrary statements in a match arm?

Rikki's DIP lowers to a chain of conditional expressions to avoid 
complicating/rewriting the backend. Presumably that is so a 
`match` expression works anywhere a normal expression works. But 
is that overkill? Is it good practice to write a `match` 
expression as a subexpression? I think usually it is not. A DIP 
could just support match expressions for the common statement 
cases:

```d
T v = e.match { ... };
return e.match { ... };
```
So the AST for those could be `class MatchExpInitializer : 
ExpInitializer` and `class ReturnMatchStatement : 
ReturnStatement`. Those could have AST lowerings without touching 
the backend, yet contain statements in the match arms.


More information about the dip.development mailing list