Skip to content

Commit 72d71c5

Browse files
committed
semantic: Implement simple global union literals to implement .init.
1 parent f7a7ebe commit 72d71c5

File tree

4 files changed

+32
-6
lines changed

4 files changed

+32
-6
lines changed

src/volt/lowerer/llvmlowerer.d

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -749,7 +749,7 @@ void lowerStructLiteral(LanguagePass lp, ir.Scope current, ref ir.Exp exp, ir.St
749749
panicAssert(exp, literal.type !is null);
750750
auto theStruct = cast(ir.Struct) realType(literal.type);
751751
panicAssert(exp, theStruct !is null);
752-
auto fields = getStructFieldVars(theStruct);
752+
auto fields = getAggregateFieldVars(theStruct);
753753
// The extyper should've caught this.
754754
panicAssert(exp, fields.length >= literal.exps.length);
755755

src/volt/semantic/classify.d

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1290,7 +1290,7 @@ ir.Type[] getStructFieldTypes(ir.Struct _struct)
12901290
}
12911291

12921292
//! Retrieves the Variables in _struct, in the order they appear.
1293-
ir.Variable[] getStructFieldVars(ir.Struct _struct)
1293+
ir.Variable[] getAggregateFieldVars(ir.Aggregate _struct)
12941294
{
12951295
ir.Variable[] vars;
12961296

src/volt/semantic/extyper.d

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5151,16 +5151,31 @@ void tagLiteralType(ir.Exp exp, ir.Type type)
51515151
auto stype = cast(ir.Struct)realType(type);
51525152
auto slit = cast(ir.StructLiteral)exp;
51535153
if (stype is null || slit is null) {
5154-
throw panic(/*#ref*/exp.loc, "tagging struct literal as not an struct.");
5154+
throw panic(/*#ref*/exp.loc, "tagging struct literal as not a struct.");
51555155
}
5156-
auto vars = getStructFieldVars(stype);
5156+
auto vars = getAggregateFieldVars(stype);
51575157
if (slit.exps.length > vars.length) {
51585158
throw makeWrongNumberOfArgumentsToStructLiteral(/*#ref*/exp.loc);
51595159
}
51605160
foreach (i, val; slit.exps) {
51615161
tagLiteralType(val, vars[i].type);
51625162
}
51635163
break;
5164+
case UnionLiteral:
5165+
auto utype = cast(ir.Union)realType(type);
5166+
auto ulit = exp.toUnionLiteralFast();
5167+
if (utype is null || ulit is null) {
5168+
throw panic(/*#ref*/exp.loc, "tagging union literal as not a union");
5169+
}
5170+
auto vars = getAggregateFieldVars(utype);
5171+
if (ulit.exps.length > vars.length) {
5172+
// @TODO: Union literals that can just take the largest field.
5173+
throw makeWrongNumberOfArgumentsToStructLiteral(/*#ref*/exp.loc);
5174+
}
5175+
foreach (i, val; ulit.exps) {
5176+
tagLiteralType(val, vars[i].type);
5177+
}
5178+
break;
51645179
default:
51655180
throw panicUnhandled(/*#ref*/exp.loc, "literal type");
51665181
}

src/volt/semantic/typer.d

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,9 @@ ir.Type getExpTypeImpl(ir.Exp exp)
100100
auto asStructLiteral = cast(ir.StructLiteral) exp;
101101
assert(asStructLiteral !is null);
102102
return getStructLiteralType(asStructLiteral);
103+
case UnionLiteral:
104+
auto asUnionLiteral = exp.toUnionLiteralFast();
105+
return getUnionLiteralType(asUnionLiteral);
103106
case ClassLiteral:
104107
auto asClassLiteral = cast(ir.ClassLiteral) exp;
105108
assert(asClassLiteral !is null);
@@ -185,9 +188,17 @@ ir.Type getStructLiteralType(ir.StructLiteral slit)
185188
return slit.type;
186189
}
187190

188-
ir.Type getClassLiteralType(ir.ClassLiteral clit)
191+
ir.Type getUnionLiteralType(ir.UnionLiteral ulit)
189192
{
190-
return clit.type;
193+
if (ulit.type is null) {
194+
throw panic(/*#ref*/ulit.loc, "null union literal");
195+
}
196+
return ulit.type;
197+
}
198+
199+
ir.Type getClassLiteralType(ir.ClassLiteral classlit)
200+
{
201+
return classlit.type;
191202
}
192203

193204
ir.Type getExpReferenceType(ir.ExpReference expref)

0 commit comments

Comments
 (0)