authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-12-28 00:54:44+02:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2020-12-28 00:54:44+02:00
log5acfaa35d3320c7595262b4d97ba4cdc3a1afc7b
tree9732cd04d10c68630cd1c3669cd793c3f7daf972
parent4cc4b54d25bcd1c1f472518a182b94411fb8cec6
parentaf80240678112276cedd5c5247b843fa101186b0
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #7557 from g-w1/stage2-hookup-compilerror

stage2: compileError builtin for zig code

5 files changed, 88 insertions(+), 31 deletions(-)

src/astgen.zig+11
...@@ -2324,6 +2324,15 @@ fn import(mod: *Module, scope: *Scope, call: *ast.Node.BuiltinCall) InnerError!*...@@ -2324,6 +2324,15 @@ fn import(mod: *Module, scope: *Scope, call: *ast.Node.BuiltinCall) InnerError!*
2324 return addZIRUnOp(mod, scope, src, .import, target);2324 return addZIRUnOp(mod, scope, src, .import, target);
2325}2325}
23262326
2327fn compileError(mod: *Module, scope: *Scope, call: *ast.Node.BuiltinCall) InnerError!*zir.Inst {
2328 try ensureBuiltinParamCount(mod, scope, call, 1);
2329 const tree = scope.tree();
2330 const src = tree.token_locs[call.builtin_token].start;
2331 const params = call.params();
2332 const target = try expr(mod, scope, .none, params[0]);
2333 return addZIRUnOp(mod, scope, src, .compileerror, target);
2334}
2335
2327fn compileLog(mod: *Module, scope: *Scope, call: *ast.Node.BuiltinCall) InnerError!*zir.Inst {2336fn compileLog(mod: *Module, scope: *Scope, call: *ast.Node.BuiltinCall) InnerError!*zir.Inst {
2328 const tree = scope.tree();2337 const tree = scope.tree();
2329 const arena = scope.arena();2338 const arena = scope.arena();
...@@ -2378,6 +2387,8 @@ fn builtinCall(mod: *Module, scope: *Scope, rl: ResultLoc, call: *ast.Node.Built...@@ -2378,6 +2387,8 @@ fn builtinCall(mod: *Module, scope: *Scope, rl: ResultLoc, call: *ast.Node.Built
2378 return rlWrap(mod, scope, rl, try addZIRNoOp(mod, scope, src, .breakpoint));2387 return rlWrap(mod, scope, rl, try addZIRNoOp(mod, scope, src, .breakpoint));
2379 } else if (mem.eql(u8, builtin_name, "@import")) {2388 } else if (mem.eql(u8, builtin_name, "@import")) {
2380 return rlWrap(mod, scope, rl, try import(mod, scope, call));2389 return rlWrap(mod, scope, rl, try import(mod, scope, call));
2390 } else if (mem.eql(u8, builtin_name, "@compileError")) {
2391 return compileError(mod, scope, call);
2381 } else if (mem.eql(u8, builtin_name, "@compileLog")) {2392 } else if (mem.eql(u8, builtin_name, "@compileLog")) {
2382 return compileLog(mod, scope, call);2393 return compileLog(mod, scope, call);
2383 } else {2394 } else {
src/zir.zig+55-20
...@@ -300,6 +300,7 @@ pub const Inst = struct {...@@ -300,6 +300,7 @@ pub const Inst = struct {
300 => NoOp,300 => NoOp,
301301
302 .boolnot,302 .boolnot,
303 .compileerror,
303 .deref,304 .deref,
304 .@"return",305 .@"return",
305 .isnull,306 .isnull,
...@@ -387,7 +388,6 @@ pub const Inst = struct {...@@ -387,7 +388,6 @@ pub const Inst = struct {
387 .declval => DeclVal,388 .declval => DeclVal,
388 .declval_in_module => DeclValInModule,389 .declval_in_module => DeclValInModule,
389 .coerce_result_block_ptr => CoerceResultBlockPtr,390 .coerce_result_block_ptr => CoerceResultBlockPtr,
390 .compileerror => CompileError,
391 .compilelog => CompileLog,391 .compilelog => CompileLog,
392 .loop => Loop,392 .loop => Loop,
393 .@"const" => Const,393 .@"const" => Const,
...@@ -701,16 +701,6 @@ pub const Inst = struct {...@@ -701,16 +701,6 @@ pub const Inst = struct {
701 kw_args: struct {},701 kw_args: struct {},
702 };702 };
703703
704 pub const CompileError = struct {
705 pub const base_tag = Tag.compileerror;
706 base: Inst,
707
708 positionals: struct {
709 msg: []const u8,
710 },
711 kw_args: struct {},
712 };
713
714 pub const CompileLog = struct {704 pub const CompileLog = struct {
715 pub const base_tag = Tag.compilelog;705 pub const base_tag = Tag.compilelog;
716 base: Inst,706 base: Inst,
...@@ -1943,14 +1933,29 @@ const EmitZIR = struct {...@@ -1943,14 +1933,29 @@ const EmitZIR = struct {
1943 .sema_failure_retryable,1933 .sema_failure_retryable,
1944 .dependency_failure,1934 .dependency_failure,
1945 => if (self.old_module.failed_decls.get(ir_decl)) |err_msg_list| {1935 => if (self.old_module.failed_decls.get(ir_decl)) |err_msg_list| {
1946 const fail_inst = try self.arena.allocator.create(Inst.CompileError);1936 const fail_inst = try self.arena.allocator.create(Inst.UnOp);
1947 fail_inst.* = .{1937 fail_inst.* = .{
1948 .base = .{1938 .base = .{
1949 .src = ir_decl.src(),1939 .src = ir_decl.src(),
1950 .tag = Inst.CompileError.base_tag,1940 .tag = .compileerror,
1951 },1941 },
1952 .positionals = .{1942 .positionals = .{
1953 .msg = try self.arena.allocator.dupe(u8, err_msg_list.items[0].msg),1943 .operand = blk: {
1944 const msg_str = try self.arena.allocator.dupe(u8, err_msg_list.items[0].msg);
1945
1946 const str_inst = try self.arena.allocator.create(Inst.Str);
1947 str_inst.* = .{
1948 .base = .{
1949 .src = ir_decl.src(),
1950 .tag = Inst.Str.base_tag,
1951 },
1952 .positionals = .{
1953 .bytes = msg_str,
1954 },
1955 .kw_args = .{},
1956 };
1957 break :blk &str_inst.base;
1958 },
1954 },1959 },
1955 .kw_args = .{},1960 .kw_args = .{},
1956 };1961 };
...@@ -2073,28 +2078,58 @@ const EmitZIR = struct {...@@ -2073,28 +2078,58 @@ const EmitZIR = struct {
2073 },2078 },
2074 .sema_failure => {2079 .sema_failure => {
2075 const err_msg = self.old_module.failed_decls.get(module_fn.owner_decl).?.items[0];2080 const err_msg = self.old_module.failed_decls.get(module_fn.owner_decl).?.items[0];
2076 const fail_inst = try self.arena.allocator.create(Inst.CompileError);2081 const fail_inst = try self.arena.allocator.create(Inst.UnOp);
2077 fail_inst.* = .{2082 fail_inst.* = .{
2078 .base = .{2083 .base = .{
2079 .src = src,2084 .src = src,
2080 .tag = Inst.CompileError.base_tag,2085 .tag = .compileerror,
2081 },2086 },
2082 .positionals = .{2087 .positionals = .{
2083 .msg = try self.arena.allocator.dupe(u8, err_msg.msg),2088 .operand = blk: {
2089 const msg_str = try self.arena.allocator.dupe(u8, err_msg.msg);
2090
2091 const str_inst = try self.arena.allocator.create(Inst.Str);
2092 str_inst.* = .{
2093 .base = .{
2094 .src = src,
2095 .tag = Inst.Str.base_tag,
2096 },
2097 .positionals = .{
2098 .bytes = msg_str,
2099 },
2100 .kw_args = .{},
2101 };
2102 break :blk &str_inst.base;
2103 },
2084 },2104 },
2085 .kw_args = .{},2105 .kw_args = .{},
2086 };2106 };
2087 try instructions.append(&fail_inst.base);2107 try instructions.append(&fail_inst.base);
2088 },2108 },
2089 .dependency_failure => {2109 .dependency_failure => {
2090 const fail_inst = try self.arena.allocator.create(Inst.CompileError);2110 const fail_inst = try self.arena.allocator.create(Inst.UnOp);
2091 fail_inst.* = .{2111 fail_inst.* = .{
2092 .base = .{2112 .base = .{
2093 .src = src,2113 .src = src,
2094 .tag = Inst.CompileError.base_tag,2114 .tag = .compileerror,
2095 },2115 },
2096 .positionals = .{2116 .positionals = .{
2097 .msg = try self.arena.allocator.dupe(u8, "depends on another failed Decl"),2117 .operand = blk: {
2118 const msg_str = try self.arena.allocator.dupe(u8, "depends on another failed Decl");
2119
2120 const str_inst = try self.arena.allocator.create(Inst.Str);
2121 str_inst.* = .{
2122 .base = .{
2123 .src = src,
2124 .tag = Inst.Str.base_tag,
2125 },
2126 .positionals = .{
2127 .bytes = msg_str,
2128 },
2129 .kw_args = .{},
2130 };
2131 break :blk &str_inst.base;
2132 },
2098 },2133 },
2099 .kw_args = .{},2134 .kw_args = .{},
2100 };2135 };
src/zir_sema.zig+3-2
...@@ -486,8 +486,9 @@ fn analyzeInstExport(mod: *Module, scope: *Scope, export_inst: *zir.Inst.Export)...@@ -486,8 +486,9 @@ fn analyzeInstExport(mod: *Module, scope: *Scope, export_inst: *zir.Inst.Export)
486 return mod.constVoid(scope, export_inst.base.src);486 return mod.constVoid(scope, export_inst.base.src);
487}487}
488488
489fn analyzeInstCompileError(mod: *Module, scope: *Scope, inst: *zir.Inst.CompileError) InnerError!*Inst {489fn analyzeInstCompileError(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp) InnerError!*Inst {
490 return mod.fail(scope, inst.base.src, "{}", .{inst.positionals.msg});490 const msg = try resolveConstString(mod, scope, inst.positionals.operand);
491 return mod.fail(scope, inst.base.src, "{}", .{msg});
491}492}
492493
493fn analyzeInstCompileLog(mod: *Module, scope: *Scope, inst: *zir.Inst.CompileLog) InnerError!*Inst {494fn analyzeInstCompileLog(mod: *Module, scope: *Scope, inst: *zir.Inst.CompileLog) InnerError!*Inst {
test/stage2/test.zig+6
...@@ -1186,6 +1186,12 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -1186,6 +1186,12 @@ pub fn addCases(ctx: *TestContext) !void {
11861186
1187 // "| true, 20, (runtime value), (function)" // TODO if this is here it invalidates the compile error checker. Need a way to check though.1187 // "| true, 20, (runtime value), (function)" // TODO if this is here it invalidates the compile error checker. Need a way to check though.
11881188
1189 ctx.compileError("compileError", linux_x64,
1190 \\export fn _start() noreturn {
1191 \\ @compileError("this is an error");
1192 \\ unreachable;
1193 \\}
1194 , &[_][]const u8{":2:3: error: this is an error"});
1189 {1195 {
1190 var case = ctx.obj("variable shadowing", linux_x64);1196 var case = ctx.obj("variable shadowing", linux_x64);
1191 case.addError(1197 case.addError(
test/stage2/zir.zig+13-9
...@@ -150,18 +150,20 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -150,18 +150,20 @@ pub fn addCases(ctx: *TestContext) !void {
150 \\})150 \\})
151 \\151 \\
152 \\@a = fn(@fnty, {152 \\@a = fn(@fnty, {
153 \\ %0 = call(@b, [])153 \\ %0 = call(@c, [])
154 \\ %1 = returnvoid()154 \\ %1 = returnvoid()
155 \\})155 \\})
156 \\156 \\
157 \\@b = fn(@fnty, {157 \\@b = str("message")
158 \\ %9 = compileerror("message")158 \\
159 \\@c = fn(@fnty, {
160 \\ %9 = compileerror(@b)
159 \\ %0 = call(@a, [])161 \\ %0 = call(@a, [])
160 \\ %1 = returnvoid()162 \\ %1 = returnvoid()
161 \\})163 \\})
162 ,164 ,
163 &[_][]const u8{165 &[_][]const u8{
164 ":18:21: error: message",166 ":20:21: error: message",
165 },167 },
166 );168 );
167 // Now we remove the call to `a`. `a` and `b` form a cycle, but no entry points are169 // Now we remove the call to `a`. `a` and `b` form a cycle, but no entry points are
...@@ -179,20 +181,22 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -179,20 +181,22 @@ pub fn addCases(ctx: *TestContext) !void {
179 \\})181 \\})
180 \\182 \\
181 \\@a = fn(@fnty, {183 \\@a = fn(@fnty, {
182 \\ %0 = call(@b, [])184 \\ %0 = call(@c, [])
183 \\ %1 = returnvoid()185 \\ %1 = returnvoid()
184 \\})186 \\})
185 \\187 \\
186 \\@b = fn(@fnty, {188 \\@b = str("message")
187 \\ %9 = compileerror("message")189 \\
190 \\@c = fn(@fnty, {
191 \\ %9 = compileerror(@b)
188 \\ %0 = call(@a, [])192 \\ %0 = call(@a, [])
189 \\ %1 = returnvoid()193 \\ %1 = returnvoid()
190 \\})194 \\})
191 ,195 ,
192 \\@void = primitive(void)196 \\@void = primitive(void)
193 \\@fnty = fntype([], @void, cc=C)197 \\@fnty = fntype([], @void, cc=C)
194 \\@9 = declref("9__anon_2")198 \\@9 = declref("9__anon_3")
195 \\@9__anon_2 = str("entry")199 \\@9__anon_3 = str("entry")
196 \\@unnamed$4 = str("entry")200 \\@unnamed$4 = str("entry")
197 \\@unnamed$5 = export(@unnamed$4, "entry")201 \\@unnamed$5 = export(@unnamed$4, "entry")
198 \\@11 = primitive(void_value)202 \\@11 = primitive(void_value)