authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-08-15 19:39:11+03:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-08-17 14:28:04+03:00
logece4a2fc512bffba3845bf611370f5ea436c57b4
tree1d47367746a091edeb84b95077e53862bd8fcadb
parentdb77b6b4e731670188e632657aa0aeadf9c87eb5
signaturelock-open Commit is signed but in an unrecognized format.

stage2: astgen for if and while with error unions


5 files changed, 75 insertions(+), 14 deletions(-)

src-self-hosted/astgen.zig+42-14
...@@ -614,11 +614,16 @@ const CondKind = union(enum) {...@@ -614,11 +614,16 @@ const CondKind = union(enum) {
614 const result = try addZIRUnOp(mod, &block_scope.base, src, .deref, cond_ptr);614 const result = try addZIRUnOp(mod, &block_scope.base, src, .deref, cond_ptr);
615 return try addZIRUnOp(mod, &block_scope.base, src, .isnonnull, result);615 return try addZIRUnOp(mod, &block_scope.base, src, .isnonnull, result);
616 },616 },
617 .err_union => unreachable,617 .err_union => {
618 const err_ptr = try expr(mod, &block_scope.base, .lvalue, cond_node);
619 self.* = .{ .err_union = err_ptr };
620 const result = try addZIRUnOp(mod, &block_scope.base, src, .deref, err_ptr);
621 return try addZIRUnOp(mod, &block_scope.base, src, .iserr, result);
622 },
618 }623 }
619 }624 }
620625
621 fn thenSubScope(self: CondKind, mod: *Module, then_scope: *Scope.GenZIR, payload_node: ?*ast.Node) !*Scope {626 fn thenSubScope(self: CondKind, mod: *Module, then_scope: *Scope.GenZIR, src: usize, payload_node: ?*ast.Node) !*Scope {
622 if (self == .bool) return &then_scope.base;627 if (self == .bool) return &then_scope.base;
623628
624 const payload = payload_node.?.castTag(.PointerPayload).?;629 const payload = payload_node.?.castTag(.PointerPayload).?;
...@@ -633,6 +638,21 @@ const CondKind = union(enum) {...@@ -633,6 +638,21 @@ const CondKind = union(enum) {
633638
634 return mod.failNode(&then_scope.base, payload.value_symbol, "TODO implement payload symbols", .{});639 return mod.failNode(&then_scope.base, payload.value_symbol, "TODO implement payload symbols", .{});
635 }640 }
641
642 fn elseSubScope(self: CondKind, mod: *Module, else_scope: *Scope.GenZIR, src: usize, payload_node: ?*ast.Node) !*Scope {
643 if (self != .err_union) return &else_scope.base;
644
645 const payload_ptr = try addZIRUnOp(mod, &else_scope.base, src, .unwrap_err_unsafe, self.err_union.?);
646
647 const payload = payload_node.?.castTag(.Payload).?;
648 const ident_node = payload.error_symbol.castTag(.Identifier).?;
649 const ident_name = try identifierTokenString(mod, &else_scope.base, ident_node.token);
650 if (mem.eql(u8, ident_name, "_")) {
651 return &else_scope.base;
652 }
653
654 return mod.failNode(&else_scope.base, payload.error_symbol, "TODO implement payload symbols", .{});
655 }
636};656};
637657
638fn ifExpr(mod: *Module, scope: *Scope, rl: ResultLoc, if_node: *ast.Node.If) InnerError!*zir.Inst {658fn 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...@@ -643,7 +663,7 @@ fn ifExpr(mod: *Module, scope: *Scope, rl: ResultLoc, if_node: *ast.Node.If) Inn
643 if (cond_kind != .optional) {663 if (cond_kind != .optional) {
644 return mod.failNode(scope, payload, "else payload invalid on bool conditions", .{});664 return mod.failNode(scope, payload, "else payload invalid on bool conditions", .{});
645 }665 }
646 return mod.failNode(scope, payload, "TODO implement astgen.IfExpr for error unions", .{});666 cond_kind = .{ .err_union = null };
647 }667 }
648 }668 }
649 var block_scope: Scope.GenZIR = .{669 var block_scope: Scope.GenZIR = .{
...@@ -667,6 +687,8 @@ fn ifExpr(mod: *Module, scope: *Scope, rl: ResultLoc, if_node: *ast.Node.If) Inn...@@ -667,6 +687,8 @@ fn ifExpr(mod: *Module, scope: *Scope, rl: ResultLoc, if_node: *ast.Node.If) Inn
667 const block = try addZIRInstBlock(mod, scope, if_src, .{687 const block = try addZIRInstBlock(mod, scope, if_src, .{
668 .instructions = try block_scope.arena.dupe(*zir.Inst, block_scope.instructions.items),688 .instructions = try block_scope.arena.dupe(*zir.Inst, block_scope.instructions.items),
669 });689 });
690
691 const then_src = tree.token_locs[if_node.body.lastToken()].start;
670 var then_scope: Scope.GenZIR = .{692 var then_scope: Scope.GenZIR = .{
671 .parent = scope,693 .parent = scope,
672 .decl = block_scope.decl,694 .decl = block_scope.decl,
...@@ -676,7 +698,7 @@ fn ifExpr(mod: *Module, scope: *Scope, rl: ResultLoc, if_node: *ast.Node.If) Inn...@@ -676,7 +698,7 @@ fn ifExpr(mod: *Module, scope: *Scope, rl: ResultLoc, if_node: *ast.Node.If) Inn
676 defer then_scope.instructions.deinit(mod.gpa);698 defer then_scope.instructions.deinit(mod.gpa);
677699
678 // declare payload to the then_scope700 // declare payload to the then_scope
679 const then_sub_scope = try cond_kind.thenSubScope(mod, &then_scope, if_node.payload);701 const then_sub_scope = try cond_kind.thenSubScope(mod, &then_scope, then_src, if_node.payload);
680702
681 // Most result location types can be forwarded directly; however703 // Most result location types can be forwarded directly; however
682 // if we need to write to a pointer which has an inferred type,704 // 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...@@ -689,7 +711,6 @@ fn ifExpr(mod: *Module, scope: *Scope, rl: ResultLoc, if_node: *ast.Node.If) Inn
689711
690 const then_result = try expr(mod, then_sub_scope, branch_rl, if_node.body);712 const then_result = try expr(mod, then_sub_scope, branch_rl, if_node.body);
691 if (!then_result.tag.isNoReturn()) {713 if (!then_result.tag.isNoReturn()) {
692 const then_src = tree.token_locs[if_node.body.lastToken()].start;
693 _ = try addZIRInst(mod, then_sub_scope, then_src, zir.Inst.Break, .{714 _ = try addZIRInst(mod, then_sub_scope, then_src, zir.Inst.Break, .{
694 .block = block,715 .block = block,
695 .operand = then_result,716 .operand = then_result,
...@@ -708,10 +729,13 @@ fn ifExpr(mod: *Module, scope: *Scope, rl: ResultLoc, if_node: *ast.Node.If) Inn...@@ -708,10 +729,13 @@ fn ifExpr(mod: *Module, scope: *Scope, rl: ResultLoc, if_node: *ast.Node.If) Inn
708 defer else_scope.instructions.deinit(mod.gpa);729 defer else_scope.instructions.deinit(mod.gpa);
709730
710 if (if_node.@"else") |else_node| {731 if (if_node.@"else") |else_node| {
711 const else_result = try expr(mod, &else_scope.base, branch_rl, else_node.body);732 const else_src = tree.token_locs[else_node.body.lastToken()].start;
733 // declare payload to the then_scope
734 const else_sub_scope = try cond_kind.elseSubScope(mod, &else_scope, else_src, else_node.payload);
735
736 const else_result = try expr(mod, else_sub_scope, branch_rl, else_node.body);
712 if (!else_result.tag.isNoReturn()) {737 if (!else_result.tag.isNoReturn()) {
713 const else_src = tree.token_locs[else_node.body.lastToken()].start;738 _ = try addZIRInst(mod, else_sub_scope, else_src, zir.Inst.Break, .{
714 _ = try addZIRInst(mod, &else_scope.base, else_src, zir.Inst.Break, .{
715 .block = block,739 .block = block,
716 .operand = else_result,740 .operand = else_result,
717 }, .{});741 }, .{});
...@@ -739,7 +763,7 @@ fn whileExpr(mod: *Module, scope: *Scope, rl: ResultLoc, while_node: *ast.Node.W...@@ -739,7 +763,7 @@ fn whileExpr(mod: *Module, scope: *Scope, rl: ResultLoc, while_node: *ast.Node.W
739 if (cond_kind != .optional) {763 if (cond_kind != .optional) {
740 return mod.failNode(scope, payload, "else payload invalid on bool conditions", .{});764 return mod.failNode(scope, payload, "else payload invalid on bool conditions", .{});
741 }765 }
742 return mod.failNode(scope, payload, "TODO implement astgen.whileExpr for error unions", .{});766 cond_kind = .{ .err_union = null };
743 }767 }
744 }768 }
745769
...@@ -796,6 +820,8 @@ fn whileExpr(mod: *Module, scope: *Scope, rl: ResultLoc, while_node: *ast.Node.W...@@ -796,6 +820,8 @@ fn whileExpr(mod: *Module, scope: *Scope, rl: ResultLoc, while_node: *ast.Node.W
796 const while_block = try addZIRInstBlock(mod, scope, while_src, .{820 const while_block = try addZIRInstBlock(mod, scope, while_src, .{
797 .instructions = try expr_scope.arena.dupe(*zir.Inst, expr_scope.instructions.items),821 .instructions = try expr_scope.arena.dupe(*zir.Inst, expr_scope.instructions.items),
798 });822 });
823
824 const then_src = tree.token_locs[while_node.body.lastToken()].start;
799 var then_scope: Scope.GenZIR = .{825 var then_scope: Scope.GenZIR = .{
800 .parent = &continue_scope.base,826 .parent = &continue_scope.base,
801 .decl = continue_scope.decl,827 .decl = continue_scope.decl,
...@@ -805,7 +831,7 @@ fn whileExpr(mod: *Module, scope: *Scope, rl: ResultLoc, while_node: *ast.Node.W...@@ -805,7 +831,7 @@ fn whileExpr(mod: *Module, scope: *Scope, rl: ResultLoc, while_node: *ast.Node.W
805 defer then_scope.instructions.deinit(mod.gpa);831 defer then_scope.instructions.deinit(mod.gpa);
806832
807 // declare payload to the then_scope833 // declare payload to the then_scope
808 const then_sub_scope = try cond_kind.thenSubScope(mod, &then_scope, while_node.payload);834 const then_sub_scope = try cond_kind.thenSubScope(mod, &then_scope, then_src, while_node.payload);
809835
810 // Most result location types can be forwarded directly; however836 // Most result location types can be forwarded directly; however
811 // if we need to write to a pointer which has an inferred type,837 // 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...@@ -818,7 +844,6 @@ fn whileExpr(mod: *Module, scope: *Scope, rl: ResultLoc, while_node: *ast.Node.W
818844
819 const then_result = try expr(mod, then_sub_scope, branch_rl, while_node.body);845 const then_result = try expr(mod, then_sub_scope, branch_rl, while_node.body);
820 if (!then_result.tag.isNoReturn()) {846 if (!then_result.tag.isNoReturn()) {
821 const then_src = tree.token_locs[while_node.body.lastToken()].start;
822 _ = try addZIRInst(mod, then_sub_scope, then_src, zir.Inst.Break, .{847 _ = try addZIRInst(mod, then_sub_scope, then_src, zir.Inst.Break, .{
823 .block = cond_block,848 .block = cond_block,
824 .operand = then_result,849 .operand = then_result,
...@@ -837,10 +862,13 @@ fn whileExpr(mod: *Module, scope: *Scope, rl: ResultLoc, while_node: *ast.Node.W...@@ -837,10 +862,13 @@ fn whileExpr(mod: *Module, scope: *Scope, rl: ResultLoc, while_node: *ast.Node.W
837 defer else_scope.instructions.deinit(mod.gpa);862 defer else_scope.instructions.deinit(mod.gpa);
838863
839 if (while_node.@"else") |else_node| {864 if (while_node.@"else") |else_node| {
840 const else_result = try expr(mod, &else_scope.base, branch_rl, else_node.body);865 const else_src = tree.token_locs[else_node.body.lastToken()].start;
866 // declare payload to the then_scope
867 const else_sub_scope = try cond_kind.elseSubScope(mod, &else_scope, else_src, else_node.payload);
868
869 const else_result = try expr(mod, else_sub_scope, branch_rl, else_node.body);
841 if (!else_result.tag.isNoReturn()) {870 if (!else_result.tag.isNoReturn()) {
842 const else_src = tree.token_locs[else_node.body.lastToken()].start;871 _ = try addZIRInst(mod, else_sub_scope, else_src, zir.Inst.Break, .{
843 _ = try addZIRInst(mod, &else_scope.base, else_src, zir.Inst.Break, .{
844 .block = while_block,872 .block = while_block,
845 .operand = else_result,873 .operand = else_result,
846 }, .{});874 }, .{});
src-self-hosted/codegen.zig+7
...@@ -671,6 +671,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {...@@ -671,6 +671,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
671 .intcast => return self.genIntCast(inst.castTag(.intcast).?),671 .intcast => return self.genIntCast(inst.castTag(.intcast).?),
672 .isnonnull => return self.genIsNonNull(inst.castTag(.isnonnull).?),672 .isnonnull => return self.genIsNonNull(inst.castTag(.isnonnull).?),
673 .isnull => return self.genIsNull(inst.castTag(.isnull).?),673 .isnull => return self.genIsNull(inst.castTag(.isnull).?),
674 .iserr => return self.genIsErr(inst.castTag(.iserr).?),
674 .load => return self.genLoad(inst.castTag(.load).?),675 .load => return self.genLoad(inst.castTag(.load).?),
675 .loop => return self.genLoop(inst.castTag(.loop).?),676 .loop => return self.genLoop(inst.castTag(.loop).?),
676 .not => return self.genNot(inst.castTag(.not).?),677 .not => return self.genNot(inst.castTag(.not).?),
...@@ -1391,6 +1392,12 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {...@@ -1391,6 +1392,12 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
1391 }1392 }
1392 }1393 }
13931394
1395 fn genIsErr(self: *Self, inst: *ir.Inst.UnOp) !MCValue {
1396 switch (arch) {
1397 else => return self.fail(inst.base.src, "TODO implement iserr for {}", .{self.target.cpu.arch}),
1398 }
1399 }
1400
1394 fn genLoop(self: *Self, inst: *ir.Inst.Loop) !MCValue {1401 fn genLoop(self: *Self, inst: *ir.Inst.Loop) !MCValue {
1395 // A loop is a setup to be able to jump back to the beginning.1402 // A loop is a setup to be able to jump back to the beginning.
1396 const start_index = self.code.items.len;1403 const start_index = self.code.items.len;
src-self-hosted/ir.zig+2
...@@ -68,6 +68,7 @@ pub const Inst = struct {...@@ -68,6 +68,7 @@ pub const Inst = struct {
68 dbg_stmt,68 dbg_stmt,
69 isnonnull,69 isnonnull,
70 isnull,70 isnull,
71 iserr,
71 /// Read a value from a pointer.72 /// Read a value from a pointer.
72 load,73 load,
73 loop,74 loop,
...@@ -100,6 +101,7 @@ pub const Inst = struct {...@@ -100,6 +101,7 @@ pub const Inst = struct {
100 .not,101 .not,
101 .isnonnull,102 .isnonnull,
102 .isnull,103 .isnull,
104 .iserr,
103 .ptrtoint,105 .ptrtoint,
104 .floatcast,106 .floatcast,
105 .intcast,107 .intcast,
src-self-hosted/zir.zig+13
...@@ -151,6 +151,8 @@ pub const Inst = struct {...@@ -151,6 +151,8 @@ pub const Inst = struct {
151 isnonnull,151 isnonnull,
152 /// Return a boolean true if an optional is null. `x == null`152 /// Return a boolean true if an optional is null. `x == null`
153 isnull,153 isnull,
154 /// Return a boolean true if value is an error
155 iserr,
154 /// A labeled block of code that loops forever. At the end of the body it is implied156 /// A labeled block of code that loops forever. At the end of the body it is implied
155 /// to repeat; no explicit "repeat" instruction terminates loop bodies.157 /// to repeat; no explicit "repeat" instruction terminates loop bodies.
156 loop,158 loop,
...@@ -219,6 +221,10 @@ pub const Inst = struct {...@@ -219,6 +221,10 @@ pub const Inst = struct {
219 unwrap_optional_safe,221 unwrap_optional_safe,
220 /// Same as previous, but without safety checks. Used for orelse, if and while222 /// Same as previous, but without safety checks. Used for orelse, if and while
221 unwrap_optional_unsafe,223 unwrap_optional_unsafe,
224 /// Gets the payload of an error union
225 unwrap_err_safe,
226 /// Same as previous, but without safety checks. Used for orelse, if and while
227 unwrap_err_unsafe,
222228
223 pub fn Type(tag: Tag) type {229 pub fn Type(tag: Tag) type {
224 return switch (tag) {230 return switch (tag) {
...@@ -237,6 +243,7 @@ pub const Inst = struct {...@@ -237,6 +243,7 @@ pub const Inst = struct {
237 .@"return",243 .@"return",
238 .isnull,244 .isnull,
239 .isnonnull,245 .isnonnull,
246 .iserr,
240 .ptrtoint,247 .ptrtoint,
241 .alloc,248 .alloc,
242 .ensure_result_used,249 .ensure_result_used,
...@@ -250,6 +257,8 @@ pub const Inst = struct {...@@ -250,6 +257,8 @@ pub const Inst = struct {
250 .optional_type,257 .optional_type,
251 .unwrap_optional_safe,258 .unwrap_optional_safe,
252 .unwrap_optional_unsafe,259 .unwrap_optional_unsafe,
260 .unwrap_err_safe,
261 .unwrap_err_unsafe,
253 => UnOp,262 => UnOp,
254263
255 .add,264 .add,
...@@ -363,6 +372,7 @@ pub const Inst = struct {...@@ -363,6 +372,7 @@ pub const Inst = struct {
363 .inttype,372 .inttype,
364 .isnonnull,373 .isnonnull,
365 .isnull,374 .isnull,
375 .iserr,
366 .mod_rem,376 .mod_rem,
367 .mul,377 .mul,
368 .mulwrap,378 .mulwrap,
...@@ -385,6 +395,8 @@ pub const Inst = struct {...@@ -385,6 +395,8 @@ pub const Inst = struct {
385 .optional_type,395 .optional_type,
386 .unwrap_optional_safe,396 .unwrap_optional_safe,
387 .unwrap_optional_unsafe,397 .unwrap_optional_unsafe,
398 .unwrap_err_safe,
399 .unwrap_err_unsafe,
388 .ptr_type,400 .ptr_type,
389 => false,401 => false,
390402
...@@ -2014,6 +2026,7 @@ const EmitZIR = struct {...@@ -2014,6 +2026,7 @@ const EmitZIR = struct {
2014 .ptrtoint => try self.emitUnOp(inst.src, new_body, inst.castTag(.ptrtoint).?, .ptrtoint),2026 .ptrtoint => try self.emitUnOp(inst.src, new_body, inst.castTag(.ptrtoint).?, .ptrtoint),
2015 .isnull => try self.emitUnOp(inst.src, new_body, inst.castTag(.isnull).?, .isnull),2027 .isnull => try self.emitUnOp(inst.src, new_body, inst.castTag(.isnull).?, .isnull),
2016 .isnonnull => try self.emitUnOp(inst.src, new_body, inst.castTag(.isnonnull).?, .isnonnull),2028 .isnonnull => try self.emitUnOp(inst.src, new_body, inst.castTag(.isnonnull).?, .isnonnull),
2029 .iserr => try self.emitUnOp(inst.src, new_body, inst.castTag(.iserr).?, .iserr),
2017 .load => try self.emitUnOp(inst.src, new_body, inst.castTag(.load).?, .deref),2030 .load => try self.emitUnOp(inst.src, new_body, inst.castTag(.load).?, .deref),
2018 .ref => try self.emitUnOp(inst.src, new_body, inst.castTag(.ref).?, .ref),2031 .ref => try self.emitUnOp(inst.src, new_body, inst.castTag(.ref).?, .ref),
2019 .unwrap_optional => try self.emitUnOp(inst.src, new_body, inst.castTag(.unwrap_optional).?, .unwrap_optional_unsafe),2032 .unwrap_optional => try self.emitUnOp(inst.src, new_body, inst.castTag(.unwrap_optional).?, .unwrap_optional_unsafe),
src-self-hosted/zir_sema.zig+11
...@@ -104,11 +104,14 @@ pub fn analyzeInst(mod: *Module, scope: *Scope, old_inst: *zir.Inst) InnerError!...@@ -104,11 +104,14 @@ pub fn analyzeInst(mod: *Module, scope: *Scope, old_inst: *zir.Inst) InnerError!
104 .condbr => return analyzeInstCondBr(mod, scope, old_inst.castTag(.condbr).?),104 .condbr => return analyzeInstCondBr(mod, scope, old_inst.castTag(.condbr).?),
105 .isnull => return analyzeInstIsNonNull(mod, scope, old_inst.castTag(.isnull).?, true),105 .isnull => return analyzeInstIsNonNull(mod, scope, old_inst.castTag(.isnull).?, true),
106 .isnonnull => return analyzeInstIsNonNull(mod, scope, old_inst.castTag(.isnonnull).?, false),106 .isnonnull => return analyzeInstIsNonNull(mod, scope, old_inst.castTag(.isnonnull).?, false),
107 .iserr => return analyzeInstIsErr(mod, scope, old_inst.castTag(.iserr).?, true),
107 .boolnot => return analyzeInstBoolNot(mod, scope, old_inst.castTag(.boolnot).?),108 .boolnot => return analyzeInstBoolNot(mod, scope, old_inst.castTag(.boolnot).?),
108 .typeof => return analyzeInstTypeOf(mod, scope, old_inst.castTag(.typeof).?),109 .typeof => return analyzeInstTypeOf(mod, scope, old_inst.castTag(.typeof).?),
109 .optional_type => return analyzeInstOptionalType(mod, scope, old_inst.castTag(.optional_type).?),110 .optional_type => return analyzeInstOptionalType(mod, scope, old_inst.castTag(.optional_type).?),
110 .unwrap_optional_safe => return analyzeInstUnwrapOptional(mod, scope, old_inst.castTag(.unwrap_optional_safe).?, true),111 .unwrap_optional_safe => return analyzeInstUnwrapOptional(mod, scope, old_inst.castTag(.unwrap_optional_safe).?, true),
111 .unwrap_optional_unsafe => return analyzeInstUnwrapOptional(mod, scope, old_inst.castTag(.unwrap_optional_unsafe).?, false),112 .unwrap_optional_unsafe => return analyzeInstUnwrapOptional(mod, scope, old_inst.castTag(.unwrap_optional_unsafe).?, false),
113 .unwrap_err_safe => return analyzeInstUnwrapErr(mod, scope, old_inst.castTag(.unwrap_err_safe).?, true),
114 .unwrap_err_unsafe => return analyzeInstUnwrapErr(mod, scope, old_inst.castTag(.unwrap_err_unsafe).?, false),
112 }115 }
113}116}
114117
...@@ -729,6 +732,10 @@ fn analyzeInstUnwrapOptional(mod: *Module, scope: *Scope, unwrap: *zir.Inst.UnOp...@@ -729,6 +732,10 @@ fn analyzeInstUnwrapOptional(mod: *Module, scope: *Scope, unwrap: *zir.Inst.UnOp
729 return mod.addUnOp(b, unwrap.base.src, child_pointer, .unwrap_optional, operand);732 return mod.addUnOp(b, unwrap.base.src, child_pointer, .unwrap_optional, operand);
730}733}
731734
735fn analyzeInstUnwrapErr(mod: *Module, scope: *Scope, unwrap: *zir.Inst.UnOp, safety_check: bool) InnerError!*Inst {
736 return mod.fail(scope, unwrap.base.src, "TODO implement analyzeInstUnwrapErr", .{});
737}
738
732fn analyzeInstFnType(mod: *Module, scope: *Scope, fntype: *zir.Inst.FnType) InnerError!*Inst {739fn analyzeInstFnType(mod: *Module, scope: *Scope, fntype: *zir.Inst.FnType) InnerError!*Inst {
733 const return_type = try resolveType(mod, scope, fntype.positionals.return_type);740 const return_type = try resolveType(mod, scope, fntype.positionals.return_type);
734741
...@@ -1169,6 +1176,10 @@ fn analyzeInstIsNonNull(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp, inver...@@ -1169,6 +1176,10 @@ fn analyzeInstIsNonNull(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp, inver
1169 return mod.analyzeIsNull(scope, inst.base.src, operand, invert_logic);1176 return mod.analyzeIsNull(scope, inst.base.src, operand, invert_logic);
1170}1177}
11711178
1179fn analyzeInstIsErr(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp, invert_logic: bool) InnerError!*Inst {
1180 return mod.fail(scope, inst.base.src, "TODO implement analyzeInstIsErr", .{});
1181}
1182
1172fn analyzeInstCondBr(mod: *Module, scope: *Scope, inst: *zir.Inst.CondBr) InnerError!*Inst {1183fn analyzeInstCondBr(mod: *Module, scope: *Scope, inst: *zir.Inst.CondBr) InnerError!*Inst {
1173 const uncasted_cond = try resolveInst(mod, scope, inst.positionals.condition);1184 const uncasted_cond = try resolveInst(mod, scope, inst.positionals.condition);
1174 const cond = try mod.coerce(scope, Type.initTag(.bool), uncasted_cond);1185 const cond = try mod.coerce(scope, Type.initTag(.bool), uncasted_cond);