mirror of
https://github.com/ziglang/zig.git
synced 2026-02-21 16:54:52 +00:00
Merge pull request #7557 from g-w1/stage2-hookup-compilerror
stage2: compileError builtin for zig code
This commit is contained in:
commit
5acfaa35d3
@ -2324,6 +2324,15 @@ fn import(mod: *Module, scope: *Scope, call: *ast.Node.BuiltinCall) InnerError!*
|
||||
return addZIRUnOp(mod, scope, src, .import, target);
|
||||
}
|
||||
|
||||
fn compileError(mod: *Module, scope: *Scope, call: *ast.Node.BuiltinCall) InnerError!*zir.Inst {
|
||||
try ensureBuiltinParamCount(mod, scope, call, 1);
|
||||
const tree = scope.tree();
|
||||
const src = tree.token_locs[call.builtin_token].start;
|
||||
const params = call.params();
|
||||
const target = try expr(mod, scope, .none, params[0]);
|
||||
return addZIRUnOp(mod, scope, src, .compileerror, target);
|
||||
}
|
||||
|
||||
fn compileLog(mod: *Module, scope: *Scope, call: *ast.Node.BuiltinCall) InnerError!*zir.Inst {
|
||||
const tree = scope.tree();
|
||||
const arena = scope.arena();
|
||||
@ -2378,6 +2387,8 @@ fn builtinCall(mod: *Module, scope: *Scope, rl: ResultLoc, call: *ast.Node.Built
|
||||
return rlWrap(mod, scope, rl, try addZIRNoOp(mod, scope, src, .breakpoint));
|
||||
} else if (mem.eql(u8, builtin_name, "@import")) {
|
||||
return rlWrap(mod, scope, rl, try import(mod, scope, call));
|
||||
} else if (mem.eql(u8, builtin_name, "@compileError")) {
|
||||
return compileError(mod, scope, call);
|
||||
} else if (mem.eql(u8, builtin_name, "@compileLog")) {
|
||||
return compileLog(mod, scope, call);
|
||||
} else {
|
||||
|
||||
75
src/zir.zig
75
src/zir.zig
@ -300,6 +300,7 @@ pub const Inst = struct {
|
||||
=> NoOp,
|
||||
|
||||
.boolnot,
|
||||
.compileerror,
|
||||
.deref,
|
||||
.@"return",
|
||||
.isnull,
|
||||
@ -387,7 +388,6 @@ pub const Inst = struct {
|
||||
.declval => DeclVal,
|
||||
.declval_in_module => DeclValInModule,
|
||||
.coerce_result_block_ptr => CoerceResultBlockPtr,
|
||||
.compileerror => CompileError,
|
||||
.compilelog => CompileLog,
|
||||
.loop => Loop,
|
||||
.@"const" => Const,
|
||||
@ -701,16 +701,6 @@ pub const Inst = struct {
|
||||
kw_args: struct {},
|
||||
};
|
||||
|
||||
pub const CompileError = struct {
|
||||
pub const base_tag = Tag.compileerror;
|
||||
base: Inst,
|
||||
|
||||
positionals: struct {
|
||||
msg: []const u8,
|
||||
},
|
||||
kw_args: struct {},
|
||||
};
|
||||
|
||||
pub const CompileLog = struct {
|
||||
pub const base_tag = Tag.compilelog;
|
||||
base: Inst,
|
||||
@ -1943,14 +1933,29 @@ const EmitZIR = struct {
|
||||
.sema_failure_retryable,
|
||||
.dependency_failure,
|
||||
=> if (self.old_module.failed_decls.get(ir_decl)) |err_msg_list| {
|
||||
const fail_inst = try self.arena.allocator.create(Inst.CompileError);
|
||||
const fail_inst = try self.arena.allocator.create(Inst.UnOp);
|
||||
fail_inst.* = .{
|
||||
.base = .{
|
||||
.src = ir_decl.src(),
|
||||
.tag = Inst.CompileError.base_tag,
|
||||
.tag = .compileerror,
|
||||
},
|
||||
.positionals = .{
|
||||
.msg = try self.arena.allocator.dupe(u8, err_msg_list.items[0].msg),
|
||||
.operand = blk: {
|
||||
const msg_str = try self.arena.allocator.dupe(u8, err_msg_list.items[0].msg);
|
||||
|
||||
const str_inst = try self.arena.allocator.create(Inst.Str);
|
||||
str_inst.* = .{
|
||||
.base = .{
|
||||
.src = ir_decl.src(),
|
||||
.tag = Inst.Str.base_tag,
|
||||
},
|
||||
.positionals = .{
|
||||
.bytes = msg_str,
|
||||
},
|
||||
.kw_args = .{},
|
||||
};
|
||||
break :blk &str_inst.base;
|
||||
},
|
||||
},
|
||||
.kw_args = .{},
|
||||
};
|
||||
@ -2073,28 +2078,58 @@ const EmitZIR = struct {
|
||||
},
|
||||
.sema_failure => {
|
||||
const err_msg = self.old_module.failed_decls.get(module_fn.owner_decl).?.items[0];
|
||||
const fail_inst = try self.arena.allocator.create(Inst.CompileError);
|
||||
const fail_inst = try self.arena.allocator.create(Inst.UnOp);
|
||||
fail_inst.* = .{
|
||||
.base = .{
|
||||
.src = src,
|
||||
.tag = Inst.CompileError.base_tag,
|
||||
.tag = .compileerror,
|
||||
},
|
||||
.positionals = .{
|
||||
.msg = try self.arena.allocator.dupe(u8, err_msg.msg),
|
||||
.operand = blk: {
|
||||
const msg_str = try self.arena.allocator.dupe(u8, err_msg.msg);
|
||||
|
||||
const str_inst = try self.arena.allocator.create(Inst.Str);
|
||||
str_inst.* = .{
|
||||
.base = .{
|
||||
.src = src,
|
||||
.tag = Inst.Str.base_tag,
|
||||
},
|
||||
.positionals = .{
|
||||
.bytes = msg_str,
|
||||
},
|
||||
.kw_args = .{},
|
||||
};
|
||||
break :blk &str_inst.base;
|
||||
},
|
||||
},
|
||||
.kw_args = .{},
|
||||
};
|
||||
try instructions.append(&fail_inst.base);
|
||||
},
|
||||
.dependency_failure => {
|
||||
const fail_inst = try self.arena.allocator.create(Inst.CompileError);
|
||||
const fail_inst = try self.arena.allocator.create(Inst.UnOp);
|
||||
fail_inst.* = .{
|
||||
.base = .{
|
||||
.src = src,
|
||||
.tag = Inst.CompileError.base_tag,
|
||||
.tag = .compileerror,
|
||||
},
|
||||
.positionals = .{
|
||||
.msg = try self.arena.allocator.dupe(u8, "depends on another failed Decl"),
|
||||
.operand = blk: {
|
||||
const msg_str = try self.arena.allocator.dupe(u8, "depends on another failed Decl");
|
||||
|
||||
const str_inst = try self.arena.allocator.create(Inst.Str);
|
||||
str_inst.* = .{
|
||||
.base = .{
|
||||
.src = src,
|
||||
.tag = Inst.Str.base_tag,
|
||||
},
|
||||
.positionals = .{
|
||||
.bytes = msg_str,
|
||||
},
|
||||
.kw_args = .{},
|
||||
};
|
||||
break :blk &str_inst.base;
|
||||
},
|
||||
},
|
||||
.kw_args = .{},
|
||||
};
|
||||
|
||||
@ -486,8 +486,9 @@ fn analyzeInstExport(mod: *Module, scope: *Scope, export_inst: *zir.Inst.Export)
|
||||
return mod.constVoid(scope, export_inst.base.src);
|
||||
}
|
||||
|
||||
fn analyzeInstCompileError(mod: *Module, scope: *Scope, inst: *zir.Inst.CompileError) InnerError!*Inst {
|
||||
return mod.fail(scope, inst.base.src, "{}", .{inst.positionals.msg});
|
||||
fn analyzeInstCompileError(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp) InnerError!*Inst {
|
||||
const msg = try resolveConstString(mod, scope, inst.positionals.operand);
|
||||
return mod.fail(scope, inst.base.src, "{}", .{msg});
|
||||
}
|
||||
|
||||
fn analyzeInstCompileLog(mod: *Module, scope: *Scope, inst: *zir.Inst.CompileLog) InnerError!*Inst {
|
||||
|
||||
@ -1186,6 +1186,12 @@ pub fn addCases(ctx: *TestContext) !void {
|
||||
|
||||
// "| true, 20, (runtime value), (function)" // TODO if this is here it invalidates the compile error checker. Need a way to check though.
|
||||
|
||||
ctx.compileError("compileError", linux_x64,
|
||||
\\export fn _start() noreturn {
|
||||
\\ @compileError("this is an error");
|
||||
\\ unreachable;
|
||||
\\}
|
||||
, &[_][]const u8{":2:3: error: this is an error"});
|
||||
{
|
||||
var case = ctx.obj("variable shadowing", linux_x64);
|
||||
case.addError(
|
||||
|
||||
@ -150,18 +150,20 @@ pub fn addCases(ctx: *TestContext) !void {
|
||||
\\})
|
||||
\\
|
||||
\\@a = fn(@fnty, {
|
||||
\\ %0 = call(@b, [])
|
||||
\\ %0 = call(@c, [])
|
||||
\\ %1 = returnvoid()
|
||||
\\})
|
||||
\\
|
||||
\\@b = fn(@fnty, {
|
||||
\\ %9 = compileerror("message")
|
||||
\\@b = str("message")
|
||||
\\
|
||||
\\@c = fn(@fnty, {
|
||||
\\ %9 = compileerror(@b)
|
||||
\\ %0 = call(@a, [])
|
||||
\\ %1 = returnvoid()
|
||||
\\})
|
||||
,
|
||||
&[_][]const u8{
|
||||
":18:21: error: message",
|
||||
":20:21: error: message",
|
||||
},
|
||||
);
|
||||
// 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 {
|
||||
\\})
|
||||
\\
|
||||
\\@a = fn(@fnty, {
|
||||
\\ %0 = call(@b, [])
|
||||
\\ %0 = call(@c, [])
|
||||
\\ %1 = returnvoid()
|
||||
\\})
|
||||
\\
|
||||
\\@b = fn(@fnty, {
|
||||
\\ %9 = compileerror("message")
|
||||
\\@b = str("message")
|
||||
\\
|
||||
\\@c = fn(@fnty, {
|
||||
\\ %9 = compileerror(@b)
|
||||
\\ %0 = call(@a, [])
|
||||
\\ %1 = returnvoid()
|
||||
\\})
|
||||
,
|
||||
\\@void = primitive(void)
|
||||
\\@fnty = fntype([], @void, cc=C)
|
||||
\\@9 = declref("9__anon_2")
|
||||
\\@9__anon_2 = str("entry")
|
||||
\\@9 = declref("9__anon_3")
|
||||
\\@9__anon_3 = str("entry")
|
||||
\\@unnamed$4 = str("entry")
|
||||
\\@unnamed$5 = export(@unnamed$4, "entry")
|
||||
\\@11 = primitive(void_value)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user