Merge branch 'main' of github.com:roc-lang/roc into upgrade-to-zig-1.15.1

This commit is contained in:
Anton-4 2025-10-14 15:48:33 +02:00
commit e5fed613ce
No known key found for this signature in database
559 changed files with 35924 additions and 26259 deletions

View file

@ -35,8 +35,8 @@ env: *CommonEnv,
tokens: TokenizedBuffer,
store: NodeStore,
root_node_idx: u32 = 0,
tokenize_diagnostics: std.ArrayList(tokenize.Diagnostic),
parse_diagnostics: std.ArrayList(AST.Diagnostic),
tokenize_diagnostics: std.array_list.Managed(tokenize.Diagnostic),
parse_diagnostics: std.array_list.Managed(AST.Diagnostic),
/// Calculate whether this region is - or will be - multiline
pub fn regionIsMultiline(self: *AST, region: TokenizedRegion) bool {
@ -201,7 +201,9 @@ pub fn tokenizedRegionToRegion(self: *AST, tokenized_region: TokenizedRegion) ba
safe_end_idx;
const start_region = self.tokens.resolve(safe_start_idx);
const end_region = self.tokens.resolve(final_end_idx - 1);
// Protect against underflow when final_end_idx is 0
const end_idx = if (final_end_idx > 0) final_end_idx - 1 else 0;
const end_region = self.tokens.resolve(end_idx);
return .{
.start = start_region.start,
.end = end_region.end,
@ -252,6 +254,9 @@ pub fn parseDiagnosticToReport(self: *AST, env: *const CommonEnv, diagnostic: Di
.where_expected_colon => "WHERE CLAUSE ERROR",
.where_expected_constraints => "WHERE CLAUSE ERROR",
.no_else => "IF WITHOUT ELSE",
.type_alias_cannot_have_associated => "TYPE ALIAS WITH ASSOCIATED ITEMS",
.nominal_associated_cannot_have_final_expression => "EXPRESSION IN ASSOCIATED ITEMS",
.where_clause_not_allowed_in_type_declaration => "WHERE CLAUSE IN TYPE DECLARATION",
else => "PARSE ERROR",
};
@ -548,6 +553,30 @@ pub fn parseDiagnosticToReport(self: *AST, env: *const CommonEnv, diagnostic: Di
try report.document.addKeyword("False");
try report.document.addReflowingText(".");
},
.type_alias_cannot_have_associated => {
try report.document.addText("Type aliases cannot have associated items (such as types or methods).");
try report.document.addLineBreak();
try report.document.addLineBreak();
try report.document.addReflowingText("Only nominal types (defined with ");
try report.document.addAnnotated(":=", .emphasized);
try report.document.addReflowingText(") can have associated items. Type aliases (defined with ");
try report.document.addAnnotated(":", .emphasized);
try report.document.addReflowingText(") only define names for other types.");
},
.nominal_associated_cannot_have_final_expression => {
try report.document.addText("Associated items (such as types or methods) can only have associated types and values, not plain expressions.");
try report.document.addLineBreak();
try report.document.addLineBreak();
try report.document.addText("To fix this, remove the expression at the very end.");
},
.where_clause_not_allowed_in_type_declaration => {
try report.document.addText("Type declarations cannot include ");
try report.document.addKeyword("where");
try report.document.addText(" clauses.");
try report.document.addLineBreak();
try report.document.addLineBreak();
try report.document.addReflowingText("Only type annotations (such as annottions for a function or other value) can have them.");
},
else => {
const tag_name = @tagName(diagnostic.tag);
const owned_tag = try report.addOwnedString(tag_name);
@ -676,6 +705,9 @@ pub const Diagnostic = struct {
expected_expr_close_curly,
expr_dot_suffix_not_allowed,
incomplete_import,
nominal_associated_cannot_have_final_expression,
type_alias_cannot_have_associated,
where_clause_not_allowed_in_type_declaration,
};
};
@ -834,8 +866,12 @@ pub const Statement = union(enum) {
type_decl: struct {
header: TypeHeader.Idx,
anno: TypeAnno.Idx,
where: ?Collection.Idx,
kind: TypeDeclKind,
/// Where clause (invalid in type declarations, but preserved for error recovery/formatting)
where: ?Collection.Idx,
/// Associated items block for .nominal types
/// (e.g. the curly braces in `Foo := [A, B].{ x = 5 }`)
associated: ?Associated,
region: TokenizedRegion,
},
type_anno: struct {
@ -978,15 +1014,19 @@ pub const Statement = union(enum) {
try ast.store.getTypeAnno(a.anno).pushToSExprTree(gpa, env, ast, tree);
if (a.where) |where_coll| {
const where_node = tree.beginNode();
try tree.pushStaticAtom("where");
const attrs2 = tree.beginNode();
for (ast.store.whereClauseSlice(.{ .span = ast.store.getCollection(where_coll).span })) |clause_idx| {
const clause_child = ast.store.getWhereClause(clause_idx);
try clause_child.pushToSExprTree(gpa, env, ast, tree);
// Add associated block if present
if (a.associated) |assoc| {
const assoc_begin = tree.beginNode();
try tree.pushStaticAtom("associated");
try ast.appendRegionInfoToSexprTree(env, tree, assoc.region);
const assoc_attrs = tree.beginNode();
for (ast.store.statementSlice(assoc.statements)) |stmt_idx| {
const stmt = ast.store.getStatement(stmt_idx);
try stmt.pushToSExprTree(gpa, env, ast, tree);
}
try tree.endNode(where_node, attrs2);
try tree.endNode(assoc_begin, assoc_attrs);
}
try tree.endNode(begin, attrs);
@ -1126,6 +1166,15 @@ pub const Block = struct {
}
};
/// Represents associated items for nominal type declarations.
/// Associated items are the statements in the `.{ }` block after a nominal type,
/// e.g., `Foo := [A, B].{ x = 5 }`
pub const Associated = struct {
/// The statements in the associated items block
statements: Statement.Span,
region: TokenizedRegion,
};
/// Represents a Pattern used in pattern matching.
pub const Pattern = union(enum) {
ident: struct {
@ -1496,6 +1545,15 @@ pub const Header = union(enum) {
exposes: Collection.Idx,
region: TokenizedRegion,
},
type_module: struct {
region: TokenizedRegion,
},
default_app: struct {
// Stores reference to the main! function
// This will be filled in during canonicalization when main! is found
main_fn_idx: u32, // Will store CIR Def.Idx
region: TokenizedRegion,
},
malformed: struct {
reason: Diagnostic.Tag,
region: TokenizedRegion,
@ -1681,6 +1739,23 @@ pub const Header = union(enum) {
try tree.endNode(begin, attrs);
},
.type_module => |a| {
const begin = tree.beginNode();
try tree.pushStaticAtom("type-module");
try ast.appendRegionInfoToSexprTree(env, tree, a.region);
const attrs = tree.beginNode();
try tree.endNode(begin, attrs);
},
.default_app => |a| {
const begin = tree.beginNode();
try tree.pushStaticAtom("default-app");
try ast.appendRegionInfoToSexprTree(env, tree, a.region);
const attrs = tree.beginNode();
var buf: [32]u8 = undefined;
const idx_str = std.fmt.bufPrint(&buf, "{d}", .{a.main_fn_idx}) catch "(error)";
try tree.pushStringPair("main-fn-idx", idx_str);
try tree.endNode(begin, attrs);
},
.malformed => |a| {
const begin = tree.beginNode();
try tree.pushStaticAtom("malformed-header");
@ -1700,6 +1775,8 @@ pub const Header = union(enum) {
.package => |p| p.region,
.platform => |p| p.region,
.hosted => |h| h.region,
.type_module => |t| t.region,
.default_app => |d| d.region,
.malformed => |m| m.region,
};
}