feat(selfhost-diag): struct-literal refType, unknown named args, comma leniency, debug cleanup

This commit is contained in:
2026-07-28 22:32:20 +03:00
parent a538e05041
commit 4f583eaec1
2 changed files with 42 additions and 6 deletions
+10 -6
View File
@@ -2168,6 +2168,7 @@ module Parser {
parserParseTypeParams(p, d);
discard parserExpect(p, tkLBrace, "expected '{'");
var lastWasComma: bool = false;
while !parserCheck(p, tkRBrace) && parserPeek(p, 0) != tkEndOfFile {
if fieldCount >= 256 {
parserEmitDiag(p, line, col, "too many struct fields (max 255)");
@@ -2176,14 +2177,16 @@ module Parser {
if parserCheck(p, tkNewLine) { discard parserAdvance(p); continue; }
if parserCheck(p, tkSemicolon) { discard parserAdvance(p); continue; }
// Commas are also valid field separators (incl. trailing comma before '}')
if parserCheck(p, tkComma) { discard parserAdvance(p); continue; }
if parserCheck(p, tkComma) {
if fieldCount == 0 || lastWasComma {
parserEmitDiag(p, parserCurToken(p).line, parserCurToken(p).column, "expected field name");
}
lastWasComma = true;
discard parserAdvance(p);
continue;
}
let beforePos: int = p.pos;
let fName: LexToken = parserExpectIdentOrKeyword(p, "expected field name");
if fieldCount >= 250 && fieldCount <= 256 {
PrintLine(String_Concat("RAW fieldCount=", bux_int_to_str(fieldCount as int64)));
PrintLine(String_Concat("RAW fName=", fName.text));
PrintLine(String_Concat("RAW pos=", bux_int_to_str(p.pos as int64)));
}
discard parserExpect(p, tkColon, "expected ':' in struct field");
let fType: *TypeExpr = parserParseType(p);
parserMatch(p, tkSemicolon);
@@ -2196,6 +2199,7 @@ module Parser {
d.fields[fieldCount].name = fName.text;
d.fields[fieldCount].refFieldType = fType;
fieldCount = fieldCount + 1;
lastWasComma = false;
}
d.fieldCount = fieldCount;
discard parserExpect(p, tkRBrace, "expected '}'");
+32
View File
@@ -360,6 +360,34 @@ module Sema {
i = i + 1;
}
// Report named args that match no parameter
var checkArg: *ExprList = expr.callArgs;
while checkArg != null as *ExprList {
if !String_Eq(checkArg.argName, "") {
var foundName: bool = false;
var j: int = 0;
while j < decl.paramCount {
var pj: *Param = null as *Param;
if j == 0 { pj = &decl.param0; }
else if j == 1 { pj = &decl.param1; }
else if j == 2 { pj = &decl.param2; }
else if j == 3 { pj = &decl.param3; }
else if j == 4 { pj = &decl.param4; }
else if j == 5 { pj = &decl.param5; }
else if j == 6 { pj = &decl.param6; }
else if j == 7 { pj = &decl.param7; }
else if j == 8 { pj = &decl.param8; }
if String_Eq(checkArg.argName, pj.name) { foundName = true; }
j = j + 1;
}
if !foundName {
Sema_EmitError(sema, expr.line, expr.column,
String_Concat("unknown argument name '", String_Concat(checkArg.argName, "'")));
}
}
checkArg = checkArg.next;
}
expr.callArgs = newFirst;
expr.callArgCount = newCount;
}
@@ -1227,6 +1255,10 @@ module Sema {
// Struct init: TypeName { field: value, ... }
if kind == ekStructInit {
let te: *TypeExpr = bux_alloc(sizeof(TypeExpr)) as *TypeExpr;
te.kind = tekNamed;
te.typeName = expr.structName;
expr.refType = te;
return tyNamed;
}