mirror of
https://github.com/ziglang/zig.git
synced 2025-12-06 14:23:09 +00:00
stage2: astgen for if and while with error unions
This commit is contained in:
parent
db77b6b4e7
commit
ece4a2fc51
@ -614,11 +614,16 @@ const CondKind = union(enum) {
|
|||||||
const result = try addZIRUnOp(mod, &block_scope.base, src, .deref, cond_ptr);
|
const result = try addZIRUnOp(mod, &block_scope.base, src, .deref, cond_ptr);
|
||||||
return try addZIRUnOp(mod, &block_scope.base, src, .isnonnull, result);
|
return try addZIRUnOp(mod, &block_scope.base, src, .isnonnull, result);
|
||||||
},
|
},
|
||||||
.err_union => unreachable,
|
.err_union => {
|
||||||
|
const err_ptr = try expr(mod, &block_scope.base, .lvalue, cond_node);
|
||||||
|
self.* = .{ .err_union = err_ptr };
|
||||||
|
const result = try addZIRUnOp(mod, &block_scope.base, src, .deref, err_ptr);
|
||||||
|
return try addZIRUnOp(mod, &block_scope.base, src, .iserr, result);
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn thenSubScope(self: CondKind, mod: *Module, then_scope: *Scope.GenZIR, payload_node: ?*ast.Node) !*Scope {
|
fn thenSubScope(self: CondKind, mod: *Module, then_scope: *Scope.GenZIR, src: usize, payload_node: ?*ast.Node) !*Scope {
|
||||||
if (self == .bool) return &then_scope.base;
|
if (self == .bool) return &then_scope.base;
|
||||||
|
|
||||||
const payload = payload_node.?.castTag(.PointerPayload).?;
|
const payload = payload_node.?.castTag(.PointerPayload).?;
|
||||||
@ -633,6 +638,21 @@ const CondKind = union(enum) {
|
|||||||
|
|
||||||
return mod.failNode(&then_scope.base, payload.value_symbol, "TODO implement payload symbols", .{});
|
return mod.failNode(&then_scope.base, payload.value_symbol, "TODO implement payload symbols", .{});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn elseSubScope(self: CondKind, mod: *Module, else_scope: *Scope.GenZIR, src: usize, payload_node: ?*ast.Node) !*Scope {
|
||||||
|
if (self != .err_union) return &else_scope.base;
|
||||||
|
|
||||||
|
const payload_ptr = try addZIRUnOp(mod, &else_scope.base, src, .unwrap_err_unsafe, self.err_union.?);
|
||||||
|
|
||||||
|
const payload = payload_node.?.castTag(.Payload).?;
|
||||||
|
const ident_node = payload.error_symbol.castTag(.Identifier).?;
|
||||||
|
const ident_name = try identifierTokenString(mod, &else_scope.base, ident_node.token);
|
||||||
|
if (mem.eql(u8, ident_name, "_")) {
|
||||||
|
return &else_scope.base;
|
||||||
|
}
|
||||||
|
|
||||||
|
return mod.failNode(&else_scope.base, payload.error_symbol, "TODO implement payload symbols", .{});
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
fn ifExpr(mod: *Module, scope: *Scope, rl: ResultLoc, if_node: *ast.Node.If) InnerError!*zir.Inst {
|
fn ifExpr(mod: *Module, scope: *Scope, rl: ResultLoc, if_node: *ast.Node.If) InnerError!*zir.Inst {
|
||||||
@ -643,7 +663,7 @@ fn ifExpr(mod: *Module, scope: *Scope, rl: ResultLoc, if_node: *ast.Node.If) Inn
|
|||||||
if (cond_kind != .optional) {
|
if (cond_kind != .optional) {
|
||||||
return mod.failNode(scope, payload, "else payload invalid on bool conditions", .{});
|
return mod.failNode(scope, payload, "else payload invalid on bool conditions", .{});
|
||||||
}
|
}
|
||||||
return mod.failNode(scope, payload, "TODO implement astgen.IfExpr for error unions", .{});
|
cond_kind = .{ .err_union = null };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var block_scope: Scope.GenZIR = .{
|
var block_scope: Scope.GenZIR = .{
|
||||||
@ -667,6 +687,8 @@ fn ifExpr(mod: *Module, scope: *Scope, rl: ResultLoc, if_node: *ast.Node.If) Inn
|
|||||||
const block = try addZIRInstBlock(mod, scope, if_src, .{
|
const block = try addZIRInstBlock(mod, scope, if_src, .{
|
||||||
.instructions = try block_scope.arena.dupe(*zir.Inst, block_scope.instructions.items),
|
.instructions = try block_scope.arena.dupe(*zir.Inst, block_scope.instructions.items),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const then_src = tree.token_locs[if_node.body.lastToken()].start;
|
||||||
var then_scope: Scope.GenZIR = .{
|
var then_scope: Scope.GenZIR = .{
|
||||||
.parent = scope,
|
.parent = scope,
|
||||||
.decl = block_scope.decl,
|
.decl = block_scope.decl,
|
||||||
@ -676,7 +698,7 @@ fn ifExpr(mod: *Module, scope: *Scope, rl: ResultLoc, if_node: *ast.Node.If) Inn
|
|||||||
defer then_scope.instructions.deinit(mod.gpa);
|
defer then_scope.instructions.deinit(mod.gpa);
|
||||||
|
|
||||||
// declare payload to the then_scope
|
// declare payload to the then_scope
|
||||||
const then_sub_scope = try cond_kind.thenSubScope(mod, &then_scope, if_node.payload);
|
const then_sub_scope = try cond_kind.thenSubScope(mod, &then_scope, then_src, if_node.payload);
|
||||||
|
|
||||||
// Most result location types can be forwarded directly; however
|
// Most result location types can be forwarded directly; however
|
||||||
// if we need to write to a pointer which has an inferred type,
|
// if we need to write to a pointer which has an inferred type,
|
||||||
@ -689,7 +711,6 @@ fn ifExpr(mod: *Module, scope: *Scope, rl: ResultLoc, if_node: *ast.Node.If) Inn
|
|||||||
|
|
||||||
const then_result = try expr(mod, then_sub_scope, branch_rl, if_node.body);
|
const then_result = try expr(mod, then_sub_scope, branch_rl, if_node.body);
|
||||||
if (!then_result.tag.isNoReturn()) {
|
if (!then_result.tag.isNoReturn()) {
|
||||||
const then_src = tree.token_locs[if_node.body.lastToken()].start;
|
|
||||||
_ = try addZIRInst(mod, then_sub_scope, then_src, zir.Inst.Break, .{
|
_ = try addZIRInst(mod, then_sub_scope, then_src, zir.Inst.Break, .{
|
||||||
.block = block,
|
.block = block,
|
||||||
.operand = then_result,
|
.operand = then_result,
|
||||||
@ -708,10 +729,13 @@ fn ifExpr(mod: *Module, scope: *Scope, rl: ResultLoc, if_node: *ast.Node.If) Inn
|
|||||||
defer else_scope.instructions.deinit(mod.gpa);
|
defer else_scope.instructions.deinit(mod.gpa);
|
||||||
|
|
||||||
if (if_node.@"else") |else_node| {
|
if (if_node.@"else") |else_node| {
|
||||||
const else_result = try expr(mod, &else_scope.base, branch_rl, else_node.body);
|
|
||||||
if (!else_result.tag.isNoReturn()) {
|
|
||||||
const else_src = tree.token_locs[else_node.body.lastToken()].start;
|
const else_src = tree.token_locs[else_node.body.lastToken()].start;
|
||||||
_ = try addZIRInst(mod, &else_scope.base, else_src, zir.Inst.Break, .{
|
// declare payload to the then_scope
|
||||||
|
const else_sub_scope = try cond_kind.elseSubScope(mod, &else_scope, else_src, else_node.payload);
|
||||||
|
|
||||||
|
const else_result = try expr(mod, else_sub_scope, branch_rl, else_node.body);
|
||||||
|
if (!else_result.tag.isNoReturn()) {
|
||||||
|
_ = try addZIRInst(mod, else_sub_scope, else_src, zir.Inst.Break, .{
|
||||||
.block = block,
|
.block = block,
|
||||||
.operand = else_result,
|
.operand = else_result,
|
||||||
}, .{});
|
}, .{});
|
||||||
@ -739,7 +763,7 @@ fn whileExpr(mod: *Module, scope: *Scope, rl: ResultLoc, while_node: *ast.Node.W
|
|||||||
if (cond_kind != .optional) {
|
if (cond_kind != .optional) {
|
||||||
return mod.failNode(scope, payload, "else payload invalid on bool conditions", .{});
|
return mod.failNode(scope, payload, "else payload invalid on bool conditions", .{});
|
||||||
}
|
}
|
||||||
return mod.failNode(scope, payload, "TODO implement astgen.whileExpr for error unions", .{});
|
cond_kind = .{ .err_union = null };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -796,6 +820,8 @@ fn whileExpr(mod: *Module, scope: *Scope, rl: ResultLoc, while_node: *ast.Node.W
|
|||||||
const while_block = try addZIRInstBlock(mod, scope, while_src, .{
|
const while_block = try addZIRInstBlock(mod, scope, while_src, .{
|
||||||
.instructions = try expr_scope.arena.dupe(*zir.Inst, expr_scope.instructions.items),
|
.instructions = try expr_scope.arena.dupe(*zir.Inst, expr_scope.instructions.items),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const then_src = tree.token_locs[while_node.body.lastToken()].start;
|
||||||
var then_scope: Scope.GenZIR = .{
|
var then_scope: Scope.GenZIR = .{
|
||||||
.parent = &continue_scope.base,
|
.parent = &continue_scope.base,
|
||||||
.decl = continue_scope.decl,
|
.decl = continue_scope.decl,
|
||||||
@ -805,7 +831,7 @@ fn whileExpr(mod: *Module, scope: *Scope, rl: ResultLoc, while_node: *ast.Node.W
|
|||||||
defer then_scope.instructions.deinit(mod.gpa);
|
defer then_scope.instructions.deinit(mod.gpa);
|
||||||
|
|
||||||
// declare payload to the then_scope
|
// declare payload to the then_scope
|
||||||
const then_sub_scope = try cond_kind.thenSubScope(mod, &then_scope, while_node.payload);
|
const then_sub_scope = try cond_kind.thenSubScope(mod, &then_scope, then_src, while_node.payload);
|
||||||
|
|
||||||
// Most result location types can be forwarded directly; however
|
// Most result location types can be forwarded directly; however
|
||||||
// if we need to write to a pointer which has an inferred type,
|
// if we need to write to a pointer which has an inferred type,
|
||||||
@ -818,7 +844,6 @@ fn whileExpr(mod: *Module, scope: *Scope, rl: ResultLoc, while_node: *ast.Node.W
|
|||||||
|
|
||||||
const then_result = try expr(mod, then_sub_scope, branch_rl, while_node.body);
|
const then_result = try expr(mod, then_sub_scope, branch_rl, while_node.body);
|
||||||
if (!then_result.tag.isNoReturn()) {
|
if (!then_result.tag.isNoReturn()) {
|
||||||
const then_src = tree.token_locs[while_node.body.lastToken()].start;
|
|
||||||
_ = try addZIRInst(mod, then_sub_scope, then_src, zir.Inst.Break, .{
|
_ = try addZIRInst(mod, then_sub_scope, then_src, zir.Inst.Break, .{
|
||||||
.block = cond_block,
|
.block = cond_block,
|
||||||
.operand = then_result,
|
.operand = then_result,
|
||||||
@ -837,10 +862,13 @@ fn whileExpr(mod: *Module, scope: *Scope, rl: ResultLoc, while_node: *ast.Node.W
|
|||||||
defer else_scope.instructions.deinit(mod.gpa);
|
defer else_scope.instructions.deinit(mod.gpa);
|
||||||
|
|
||||||
if (while_node.@"else") |else_node| {
|
if (while_node.@"else") |else_node| {
|
||||||
const else_result = try expr(mod, &else_scope.base, branch_rl, else_node.body);
|
|
||||||
if (!else_result.tag.isNoReturn()) {
|
|
||||||
const else_src = tree.token_locs[else_node.body.lastToken()].start;
|
const else_src = tree.token_locs[else_node.body.lastToken()].start;
|
||||||
_ = try addZIRInst(mod, &else_scope.base, else_src, zir.Inst.Break, .{
|
// declare payload to the then_scope
|
||||||
|
const else_sub_scope = try cond_kind.elseSubScope(mod, &else_scope, else_src, else_node.payload);
|
||||||
|
|
||||||
|
const else_result = try expr(mod, else_sub_scope, branch_rl, else_node.body);
|
||||||
|
if (!else_result.tag.isNoReturn()) {
|
||||||
|
_ = try addZIRInst(mod, else_sub_scope, else_src, zir.Inst.Break, .{
|
||||||
.block = while_block,
|
.block = while_block,
|
||||||
.operand = else_result,
|
.operand = else_result,
|
||||||
}, .{});
|
}, .{});
|
||||||
|
|||||||
@ -671,6 +671,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
|
|||||||
.intcast => return self.genIntCast(inst.castTag(.intcast).?),
|
.intcast => return self.genIntCast(inst.castTag(.intcast).?),
|
||||||
.isnonnull => return self.genIsNonNull(inst.castTag(.isnonnull).?),
|
.isnonnull => return self.genIsNonNull(inst.castTag(.isnonnull).?),
|
||||||
.isnull => return self.genIsNull(inst.castTag(.isnull).?),
|
.isnull => return self.genIsNull(inst.castTag(.isnull).?),
|
||||||
|
.iserr => return self.genIsErr(inst.castTag(.iserr).?),
|
||||||
.load => return self.genLoad(inst.castTag(.load).?),
|
.load => return self.genLoad(inst.castTag(.load).?),
|
||||||
.loop => return self.genLoop(inst.castTag(.loop).?),
|
.loop => return self.genLoop(inst.castTag(.loop).?),
|
||||||
.not => return self.genNot(inst.castTag(.not).?),
|
.not => return self.genNot(inst.castTag(.not).?),
|
||||||
@ -1391,6 +1392,12 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn genIsErr(self: *Self, inst: *ir.Inst.UnOp) !MCValue {
|
||||||
|
switch (arch) {
|
||||||
|
else => return self.fail(inst.base.src, "TODO implement iserr for {}", .{self.target.cpu.arch}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn genLoop(self: *Self, inst: *ir.Inst.Loop) !MCValue {
|
fn genLoop(self: *Self, inst: *ir.Inst.Loop) !MCValue {
|
||||||
// A loop is a setup to be able to jump back to the beginning.
|
// A loop is a setup to be able to jump back to the beginning.
|
||||||
const start_index = self.code.items.len;
|
const start_index = self.code.items.len;
|
||||||
|
|||||||
@ -68,6 +68,7 @@ pub const Inst = struct {
|
|||||||
dbg_stmt,
|
dbg_stmt,
|
||||||
isnonnull,
|
isnonnull,
|
||||||
isnull,
|
isnull,
|
||||||
|
iserr,
|
||||||
/// Read a value from a pointer.
|
/// Read a value from a pointer.
|
||||||
load,
|
load,
|
||||||
loop,
|
loop,
|
||||||
@ -100,6 +101,7 @@ pub const Inst = struct {
|
|||||||
.not,
|
.not,
|
||||||
.isnonnull,
|
.isnonnull,
|
||||||
.isnull,
|
.isnull,
|
||||||
|
.iserr,
|
||||||
.ptrtoint,
|
.ptrtoint,
|
||||||
.floatcast,
|
.floatcast,
|
||||||
.intcast,
|
.intcast,
|
||||||
|
|||||||
@ -151,6 +151,8 @@ pub const Inst = struct {
|
|||||||
isnonnull,
|
isnonnull,
|
||||||
/// Return a boolean true if an optional is null. `x == null`
|
/// Return a boolean true if an optional is null. `x == null`
|
||||||
isnull,
|
isnull,
|
||||||
|
/// Return a boolean true if value is an error
|
||||||
|
iserr,
|
||||||
/// A labeled block of code that loops forever. At the end of the body it is implied
|
/// A labeled block of code that loops forever. At the end of the body it is implied
|
||||||
/// to repeat; no explicit "repeat" instruction terminates loop bodies.
|
/// to repeat; no explicit "repeat" instruction terminates loop bodies.
|
||||||
loop,
|
loop,
|
||||||
@ -219,6 +221,10 @@ pub const Inst = struct {
|
|||||||
unwrap_optional_safe,
|
unwrap_optional_safe,
|
||||||
/// Same as previous, but without safety checks. Used for orelse, if and while
|
/// Same as previous, but without safety checks. Used for orelse, if and while
|
||||||
unwrap_optional_unsafe,
|
unwrap_optional_unsafe,
|
||||||
|
/// Gets the payload of an error union
|
||||||
|
unwrap_err_safe,
|
||||||
|
/// Same as previous, but without safety checks. Used for orelse, if and while
|
||||||
|
unwrap_err_unsafe,
|
||||||
|
|
||||||
pub fn Type(tag: Tag) type {
|
pub fn Type(tag: Tag) type {
|
||||||
return switch (tag) {
|
return switch (tag) {
|
||||||
@ -237,6 +243,7 @@ pub const Inst = struct {
|
|||||||
.@"return",
|
.@"return",
|
||||||
.isnull,
|
.isnull,
|
||||||
.isnonnull,
|
.isnonnull,
|
||||||
|
.iserr,
|
||||||
.ptrtoint,
|
.ptrtoint,
|
||||||
.alloc,
|
.alloc,
|
||||||
.ensure_result_used,
|
.ensure_result_used,
|
||||||
@ -250,6 +257,8 @@ pub const Inst = struct {
|
|||||||
.optional_type,
|
.optional_type,
|
||||||
.unwrap_optional_safe,
|
.unwrap_optional_safe,
|
||||||
.unwrap_optional_unsafe,
|
.unwrap_optional_unsafe,
|
||||||
|
.unwrap_err_safe,
|
||||||
|
.unwrap_err_unsafe,
|
||||||
=> UnOp,
|
=> UnOp,
|
||||||
|
|
||||||
.add,
|
.add,
|
||||||
@ -363,6 +372,7 @@ pub const Inst = struct {
|
|||||||
.inttype,
|
.inttype,
|
||||||
.isnonnull,
|
.isnonnull,
|
||||||
.isnull,
|
.isnull,
|
||||||
|
.iserr,
|
||||||
.mod_rem,
|
.mod_rem,
|
||||||
.mul,
|
.mul,
|
||||||
.mulwrap,
|
.mulwrap,
|
||||||
@ -385,6 +395,8 @@ pub const Inst = struct {
|
|||||||
.optional_type,
|
.optional_type,
|
||||||
.unwrap_optional_safe,
|
.unwrap_optional_safe,
|
||||||
.unwrap_optional_unsafe,
|
.unwrap_optional_unsafe,
|
||||||
|
.unwrap_err_safe,
|
||||||
|
.unwrap_err_unsafe,
|
||||||
.ptr_type,
|
.ptr_type,
|
||||||
=> false,
|
=> false,
|
||||||
|
|
||||||
@ -2014,6 +2026,7 @@ const EmitZIR = struct {
|
|||||||
.ptrtoint => try self.emitUnOp(inst.src, new_body, inst.castTag(.ptrtoint).?, .ptrtoint),
|
.ptrtoint => try self.emitUnOp(inst.src, new_body, inst.castTag(.ptrtoint).?, .ptrtoint),
|
||||||
.isnull => try self.emitUnOp(inst.src, new_body, inst.castTag(.isnull).?, .isnull),
|
.isnull => try self.emitUnOp(inst.src, new_body, inst.castTag(.isnull).?, .isnull),
|
||||||
.isnonnull => try self.emitUnOp(inst.src, new_body, inst.castTag(.isnonnull).?, .isnonnull),
|
.isnonnull => try self.emitUnOp(inst.src, new_body, inst.castTag(.isnonnull).?, .isnonnull),
|
||||||
|
.iserr => try self.emitUnOp(inst.src, new_body, inst.castTag(.iserr).?, .iserr),
|
||||||
.load => try self.emitUnOp(inst.src, new_body, inst.castTag(.load).?, .deref),
|
.load => try self.emitUnOp(inst.src, new_body, inst.castTag(.load).?, .deref),
|
||||||
.ref => try self.emitUnOp(inst.src, new_body, inst.castTag(.ref).?, .ref),
|
.ref => try self.emitUnOp(inst.src, new_body, inst.castTag(.ref).?, .ref),
|
||||||
.unwrap_optional => try self.emitUnOp(inst.src, new_body, inst.castTag(.unwrap_optional).?, .unwrap_optional_unsafe),
|
.unwrap_optional => try self.emitUnOp(inst.src, new_body, inst.castTag(.unwrap_optional).?, .unwrap_optional_unsafe),
|
||||||
|
|||||||
@ -104,11 +104,14 @@ pub fn analyzeInst(mod: *Module, scope: *Scope, old_inst: *zir.Inst) InnerError!
|
|||||||
.condbr => return analyzeInstCondBr(mod, scope, old_inst.castTag(.condbr).?),
|
.condbr => return analyzeInstCondBr(mod, scope, old_inst.castTag(.condbr).?),
|
||||||
.isnull => return analyzeInstIsNonNull(mod, scope, old_inst.castTag(.isnull).?, true),
|
.isnull => return analyzeInstIsNonNull(mod, scope, old_inst.castTag(.isnull).?, true),
|
||||||
.isnonnull => return analyzeInstIsNonNull(mod, scope, old_inst.castTag(.isnonnull).?, false),
|
.isnonnull => return analyzeInstIsNonNull(mod, scope, old_inst.castTag(.isnonnull).?, false),
|
||||||
|
.iserr => return analyzeInstIsErr(mod, scope, old_inst.castTag(.iserr).?, true),
|
||||||
.boolnot => return analyzeInstBoolNot(mod, scope, old_inst.castTag(.boolnot).?),
|
.boolnot => return analyzeInstBoolNot(mod, scope, old_inst.castTag(.boolnot).?),
|
||||||
.typeof => return analyzeInstTypeOf(mod, scope, old_inst.castTag(.typeof).?),
|
.typeof => return analyzeInstTypeOf(mod, scope, old_inst.castTag(.typeof).?),
|
||||||
.optional_type => return analyzeInstOptionalType(mod, scope, old_inst.castTag(.optional_type).?),
|
.optional_type => return analyzeInstOptionalType(mod, scope, old_inst.castTag(.optional_type).?),
|
||||||
.unwrap_optional_safe => return analyzeInstUnwrapOptional(mod, scope, old_inst.castTag(.unwrap_optional_safe).?, true),
|
.unwrap_optional_safe => return analyzeInstUnwrapOptional(mod, scope, old_inst.castTag(.unwrap_optional_safe).?, true),
|
||||||
.unwrap_optional_unsafe => return analyzeInstUnwrapOptional(mod, scope, old_inst.castTag(.unwrap_optional_unsafe).?, false),
|
.unwrap_optional_unsafe => return analyzeInstUnwrapOptional(mod, scope, old_inst.castTag(.unwrap_optional_unsafe).?, false),
|
||||||
|
.unwrap_err_safe => return analyzeInstUnwrapErr(mod, scope, old_inst.castTag(.unwrap_err_safe).?, true),
|
||||||
|
.unwrap_err_unsafe => return analyzeInstUnwrapErr(mod, scope, old_inst.castTag(.unwrap_err_unsafe).?, false),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -729,6 +732,10 @@ fn analyzeInstUnwrapOptional(mod: *Module, scope: *Scope, unwrap: *zir.Inst.UnOp
|
|||||||
return mod.addUnOp(b, unwrap.base.src, child_pointer, .unwrap_optional, operand);
|
return mod.addUnOp(b, unwrap.base.src, child_pointer, .unwrap_optional, operand);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn analyzeInstUnwrapErr(mod: *Module, scope: *Scope, unwrap: *zir.Inst.UnOp, safety_check: bool) InnerError!*Inst {
|
||||||
|
return mod.fail(scope, unwrap.base.src, "TODO implement analyzeInstUnwrapErr", .{});
|
||||||
|
}
|
||||||
|
|
||||||
fn analyzeInstFnType(mod: *Module, scope: *Scope, fntype: *zir.Inst.FnType) InnerError!*Inst {
|
fn analyzeInstFnType(mod: *Module, scope: *Scope, fntype: *zir.Inst.FnType) InnerError!*Inst {
|
||||||
const return_type = try resolveType(mod, scope, fntype.positionals.return_type);
|
const return_type = try resolveType(mod, scope, fntype.positionals.return_type);
|
||||||
|
|
||||||
@ -1169,6 +1176,10 @@ fn analyzeInstIsNonNull(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp, inver
|
|||||||
return mod.analyzeIsNull(scope, inst.base.src, operand, invert_logic);
|
return mod.analyzeIsNull(scope, inst.base.src, operand, invert_logic);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn analyzeInstIsErr(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp, invert_logic: bool) InnerError!*Inst {
|
||||||
|
return mod.fail(scope, inst.base.src, "TODO implement analyzeInstIsErr", .{});
|
||||||
|
}
|
||||||
|
|
||||||
fn analyzeInstCondBr(mod: *Module, scope: *Scope, inst: *zir.Inst.CondBr) InnerError!*Inst {
|
fn analyzeInstCondBr(mod: *Module, scope: *Scope, inst: *zir.Inst.CondBr) InnerError!*Inst {
|
||||||
const uncasted_cond = try resolveInst(mod, scope, inst.positionals.condition);
|
const uncasted_cond = try resolveInst(mod, scope, inst.positionals.condition);
|
||||||
const cond = try mod.coerce(scope, Type.initTag(.bool), uncasted_cond);
|
const cond = try mod.coerce(scope, Type.initTag(.bool), uncasted_cond);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user