| author | |
| committer | |
| log | 5acfaa35d3320c7595262b4d97ba4cdc3a1afc7b |
| tree | 9732cd04d10c68630cd1c3669cd793c3f7daf972 |
| parent | 4cc4b54d25bcd1c1f472518a182b94411fb8cec6 |
| parent | af80240678112276cedd5c5247b843fa101186b0 |
| signature |
stage2: compileError builtin for zig code5 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 | 2324 | return addZIRUnOp(mod, scope, src, .import, target); |
| 2325 | 2325 | } |
| 2326 | 2326 | |
| 2327 | fn 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 | ||
| 2327 | 2336 | fn compileLog(mod: *Module, scope: *Scope, call: *ast.Node.BuiltinCall) InnerError!*zir.Inst { |
| 2328 | 2337 | const tree = scope.tree(); |
| 2329 | 2338 | const arena = scope.arena(); |
| ... | ... | @@ -2378,6 +2387,8 @@ fn builtinCall(mod: *Module, scope: *Scope, rl: ResultLoc, call: *ast.Node.Built |
| 2378 | 2387 | return rlWrap(mod, scope, rl, try addZIRNoOp(mod, scope, src, .breakpoint)); |
| 2379 | 2388 | } else if (mem.eql(u8, builtin_name, "@import")) { |
| 2380 | 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 | 2392 | } else if (mem.eql(u8, builtin_name, "@compileLog")) { |
| 2382 | 2393 | return compileLog(mod, scope, call); |
| 2383 | 2394 | } else { |
src/zir.zig+55-20| ... | ... | @@ -300,6 +300,7 @@ pub const Inst = struct { |
| 300 | 300 | => NoOp, |
| 301 | 301 | |
| 302 | 302 | .boolnot, |
| 303 | .compileerror, | |
| 303 | 304 | .deref, |
| 304 | 305 | .@"return", |
| 305 | 306 | .isnull, |
| ... | ... | @@ -387,7 +388,6 @@ pub const Inst = struct { |
| 387 | 388 | .declval => DeclVal, |
| 388 | 389 | .declval_in_module => DeclValInModule, |
| 389 | 390 | .coerce_result_block_ptr => CoerceResultBlockPtr, |
| 390 | .compileerror => CompileError, | |
| 391 | 391 | .compilelog => CompileLog, |
| 392 | 392 | .loop => Loop, |
| 393 | 393 | .@"const" => Const, |
| ... | ... | @@ -701,16 +701,6 @@ pub const Inst = struct { |
| 701 | 701 | kw_args: struct {}, |
| 702 | 702 | }; |
| 703 | 703 | |
| 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 | 704 | pub const CompileLog = struct { |
| 715 | 705 | pub const base_tag = Tag.compilelog; |
| 716 | 706 | base: Inst, |
| ... | ... | @@ -1943,14 +1933,29 @@ const EmitZIR = struct { |
| 1943 | 1933 | .sema_failure_retryable, |
| 1944 | 1934 | .dependency_failure, |
| 1945 | 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 | 1937 | fail_inst.* = .{ |
| 1948 | 1938 | .base = .{ |
| 1949 | 1939 | .src = ir_decl.src(), |
| 1950 | .tag = Inst.CompileError.base_tag, | |
| 1940 | .tag = .compileerror, | |
| 1951 | 1941 | }, |
| 1952 | 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 | 1960 | .kw_args = .{}, |
| 1956 | 1961 | }; |
| ... | ... | @@ -2073,28 +2078,58 @@ const EmitZIR = struct { |
| 2073 | 2078 | }, |
| 2074 | 2079 | .sema_failure => { |
| 2075 | 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 | 2082 | fail_inst.* = .{ |
| 2078 | 2083 | .base = .{ |
| 2079 | 2084 | .src = src, |
| 2080 | .tag = Inst.CompileError.base_tag, | |
| 2085 | .tag = .compileerror, | |
| 2081 | 2086 | }, |
| 2082 | 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 | 2105 | .kw_args = .{}, |
| 2086 | 2106 | }; |
| 2087 | 2107 | try instructions.append(&fail_inst.base); |
| 2088 | 2108 | }, |
| 2089 | 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 | 2111 | fail_inst.* = .{ |
| 2092 | 2112 | .base = .{ |
| 2093 | 2113 | .src = src, |
| 2094 | .tag = Inst.CompileError.base_tag, | |
| 2114 | .tag = .compileerror, | |
| 2095 | 2115 | }, |
| 2096 | 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 | 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 | 486 | return mod.constVoid(scope, export_inst.base.src); |
| 487 | 487 | } |
| 488 | 488 | |
| 489 | fn analyzeInstCompileError(mod: *Module, scope: *Scope, inst: *zir.Inst.CompileError) InnerError!*Inst { | |
| 490 | return mod.fail(scope, inst.base.src, "{}", .{inst.positionals.msg}); | |
| 489 | fn analyzeInstCompileError(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp) InnerError!*Inst { | |
| 490 | const msg = try resolveConstString(mod, scope, inst.positionals.operand); | |
| 491 | return mod.fail(scope, inst.base.src, "{}", .{msg}); | |
| 491 | 492 | } |
| 492 | 493 | |
| 493 | 494 | fn 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 | 1186 | |
| 1187 | 1187 | // "| true, 20, (runtime value), (function)" // TODO if this is here it invalidates the compile error checker. Need a way to check though. |
| 1188 | 1188 | |
| 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 | 1196 | var case = ctx.obj("variable shadowing", linux_x64); |
| 1191 | 1197 | case.addError( |
test/stage2/zir.zig+13-9| ... | ... | @@ -150,18 +150,20 @@ pub fn addCases(ctx: *TestContext) !void { |
| 150 | 150 | \\}) |
| 151 | 151 | \\ |
| 152 | 152 | \\@a = fn(@fnty, { |
| 153 | \\ %0 = call(@b, []) | |
| 153 | \\ %0 = call(@c, []) | |
| 154 | 154 | \\ %1 = returnvoid() |
| 155 | 155 | \\}) |
| 156 | 156 | \\ |
| 157 | \\@b = fn(@fnty, { | |
| 158 | \\ %9 = compileerror("message") | |
| 157 | \\@b = str("message") | |
| 158 | \\ | |
| 159 | \\@c = fn(@fnty, { | |
| 160 | \\ %9 = compileerror(@b) | |
| 159 | 161 | \\ %0 = call(@a, []) |
| 160 | 162 | \\ %1 = returnvoid() |
| 161 | 163 | \\}) |
| 162 | 164 | , |
| 163 | 165 | &[_][]const u8{ |
| 164 | ":18:21: error: message", | |
| 166 | ":20:21: error: message", | |
| 165 | 167 | }, |
| 166 | 168 | ); |
| 167 | 169 | // 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 | 181 | \\}) |
| 180 | 182 | \\ |
| 181 | 183 | \\@a = fn(@fnty, { |
| 182 | \\ %0 = call(@b, []) | |
| 184 | \\ %0 = call(@c, []) | |
| 183 | 185 | \\ %1 = returnvoid() |
| 184 | 186 | \\}) |
| 185 | 187 | \\ |
| 186 | \\@b = fn(@fnty, { | |
| 187 | \\ %9 = compileerror("message") | |
| 188 | \\@b = str("message") | |
| 189 | \\ | |
| 190 | \\@c = fn(@fnty, { | |
| 191 | \\ %9 = compileerror(@b) | |
| 188 | 192 | \\ %0 = call(@a, []) |
| 189 | 193 | \\ %1 = returnvoid() |
| 190 | 194 | \\}) |
| 191 | 195 | , |
| 192 | 196 | \\@void = primitive(void) |
| 193 | 197 | \\@fnty = fntype([], @void, cc=C) |
| 194 | \\@9 = declref("9__anon_2") | |
| 195 | \\@9__anon_2 = str("entry") | |
| 198 | \\@9 = declref("9__anon_3") | |
| 199 | \\@9__anon_3 = str("entry") | |
| 196 | 200 | \\@unnamed$4 = str("entry") |
| 197 | 201 | \\@unnamed$5 = export(@unnamed$4, "entry") |
| 198 | 202 | \\@11 = primitive(void_value) |