From fb3952615948748baab6cac02371a7cbfff4e9ac Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Tue, 11 May 2021 14:50:39 -0700 Subject: [PATCH] AstGen: support emitting multiple compile errors --- BRANCH_TODO | 5 +- src/AstGen.zig | 300 +++++++++++++++++++++++++++++++++++--------- src/Compilation.zig | 15 ++- 3 files changed, 256 insertions(+), 64 deletions(-) diff --git a/BRANCH_TODO b/BRANCH_TODO index ac1ad75b7e..e89cd16acb 100644 --- a/BRANCH_TODO +++ b/BRANCH_TODO @@ -44,9 +44,6 @@ * sort compile errors before presenting them to eliminate nondeterministic error reporting - * when handling decls, catch the error and continue, so that - AstGen can report more than one compile error. - * AstGen: add result location pointers to function calls * nested function decl: how to refer to params? @@ -66,3 +63,5 @@ * better anonymous Decl naming convention - avoid the global atomic integer for the number because of contention + + * AstGen memory leak with `block_gz.labeled_store_to_block_ptr_list.append` diff --git a/src/AstGen.zig b/src/AstGen.zig index f445f3dd26..c8225602ae 100644 --- a/src/AstGen.zig +++ b/src/AstGen.zig @@ -3317,20 +3317,32 @@ fn structDeclInner( switch (node_tags[fn_proto]) { .fn_proto_simple => { var params: [1]ast.Node.Index = undefined; - try astgen.fnDecl(gz, &wip_decls, member_node, body, tree.fnProtoSimple(¶ms, fn_proto)); + astgen.fnDecl(gz, &wip_decls, member_node, body, tree.fnProtoSimple(¶ms, fn_proto)) catch |err| switch (err) { + error.OutOfMemory => return error.OutOfMemory, + error.AnalysisFail => {}, + }; continue; }, .fn_proto_multi => { - try astgen.fnDecl(gz, &wip_decls, member_node, body, tree.fnProtoMulti(fn_proto)); + astgen.fnDecl(gz, &wip_decls, member_node, body, tree.fnProtoMulti(fn_proto)) catch |err| switch (err) { + error.OutOfMemory => return error.OutOfMemory, + error.AnalysisFail => {}, + }; continue; }, .fn_proto_one => { var params: [1]ast.Node.Index = undefined; - try astgen.fnDecl(gz, &wip_decls, member_node, body, tree.fnProtoOne(¶ms, fn_proto)); + astgen.fnDecl(gz, &wip_decls, member_node, body, tree.fnProtoOne(¶ms, fn_proto)) catch |err| switch (err) { + error.OutOfMemory => return error.OutOfMemory, + error.AnalysisFail => {}, + }; continue; }, .fn_proto => { - try astgen.fnDecl(gz, &wip_decls, member_node, body, tree.fnProto(fn_proto)); + astgen.fnDecl(gz, &wip_decls, member_node, body, tree.fnProto(fn_proto)) catch |err| switch (err) { + error.OutOfMemory => return error.OutOfMemory, + error.AnalysisFail => {}, + }; continue; }, else => unreachable, @@ -3338,50 +3350,83 @@ fn structDeclInner( }, .fn_proto_simple => { var params: [1]ast.Node.Index = undefined; - try astgen.fnDecl(gz, &wip_decls, member_node, 0, tree.fnProtoSimple(¶ms, member_node)); + astgen.fnDecl(gz, &wip_decls, member_node, 0, tree.fnProtoSimple(¶ms, member_node)) catch |err| switch (err) { + error.OutOfMemory => return error.OutOfMemory, + error.AnalysisFail => {}, + }; continue; }, .fn_proto_multi => { - try astgen.fnDecl(gz, &wip_decls, member_node, 0, tree.fnProtoMulti(member_node)); + astgen.fnDecl(gz, &wip_decls, member_node, 0, tree.fnProtoMulti(member_node)) catch |err| switch (err) { + error.OutOfMemory => return error.OutOfMemory, + error.AnalysisFail => {}, + }; continue; }, .fn_proto_one => { var params: [1]ast.Node.Index = undefined; - try astgen.fnDecl(gz, &wip_decls, member_node, 0, tree.fnProtoOne(¶ms, member_node)); + astgen.fnDecl(gz, &wip_decls, member_node, 0, tree.fnProtoOne(¶ms, member_node)) catch |err| switch (err) { + error.OutOfMemory => return error.OutOfMemory, + error.AnalysisFail => {}, + }; continue; }, .fn_proto => { - try astgen.fnDecl(gz, &wip_decls, member_node, 0, tree.fnProto(member_node)); + astgen.fnDecl(gz, &wip_decls, member_node, 0, tree.fnProto(member_node)) catch |err| switch (err) { + error.OutOfMemory => return error.OutOfMemory, + error.AnalysisFail => {}, + }; continue; }, .global_var_decl => { - try astgen.globalVarDecl(gz, scope, &wip_decls, member_node, tree.globalVarDecl(member_node)); + astgen.globalVarDecl(gz, scope, &wip_decls, member_node, tree.globalVarDecl(member_node)) catch |err| switch (err) { + error.OutOfMemory => return error.OutOfMemory, + error.AnalysisFail => {}, + }; continue; }, .local_var_decl => { - try astgen.globalVarDecl(gz, scope, &wip_decls, member_node, tree.localVarDecl(member_node)); + astgen.globalVarDecl(gz, scope, &wip_decls, member_node, tree.localVarDecl(member_node)) catch |err| switch (err) { + error.OutOfMemory => return error.OutOfMemory, + error.AnalysisFail => {}, + }; continue; }, .simple_var_decl => { - try astgen.globalVarDecl(gz, scope, &wip_decls, member_node, tree.simpleVarDecl(member_node)); + astgen.globalVarDecl(gz, scope, &wip_decls, member_node, tree.simpleVarDecl(member_node)) catch |err| switch (err) { + error.OutOfMemory => return error.OutOfMemory, + error.AnalysisFail => {}, + }; continue; }, .aligned_var_decl => { - try astgen.globalVarDecl(gz, scope, &wip_decls, member_node, tree.alignedVarDecl(member_node)); + astgen.globalVarDecl(gz, scope, &wip_decls, member_node, tree.alignedVarDecl(member_node)) catch |err| switch (err) { + error.OutOfMemory => return error.OutOfMemory, + error.AnalysisFail => {}, + }; continue; }, .@"comptime" => { - try astgen.comptimeDecl(gz, scope, &wip_decls, member_node); + astgen.comptimeDecl(gz, scope, &wip_decls, member_node) catch |err| switch (err) { + error.OutOfMemory => return error.OutOfMemory, + error.AnalysisFail => {}, + }; continue; }, .@"usingnamespace" => { - try astgen.usingnamespaceDecl(gz, scope, &wip_decls, member_node); + astgen.usingnamespaceDecl(gz, scope, &wip_decls, member_node) catch |err| switch (err) { + error.OutOfMemory => return error.OutOfMemory, + error.AnalysisFail => {}, + }; continue; }, .test_decl => { - try astgen.testDecl(gz, scope, &wip_decls, member_node); + astgen.testDecl(gz, scope, &wip_decls, member_node) catch |err| switch (err) { + error.OutOfMemory => return error.OutOfMemory, + error.AnalysisFail => {}, + }; continue; }, else => unreachable, @@ -3530,20 +3575,32 @@ fn unionDeclInner( switch (node_tags[fn_proto]) { .fn_proto_simple => { var params: [1]ast.Node.Index = undefined; - try astgen.fnDecl(gz, &wip_decls, member_node, body, tree.fnProtoSimple(¶ms, fn_proto)); + astgen.fnDecl(gz, &wip_decls, member_node, body, tree.fnProtoSimple(¶ms, fn_proto)) catch |err| switch (err) { + error.OutOfMemory => return error.OutOfMemory, + error.AnalysisFail => {}, + }; continue; }, .fn_proto_multi => { - try astgen.fnDecl(gz, &wip_decls, member_node, body, tree.fnProtoMulti(fn_proto)); + astgen.fnDecl(gz, &wip_decls, member_node, body, tree.fnProtoMulti(fn_proto)) catch |err| switch (err) { + error.OutOfMemory => return error.OutOfMemory, + error.AnalysisFail => {}, + }; continue; }, .fn_proto_one => { var params: [1]ast.Node.Index = undefined; - try astgen.fnDecl(gz, &wip_decls, member_node, body, tree.fnProtoOne(¶ms, fn_proto)); + astgen.fnDecl(gz, &wip_decls, member_node, body, tree.fnProtoOne(¶ms, fn_proto)) catch |err| switch (err) { + error.OutOfMemory => return error.OutOfMemory, + error.AnalysisFail => {}, + }; continue; }, .fn_proto => { - try astgen.fnDecl(gz, &wip_decls, member_node, body, tree.fnProto(fn_proto)); + astgen.fnDecl(gz, &wip_decls, member_node, body, tree.fnProto(fn_proto)) catch |err| switch (err) { + error.OutOfMemory => return error.OutOfMemory, + error.AnalysisFail => {}, + }; continue; }, else => unreachable, @@ -3551,50 +3608,83 @@ fn unionDeclInner( }, .fn_proto_simple => { var params: [1]ast.Node.Index = undefined; - try astgen.fnDecl(gz, &wip_decls, member_node, 0, tree.fnProtoSimple(¶ms, member_node)); + astgen.fnDecl(gz, &wip_decls, member_node, 0, tree.fnProtoSimple(¶ms, member_node)) catch |err| switch (err) { + error.OutOfMemory => return error.OutOfMemory, + error.AnalysisFail => {}, + }; continue; }, .fn_proto_multi => { - try astgen.fnDecl(gz, &wip_decls, member_node, 0, tree.fnProtoMulti(member_node)); + astgen.fnDecl(gz, &wip_decls, member_node, 0, tree.fnProtoMulti(member_node)) catch |err| switch (err) { + error.OutOfMemory => return error.OutOfMemory, + error.AnalysisFail => {}, + }; continue; }, .fn_proto_one => { var params: [1]ast.Node.Index = undefined; - try astgen.fnDecl(gz, &wip_decls, member_node, 0, tree.fnProtoOne(¶ms, member_node)); + astgen.fnDecl(gz, &wip_decls, member_node, 0, tree.fnProtoOne(¶ms, member_node)) catch |err| switch (err) { + error.OutOfMemory => return error.OutOfMemory, + error.AnalysisFail => {}, + }; continue; }, .fn_proto => { - try astgen.fnDecl(gz, &wip_decls, member_node, 0, tree.fnProto(member_node)); + astgen.fnDecl(gz, &wip_decls, member_node, 0, tree.fnProto(member_node)) catch |err| switch (err) { + error.OutOfMemory => return error.OutOfMemory, + error.AnalysisFail => {}, + }; continue; }, .global_var_decl => { - try astgen.globalVarDecl(gz, scope, &wip_decls, member_node, tree.globalVarDecl(member_node)); + astgen.globalVarDecl(gz, scope, &wip_decls, member_node, tree.globalVarDecl(member_node)) catch |err| switch (err) { + error.OutOfMemory => return error.OutOfMemory, + error.AnalysisFail => {}, + }; continue; }, .local_var_decl => { - try astgen.globalVarDecl(gz, scope, &wip_decls, member_node, tree.localVarDecl(member_node)); + astgen.globalVarDecl(gz, scope, &wip_decls, member_node, tree.localVarDecl(member_node)) catch |err| switch (err) { + error.OutOfMemory => return error.OutOfMemory, + error.AnalysisFail => {}, + }; continue; }, .simple_var_decl => { - try astgen.globalVarDecl(gz, scope, &wip_decls, member_node, tree.simpleVarDecl(member_node)); + astgen.globalVarDecl(gz, scope, &wip_decls, member_node, tree.simpleVarDecl(member_node)) catch |err| switch (err) { + error.OutOfMemory => return error.OutOfMemory, + error.AnalysisFail => {}, + }; continue; }, .aligned_var_decl => { - try astgen.globalVarDecl(gz, scope, &wip_decls, member_node, tree.alignedVarDecl(member_node)); + astgen.globalVarDecl(gz, scope, &wip_decls, member_node, tree.alignedVarDecl(member_node)) catch |err| switch (err) { + error.OutOfMemory => return error.OutOfMemory, + error.AnalysisFail => {}, + }; continue; }, .@"comptime" => { - try astgen.comptimeDecl(gz, scope, &wip_decls, member_node); + astgen.comptimeDecl(gz, scope, &wip_decls, member_node) catch |err| switch (err) { + error.OutOfMemory => return error.OutOfMemory, + error.AnalysisFail => {}, + }; continue; }, .@"usingnamespace" => { - try astgen.usingnamespaceDecl(gz, scope, &wip_decls, member_node); + astgen.usingnamespaceDecl(gz, scope, &wip_decls, member_node) catch |err| switch (err) { + error.OutOfMemory => return error.OutOfMemory, + error.AnalysisFail => {}, + }; continue; }, .test_decl => { - try astgen.testDecl(gz, scope, &wip_decls, member_node); + astgen.testDecl(gz, scope, &wip_decls, member_node) catch |err| switch (err) { + error.OutOfMemory => return error.OutOfMemory, + error.AnalysisFail => {}, + }; continue; }, else => unreachable, @@ -3878,20 +3968,32 @@ fn containerDecl( switch (node_tags[fn_proto]) { .fn_proto_simple => { var params: [1]ast.Node.Index = undefined; - try astgen.fnDecl(gz, &wip_decls, member_node, body, tree.fnProtoSimple(¶ms, fn_proto)); + astgen.fnDecl(gz, &wip_decls, member_node, body, tree.fnProtoSimple(¶ms, fn_proto)) catch |err| switch (err) { + error.OutOfMemory => return error.OutOfMemory, + error.AnalysisFail => {}, + }; continue; }, .fn_proto_multi => { - try astgen.fnDecl(gz, &wip_decls, member_node, body, tree.fnProtoMulti(fn_proto)); + astgen.fnDecl(gz, &wip_decls, member_node, body, tree.fnProtoMulti(fn_proto)) catch |err| switch (err) { + error.OutOfMemory => return error.OutOfMemory, + error.AnalysisFail => {}, + }; continue; }, .fn_proto_one => { var params: [1]ast.Node.Index = undefined; - try astgen.fnDecl(gz, &wip_decls, member_node, body, tree.fnProtoOne(¶ms, fn_proto)); + astgen.fnDecl(gz, &wip_decls, member_node, body, tree.fnProtoOne(¶ms, fn_proto)) catch |err| switch (err) { + error.OutOfMemory => return error.OutOfMemory, + error.AnalysisFail => {}, + }; continue; }, .fn_proto => { - try astgen.fnDecl(gz, &wip_decls, member_node, body, tree.fnProto(fn_proto)); + astgen.fnDecl(gz, &wip_decls, member_node, body, tree.fnProto(fn_proto)) catch |err| switch (err) { + error.OutOfMemory => return error.OutOfMemory, + error.AnalysisFail => {}, + }; continue; }, else => unreachable, @@ -3899,50 +4001,83 @@ fn containerDecl( }, .fn_proto_simple => { var params: [1]ast.Node.Index = undefined; - try astgen.fnDecl(gz, &wip_decls, member_node, 0, tree.fnProtoSimple(¶ms, member_node)); + astgen.fnDecl(gz, &wip_decls, member_node, 0, tree.fnProtoSimple(¶ms, member_node)) catch |err| switch (err) { + error.OutOfMemory => return error.OutOfMemory, + error.AnalysisFail => {}, + }; continue; }, .fn_proto_multi => { - try astgen.fnDecl(gz, &wip_decls, member_node, 0, tree.fnProtoMulti(member_node)); + astgen.fnDecl(gz, &wip_decls, member_node, 0, tree.fnProtoMulti(member_node)) catch |err| switch (err) { + error.OutOfMemory => return error.OutOfMemory, + error.AnalysisFail => {}, + }; continue; }, .fn_proto_one => { var params: [1]ast.Node.Index = undefined; - try astgen.fnDecl(gz, &wip_decls, member_node, 0, tree.fnProtoOne(¶ms, member_node)); + astgen.fnDecl(gz, &wip_decls, member_node, 0, tree.fnProtoOne(¶ms, member_node)) catch |err| switch (err) { + error.OutOfMemory => return error.OutOfMemory, + error.AnalysisFail => {}, + }; continue; }, .fn_proto => { - try astgen.fnDecl(gz, &wip_decls, member_node, 0, tree.fnProto(member_node)); + astgen.fnDecl(gz, &wip_decls, member_node, 0, tree.fnProto(member_node)) catch |err| switch (err) { + error.OutOfMemory => return error.OutOfMemory, + error.AnalysisFail => {}, + }; continue; }, .global_var_decl => { - try astgen.globalVarDecl(gz, scope, &wip_decls, member_node, tree.globalVarDecl(member_node)); + astgen.globalVarDecl(gz, scope, &wip_decls, member_node, tree.globalVarDecl(member_node)) catch |err| switch (err) { + error.OutOfMemory => return error.OutOfMemory, + error.AnalysisFail => {}, + }; continue; }, .local_var_decl => { - try astgen.globalVarDecl(gz, scope, &wip_decls, member_node, tree.localVarDecl(member_node)); + astgen.globalVarDecl(gz, scope, &wip_decls, member_node, tree.localVarDecl(member_node)) catch |err| switch (err) { + error.OutOfMemory => return error.OutOfMemory, + error.AnalysisFail => {}, + }; continue; }, .simple_var_decl => { - try astgen.globalVarDecl(gz, scope, &wip_decls, member_node, tree.simpleVarDecl(member_node)); + astgen.globalVarDecl(gz, scope, &wip_decls, member_node, tree.simpleVarDecl(member_node)) catch |err| switch (err) { + error.OutOfMemory => return error.OutOfMemory, + error.AnalysisFail => {}, + }; continue; }, .aligned_var_decl => { - try astgen.globalVarDecl(gz, scope, &wip_decls, member_node, tree.alignedVarDecl(member_node)); + astgen.globalVarDecl(gz, scope, &wip_decls, member_node, tree.alignedVarDecl(member_node)) catch |err| switch (err) { + error.OutOfMemory => return error.OutOfMemory, + error.AnalysisFail => {}, + }; continue; }, .@"comptime" => { - try astgen.comptimeDecl(gz, scope, &wip_decls, member_node); + astgen.comptimeDecl(gz, scope, &wip_decls, member_node) catch |err| switch (err) { + error.OutOfMemory => return error.OutOfMemory, + error.AnalysisFail => {}, + }; continue; }, .@"usingnamespace" => { - try astgen.usingnamespaceDecl(gz, scope, &wip_decls, member_node); + astgen.usingnamespaceDecl(gz, scope, &wip_decls, member_node) catch |err| switch (err) { + error.OutOfMemory => return error.OutOfMemory, + error.AnalysisFail => {}, + }; continue; }, .test_decl => { - try astgen.testDecl(gz, scope, &wip_decls, member_node); + astgen.testDecl(gz, scope, &wip_decls, member_node) catch |err| switch (err) { + error.OutOfMemory => return error.OutOfMemory, + error.AnalysisFail => {}, + }; continue; }, else => unreachable, @@ -4044,20 +4179,32 @@ fn containerDecl( switch (node_tags[fn_proto]) { .fn_proto_simple => { var params: [1]ast.Node.Index = undefined; - try astgen.fnDecl(gz, &wip_decls, member_node, body, tree.fnProtoSimple(¶ms, fn_proto)); + astgen.fnDecl(gz, &wip_decls, member_node, body, tree.fnProtoSimple(¶ms, fn_proto)) catch |err| switch (err) { + error.OutOfMemory => return error.OutOfMemory, + error.AnalysisFail => {}, + }; continue; }, .fn_proto_multi => { - try astgen.fnDecl(gz, &wip_decls, member_node, body, tree.fnProtoMulti(fn_proto)); + astgen.fnDecl(gz, &wip_decls, member_node, body, tree.fnProtoMulti(fn_proto)) catch |err| switch (err) { + error.OutOfMemory => return error.OutOfMemory, + error.AnalysisFail => {}, + }; continue; }, .fn_proto_one => { var params: [1]ast.Node.Index = undefined; - try astgen.fnDecl(gz, &wip_decls, member_node, body, tree.fnProtoOne(¶ms, fn_proto)); + astgen.fnDecl(gz, &wip_decls, member_node, body, tree.fnProtoOne(¶ms, fn_proto)) catch |err| switch (err) { + error.OutOfMemory => return error.OutOfMemory, + error.AnalysisFail => {}, + }; continue; }, .fn_proto => { - try astgen.fnDecl(gz, &wip_decls, member_node, body, tree.fnProto(fn_proto)); + astgen.fnDecl(gz, &wip_decls, member_node, body, tree.fnProto(fn_proto)) catch |err| switch (err) { + error.OutOfMemory => return error.OutOfMemory, + error.AnalysisFail => {}, + }; continue; }, else => unreachable, @@ -4065,50 +4212,83 @@ fn containerDecl( }, .fn_proto_simple => { var params: [1]ast.Node.Index = undefined; - try astgen.fnDecl(gz, &wip_decls, member_node, 0, tree.fnProtoSimple(¶ms, member_node)); + astgen.fnDecl(gz, &wip_decls, member_node, 0, tree.fnProtoSimple(¶ms, member_node)) catch |err| switch (err) { + error.OutOfMemory => return error.OutOfMemory, + error.AnalysisFail => {}, + }; continue; }, .fn_proto_multi => { - try astgen.fnDecl(gz, &wip_decls, member_node, 0, tree.fnProtoMulti(member_node)); + astgen.fnDecl(gz, &wip_decls, member_node, 0, tree.fnProtoMulti(member_node)) catch |err| switch (err) { + error.OutOfMemory => return error.OutOfMemory, + error.AnalysisFail => {}, + }; continue; }, .fn_proto_one => { var params: [1]ast.Node.Index = undefined; - try astgen.fnDecl(gz, &wip_decls, member_node, 0, tree.fnProtoOne(¶ms, member_node)); + astgen.fnDecl(gz, &wip_decls, member_node, 0, tree.fnProtoOne(¶ms, member_node)) catch |err| switch (err) { + error.OutOfMemory => return error.OutOfMemory, + error.AnalysisFail => {}, + }; continue; }, .fn_proto => { - try astgen.fnDecl(gz, &wip_decls, member_node, 0, tree.fnProto(member_node)); + astgen.fnDecl(gz, &wip_decls, member_node, 0, tree.fnProto(member_node)) catch |err| switch (err) { + error.OutOfMemory => return error.OutOfMemory, + error.AnalysisFail => {}, + }; continue; }, .global_var_decl => { - try astgen.globalVarDecl(gz, scope, &wip_decls, member_node, tree.globalVarDecl(member_node)); + astgen.globalVarDecl(gz, scope, &wip_decls, member_node, tree.globalVarDecl(member_node)) catch |err| switch (err) { + error.OutOfMemory => return error.OutOfMemory, + error.AnalysisFail => {}, + }; continue; }, .local_var_decl => { - try astgen.globalVarDecl(gz, scope, &wip_decls, member_node, tree.localVarDecl(member_node)); + astgen.globalVarDecl(gz, scope, &wip_decls, member_node, tree.localVarDecl(member_node)) catch |err| switch (err) { + error.OutOfMemory => return error.OutOfMemory, + error.AnalysisFail => {}, + }; continue; }, .simple_var_decl => { - try astgen.globalVarDecl(gz, scope, &wip_decls, member_node, tree.simpleVarDecl(member_node)); + astgen.globalVarDecl(gz, scope, &wip_decls, member_node, tree.simpleVarDecl(member_node)) catch |err| switch (err) { + error.OutOfMemory => return error.OutOfMemory, + error.AnalysisFail => {}, + }; continue; }, .aligned_var_decl => { - try astgen.globalVarDecl(gz, scope, &wip_decls, member_node, tree.alignedVarDecl(member_node)); + astgen.globalVarDecl(gz, scope, &wip_decls, member_node, tree.alignedVarDecl(member_node)) catch |err| switch (err) { + error.OutOfMemory => return error.OutOfMemory, + error.AnalysisFail => {}, + }; continue; }, .@"comptime" => { - try astgen.comptimeDecl(gz, scope, &wip_decls, member_node); + astgen.comptimeDecl(gz, scope, &wip_decls, member_node) catch |err| switch (err) { + error.OutOfMemory => return error.OutOfMemory, + error.AnalysisFail => {}, + }; continue; }, .@"usingnamespace" => { - try astgen.usingnamespaceDecl(gz, scope, &wip_decls, member_node); + astgen.usingnamespaceDecl(gz, scope, &wip_decls, member_node) catch |err| switch (err) { + error.OutOfMemory => return error.OutOfMemory, + error.AnalysisFail => {}, + }; continue; }, .test_decl => { - try astgen.testDecl(gz, scope, &wip_decls, member_node); + astgen.testDecl(gz, scope, &wip_decls, member_node) catch |err| switch (err) { + error.OutOfMemory => return error.OutOfMemory, + error.AnalysisFail => {}, + }; continue; }, else => unreachable, diff --git a/src/Compilation.zig b/src/Compilation.zig index f75b3bc862..ac53abb127 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -1676,8 +1676,21 @@ pub fn totalErrorCount(self: *Compilation) usize { if (self.bin_file.options.module) |module| { total += module.failed_exports.items().len + - module.failed_files.items().len + @boolToInt(module.failed_root_src_file != null); + + for (module.failed_files.items()) |entry| { + if (entry.value) |_| { + total += 1; + } else { + const file = entry.key; + assert(file.zir_loaded); + const payload_index = file.zir.extra[@enumToInt(Zir.ExtraIndex.compile_errors)]; + assert(payload_index != 0); + const header = file.zir.extraData(Zir.Inst.CompileErrors, payload_index); + total += header.data.items_len; + } + } + // Skip errors for Decls within files that failed parsing. // When a parse error is introduced, we keep all the semantic analysis for // the previous parse success, including compile errors, but we cannot