Make choice work for alternatives without parameters (#4815)

This adds support for choice types at a similar level to that of a C
enum, where each alternative has a name but no additional
data/parameters attached to it. We generate a TODO diagnostic if
parameters are specified.

Because there's no extra data, the storage is a simple unsigned integer
discriminant of the smallest possible size.

A choice without any alternatives is not constructible. A choice with a
single alternative is, and has an empty tuple in place of a discriminant
since it has only one state. The empty tuple is used to make the class
non-constructible. This can be improved.

Each alternative is turned into a let binding on the choice that is a
value of the choice with that alternative set as the active one in the
discriminant. This isn't possible to write in user code with a class
right now, since the let binding has the same type as the choice
(which is a class) it is within. It's possible to generate it in semir
however by adding the binding after the class is marked complete.
This commit is contained in:
Dana Jansens
2025-02-19 16:37:36 +00:00
committed by GitHub
parent 6a99c4e970
commit 3f01310039
14 changed files with 1171 additions and 16 deletions
+3 -2
View File
@@ -417,6 +417,8 @@ class NodeStack {
case Parse::NodeKind::FunctionDefinitionStart:
case Parse::NodeKind::BuiltinFunctionDefinitionStart:
return Id::KindFor<SemIR::FunctionId>();
case Parse::NodeKind::ChoiceDefinitionStart:
// TODO: Should we have a separate SemIR::ChoiceId?
case Parse::NodeKind::ClassDefinitionStart:
return Id::KindFor<SemIR::ClassId>();
case Parse::NodeKind::InterfaceDefinitionStart:
@@ -431,6 +433,7 @@ class NodeStack {
return Id::KindFor<SemIR::LibraryNameId>();
case Parse::NodeKind::ArrayExprSemi:
case Parse::NodeKind::BuiltinName:
case Parse::NodeKind::ChoiceIntroducer:
case Parse::NodeKind::ClassIntroducer:
case Parse::NodeKind::CodeBlockStart:
case Parse::NodeKind::FunctionIntroducer:
@@ -459,8 +462,6 @@ class NodeStack {
case Parse::NodeKind::BreakStatementStart:
case Parse::NodeKind::CallExprComma:
case Parse::NodeKind::ChoiceAlternativeListComma:
case Parse::NodeKind::ChoiceDefinitionStart:
case Parse::NodeKind::ChoiceIntroducer:
case Parse::NodeKind::CodeBlock:
case Parse::NodeKind::ContinueStatementStart:
case Parse::NodeKind::CorePackageName: