| author | |
| committer | |
| log | fb28349349483c5e1c9523b19c2158cb465cf4e9 |
| tree | 9943dadd549168087d653d2145642f4752736539 |
| parent | bf014d529a8373d43f92b0dd5c8a5d8509150ca9 |
4 files changed, 120 insertions(+), 22 deletions(-)
src-self-hosted/Module.zig+11-1| ... | @@ -2570,7 +2570,17 @@ pub fn analyzeIsNull( | ... | @@ -2570,7 +2570,17 @@ pub fn analyzeIsNull( |
| 2570 | operand: *Inst, | 2570 | operand: *Inst, |
| 2571 | invert_logic: bool, | 2571 | invert_logic: bool, |
| 2572 | ) InnerError!*Inst { | 2572 | ) InnerError!*Inst { |
| 2573 | return self.fail(scope, src, "TODO implement analysis of isnull and isnotnull", .{}); | 2573 | if (operand.value()) |opt_val| { |
| 2574 | const is_null = opt_val.isNull(); | ||
| 2575 | return self.constBool(scope, src, invert_logic); | ||
| 2576 | } | ||
| 2577 | const b = try self.requireRuntimeBlock(scope, src); | ||
| 2578 | const inst_tag: Inst.Tag = if (invert_logic) .isnonnull else .isnull; | ||
| 2579 | return self.addUnOp(b, src, Type.initTag(.bool), inst_tag, operand); | ||
| 2580 | } | ||
| 2581 | |||
| 2582 | pub fn analyzeIsErr(self: *Module, scope: *Scope, src: usize, operand: *Inst) InnerError!*Inst { | ||
| 2583 | return self.fail(scope, src, "TODO implement analysis of iserr", .{}); | ||
| 2574 | } | 2584 | } |
| 2575 | 2585 | ||
| 2576 | /// Asserts that lhs and rhs types are both numeric. | 2586 | /// Asserts that lhs and rhs types are both numeric. |
src-self-hosted/astgen.zig+90-4| ... | @@ -275,9 +275,9 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node) InnerEr | ... | @@ -275,9 +275,9 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node) InnerEr |
| 275 | .ErrorType => return rlWrap(mod, scope, rl, try errorType(mod, scope, node.castTag(.ErrorType).?)), | 275 | .ErrorType => return rlWrap(mod, scope, rl, try errorType(mod, scope, node.castTag(.ErrorType).?)), |
| 276 | .For => return forExpr(mod, scope, rl, node.castTag(.For).?), | 276 | .For => return forExpr(mod, scope, rl, node.castTag(.For).?), |
| 277 | .ArrayAccess => return arrayAccess(mod, scope, rl, node.castTag(.ArrayAccess).?), | 277 | .ArrayAccess => return arrayAccess(mod, scope, rl, node.castTag(.ArrayAccess).?), |
| 278 | .Catch => return catchExpr(mod, scope, rl, node.castTag(.Catch).?), | ||
| 278 | 279 | ||
| 279 | .Defer => return mod.failNode(scope, node, "TODO implement astgen.expr for .Defer", .{}), | 280 | .Defer => return mod.failNode(scope, node, "TODO implement astgen.expr for .Defer", .{}), |
| 280 | .Catch => return mod.failNode(scope, node, "TODO implement astgen.expr for .Catch", .{}), | ||
| 281 | .Range => return mod.failNode(scope, node, "TODO implement astgen.expr for .Range", .{}), | 281 | .Range => return mod.failNode(scope, node, "TODO implement astgen.expr for .Range", .{}), |
| 282 | .OrElse => return mod.failNode(scope, node, "TODO implement astgen.expr for .OrElse", .{}), | 282 | .OrElse => return mod.failNode(scope, node, "TODO implement astgen.expr for .OrElse", .{}), |
| 283 | .Await => return mod.failNode(scope, node, "TODO implement astgen.expr for .Await", .{}), | 283 | .Await => return mod.failNode(scope, node, "TODO implement astgen.expr for .Await", .{}), |
| ... | @@ -750,6 +750,93 @@ fn errorType(mod: *Module, scope: *Scope, node: *ast.Node.OneToken) InnerError!* | ... | @@ -750,6 +750,93 @@ fn errorType(mod: *Module, scope: *Scope, node: *ast.Node.OneToken) InnerError!* |
| 750 | }); | 750 | }); |
| 751 | } | 751 | } |
| 752 | 752 | ||
| 753 | fn catchExpr(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.Catch) InnerError!*zir.Inst { | ||
| 754 | const tree = scope.tree(); | ||
| 755 | const src = tree.token_locs[node.op_token].start; | ||
| 756 | |||
| 757 | const err_union_ptr = try expr(mod, scope, .ref, node.lhs); | ||
| 758 | // TODO we could avoid an unnecessary copy if .iserr took a pointer | ||
| 759 | const err_union = try addZIRUnOp(mod, scope, src, .deref, err_union_ptr); | ||
| 760 | const cond = try addZIRUnOp(mod, scope, src, .iserr, err_union); | ||
| 761 | |||
| 762 | var block_scope: Scope.GenZIR = .{ | ||
| 763 | .parent = scope, | ||
| 764 | .decl = scope.decl().?, | ||
| 765 | .arena = scope.arena(), | ||
| 766 | .instructions = .{}, | ||
| 767 | }; | ||
| 768 | defer block_scope.instructions.deinit(mod.gpa); | ||
| 769 | |||
| 770 | const condbr = try addZIRInstSpecial(mod, &block_scope.base, src, zir.Inst.CondBr, .{ | ||
| 771 | .condition = cond, | ||
| 772 | .then_body = undefined, // populated below | ||
| 773 | .else_body = undefined, // populated below | ||
| 774 | }, .{}); | ||
| 775 | |||
| 776 | const block = try addZIRInstBlock(mod, scope, src, .{ | ||
| 777 | .instructions = try block_scope.arena.dupe(*zir.Inst, block_scope.instructions.items), | ||
| 778 | }); | ||
| 779 | |||
| 780 | // Most result location types can be forwarded directly; however | ||
| 781 | // if we need to write to a pointer which has an inferred type, | ||
| 782 | // proper type inference requires peer type resolution on the if's | ||
| 783 | // branches. | ||
| 784 | const branch_rl: ResultLoc = switch (rl) { | ||
| 785 | .discard, .none, .ty, .ptr, .ref => rl, | ||
| 786 | .inferred_ptr, .bitcasted_ptr, .block_ptr => .{ .block_ptr = block }, | ||
| 787 | }; | ||
| 788 | |||
| 789 | var err_scope: Scope.GenZIR = .{ | ||
| 790 | .parent = scope, | ||
| 791 | .decl = block_scope.decl, | ||
| 792 | .arena = block_scope.arena, | ||
| 793 | .instructions = .{}, | ||
| 794 | }; | ||
| 795 | defer err_scope.instructions.deinit(mod.gpa); | ||
| 796 | |||
| 797 | var err_val_scope: Scope.LocalVal = undefined; | ||
| 798 | const err_sub_scope = blk: { | ||
| 799 | const payload = node.payload orelse | ||
| 800 | break :blk &err_scope.base; | ||
| 801 | |||
| 802 | const err_name = tree.tokenSlice(payload.castTag(.Payload).?.error_symbol.firstToken()); | ||
| 803 | if (mem.eql(u8, err_name, "_")) | ||
| 804 | break :blk &err_scope.base; | ||
| 805 | |||
| 806 | const unwrapped_err_ptr = try addZIRUnOp(mod, &err_scope.base, src, .unwrap_err_code, err_union_ptr); | ||
| 807 | err_val_scope = .{ | ||
| 808 | .parent = &err_scope.base, | ||
| 809 | .gen_zir = &err_scope, | ||
| 810 | .name = err_name, | ||
| 811 | .inst = try addZIRUnOp(mod, &err_scope.base, src, .deref, unwrapped_err_ptr), | ||
| 812 | }; | ||
| 813 | break :blk &err_val_scope.base; | ||
| 814 | }; | ||
| 815 | |||
| 816 | _ = try addZIRInst(mod, &err_scope.base, src, zir.Inst.Break, .{ | ||
| 817 | .block = block, | ||
| 818 | .operand = try expr(mod, err_sub_scope, branch_rl, node.rhs), | ||
| 819 | }, .{}); | ||
| 820 | |||
| 821 | var not_err_scope: Scope.GenZIR = .{ | ||
| 822 | .parent = scope, | ||
| 823 | .decl = block_scope.decl, | ||
| 824 | .arena = block_scope.arena, | ||
| 825 | .instructions = .{}, | ||
| 826 | }; | ||
| 827 | defer not_err_scope.instructions.deinit(mod.gpa); | ||
| 828 | |||
| 829 | const unwrapped_payload = try addZIRUnOp(mod, &not_err_scope.base, src, .unwrap_err_unsafe, err_union_ptr); | ||
| 830 | _ = try addZIRInst(mod, &not_err_scope.base, src, zir.Inst.Break, .{ | ||
| 831 | .block = block, | ||
| 832 | .operand = unwrapped_payload, | ||
| 833 | }, .{}); | ||
| 834 | |||
| 835 | condbr.positionals.then_body = .{ .instructions = try err_scope.arena.dupe(*zir.Inst, err_scope.instructions.items) }; | ||
| 836 | condbr.positionals.else_body = .{ .instructions = try not_err_scope.arena.dupe(*zir.Inst, not_err_scope.instructions.items) }; | ||
| 837 | return rlWrap(mod, scope, rl, &block.base); | ||
| 838 | } | ||
| 839 | |||
| 753 | /// Return whether the identifier names of two tokens are equal. Resolves @"" tokens without allocating. | 840 | /// Return whether the identifier names of two tokens are equal. Resolves @"" tokens without allocating. |
| 754 | /// OK in theory it could do it without allocating. This implementation allocates when the @"" form is used. | 841 | /// OK in theory it could do it without allocating. This implementation allocates when the @"" form is used. |
| 755 | fn tokenIdentEql(mod: *Module, scope: *Scope, token1: ast.TokenIndex, token2: ast.TokenIndex) !bool { | 842 | fn tokenIdentEql(mod: *Module, scope: *Scope, token1: ast.TokenIndex, token2: ast.TokenIndex) !bool { |
| ... | @@ -1317,7 +1404,7 @@ fn forExpr(mod: *Module, scope: *Scope, rl: ResultLoc, for_node: *ast.Node.For) | ... | @@ -1317,7 +1404,7 @@ fn forExpr(mod: *Module, scope: *Scope, rl: ResultLoc, for_node: *ast.Node.For) |
| 1317 | .inferred_ptr, .bitcasted_ptr, .block_ptr => .{ .block_ptr = for_block }, | 1404 | .inferred_ptr, .bitcasted_ptr, .block_ptr => .{ .block_ptr = for_block }, |
| 1318 | }; | 1405 | }; |
| 1319 | 1406 | ||
| 1320 | var index_scope: Scope.LocalPtr = undefined; | 1407 | var index_scope: Scope.LocalVal = undefined; |
| 1321 | const then_sub_scope = blk: { | 1408 | const then_sub_scope = blk: { |
| 1322 | const payload = for_node.payload.castTag(.PointerIndexPayload).?; | 1409 | const payload = for_node.payload.castTag(.PointerIndexPayload).?; |
| 1323 | const is_ptr = payload.ptr_token != null; | 1410 | const is_ptr = payload.ptr_token != null; |
| ... | @@ -1335,12 +1422,11 @@ fn forExpr(mod: *Module, scope: *Scope, rl: ResultLoc, for_node: *ast.Node.For) | ... | @@ -1335,12 +1422,11 @@ fn forExpr(mod: *Module, scope: *Scope, rl: ResultLoc, for_node: *ast.Node.For) |
| 1335 | if (mem.eql(u8, index_name, "_")) { | 1422 | if (mem.eql(u8, index_name, "_")) { |
| 1336 | break :blk &then_scope.base; | 1423 | break :blk &then_scope.base; |
| 1337 | } | 1424 | } |
| 1338 | // TODO ensure this is const | ||
| 1339 | index_scope = .{ | 1425 | index_scope = .{ |
| 1340 | .parent = &then_scope.base, | 1426 | .parent = &then_scope.base, |
| 1341 | .gen_zir = &then_scope, | 1427 | .gen_zir = &then_scope, |
| 1342 | .name = index_name, | 1428 | .name = index_name, |
| 1343 | .ptr = index_ptr, | 1429 | .inst = index, |
| 1344 | }; | 1430 | }; |
| 1345 | break :blk &index_scope.base; | 1431 | break :blk &index_scope.base; |
| 1346 | }; | 1432 | }; |
src-self-hosted/zir.zig+4| ... | @@ -253,6 +253,8 @@ pub const Inst = struct { | ... | @@ -253,6 +253,8 @@ pub const Inst = struct { |
| 253 | unwrap_err_safe, | 253 | unwrap_err_safe, |
| 254 | /// Same as previous, but without safety checks. Used for orelse, if and while | 254 | /// Same as previous, but without safety checks. Used for orelse, if and while |
| 255 | unwrap_err_unsafe, | 255 | unwrap_err_unsafe, |
| 256 | /// Gets the error code value of an error union | ||
| 257 | unwrap_err_code, | ||
| 256 | /// Takes a *E!T and raises a compiler error if T != void | 258 | /// Takes a *E!T and raises a compiler error if T != void |
| 257 | ensure_err_payload_void, | 259 | ensure_err_payload_void, |
| 258 | /// Enum literal | 260 | /// Enum literal |
| ... | @@ -298,6 +300,7 @@ pub const Inst = struct { | ... | @@ -298,6 +300,7 @@ pub const Inst = struct { |
| 298 | .unwrap_optional_unsafe, | 300 | .unwrap_optional_unsafe, |
| 299 | .unwrap_err_safe, | 301 | .unwrap_err_safe, |
| 300 | .unwrap_err_unsafe, | 302 | .unwrap_err_unsafe, |
| 303 | .unwrap_err_code, | ||
| 301 | .ensure_err_payload_void, | 304 | .ensure_err_payload_void, |
| 302 | .anyframe_type, | 305 | .anyframe_type, |
| 303 | .bitnot, | 306 | .bitnot, |
| ... | @@ -454,6 +457,7 @@ pub const Inst = struct { | ... | @@ -454,6 +457,7 @@ pub const Inst = struct { |
| 454 | .unwrap_optional_unsafe, | 457 | .unwrap_optional_unsafe, |
| 455 | .unwrap_err_safe, | 458 | .unwrap_err_safe, |
| 456 | .unwrap_err_unsafe, | 459 | .unwrap_err_unsafe, |
| 460 | .unwrap_err_code, | ||
| 457 | .ptr_type, | 461 | .ptr_type, |
| 458 | .ensure_err_payload_void, | 462 | .ensure_err_payload_void, |
| 459 | .enum_literal, | 463 | .enum_literal, |
src-self-hosted/zir_sema.zig+15-17| ... | @@ -120,6 +120,7 @@ pub fn analyzeInst(mod: *Module, scope: *Scope, old_inst: *zir.Inst) InnerError! | ... | @@ -120,6 +120,7 @@ pub fn analyzeInst(mod: *Module, scope: *Scope, old_inst: *zir.Inst) InnerError! |
| 120 | .unwrap_optional_unsafe => return analyzeInstUnwrapOptional(mod, scope, old_inst.castTag(.unwrap_optional_unsafe).?, false), | 120 | .unwrap_optional_unsafe => return analyzeInstUnwrapOptional(mod, scope, old_inst.castTag(.unwrap_optional_unsafe).?, false), |
| 121 | .unwrap_err_safe => return analyzeInstUnwrapErr(mod, scope, old_inst.castTag(.unwrap_err_safe).?, true), | 121 | .unwrap_err_safe => return analyzeInstUnwrapErr(mod, scope, old_inst.castTag(.unwrap_err_safe).?, true), |
| 122 | .unwrap_err_unsafe => return analyzeInstUnwrapErr(mod, scope, old_inst.castTag(.unwrap_err_unsafe).?, false), | 122 | .unwrap_err_unsafe => return analyzeInstUnwrapErr(mod, scope, old_inst.castTag(.unwrap_err_unsafe).?, false), |
| 123 | .unwrap_err_code => return analyzeInstUnwrapErrCode(mod, scope, old_inst.castTag(.unwrap_err_code).?), | ||
| 123 | .ensure_err_payload_void => return analyzeInstEnsureErrPayloadVoid(mod, scope, old_inst.castTag(.ensure_err_payload_void).?), | 124 | .ensure_err_payload_void => return analyzeInstEnsureErrPayloadVoid(mod, scope, old_inst.castTag(.ensure_err_payload_void).?), |
| 124 | .array_type => return analyzeInstArrayType(mod, scope, old_inst.castTag(.array_type).?), | 125 | .array_type => return analyzeInstArrayType(mod, scope, old_inst.castTag(.array_type).?), |
| 125 | .array_type_sentinel => return analyzeInstArrayTypeSentinel(mod, scope, old_inst.castTag(.array_type_sentinel).?), | 126 | .array_type_sentinel => return analyzeInstArrayTypeSentinel(mod, scope, old_inst.castTag(.array_type_sentinel).?), |
| ... | @@ -800,11 +801,12 @@ fn analyzeInstUnwrapOptional(mod: *Module, scope: *Scope, unwrap: *zir.Inst.UnOp | ... | @@ -800,11 +801,12 @@ fn analyzeInstUnwrapOptional(mod: *Module, scope: *Scope, unwrap: *zir.Inst.UnOp |
| 800 | const operand = try resolveInst(mod, scope, unwrap.positionals.operand); | 801 | const operand = try resolveInst(mod, scope, unwrap.positionals.operand); |
| 801 | assert(operand.ty.zigTypeTag() == .Pointer); | 802 | assert(operand.ty.zigTypeTag() == .Pointer); |
| 802 | 803 | ||
| 803 | if (operand.ty.elemType().zigTypeTag() != .Optional) { | 804 | const elem_type = operand.ty.elemType(); |
| 804 | return mod.fail(scope, unwrap.base.src, "expected optional type, found {}", .{operand.ty.elemType()}); | 805 | if (elem_type.zigTypeTag() != .Optional) { |
| 806 | return mod.fail(scope, unwrap.base.src, "expected optional type, found {}", .{elem_type}); | ||
| 805 | } | 807 | } |
| 806 | 808 | ||
| 807 | const child_type = try operand.ty.elemType().optionalChildAlloc(scope.arena()); | 809 | const child_type = try elem_type.optionalChildAlloc(scope.arena()); |
| 808 | const child_pointer = try mod.simplePtrType(scope, unwrap.base.src, child_type, operand.ty.isConstPtr(), .One); | 810 | const child_pointer = try mod.simplePtrType(scope, unwrap.base.src, child_type, operand.ty.isConstPtr(), .One); |
| 809 | 811 | ||
| 810 | if (operand.value()) |val| { | 812 | if (operand.value()) |val| { |
| ... | @@ -829,6 +831,10 @@ fn analyzeInstUnwrapErr(mod: *Module, scope: *Scope, unwrap: *zir.Inst.UnOp, saf | ... | @@ -829,6 +831,10 @@ fn analyzeInstUnwrapErr(mod: *Module, scope: *Scope, unwrap: *zir.Inst.UnOp, saf |
| 829 | return mod.fail(scope, unwrap.base.src, "TODO implement analyzeInstUnwrapErr", .{}); | 831 | return mod.fail(scope, unwrap.base.src, "TODO implement analyzeInstUnwrapErr", .{}); |
| 830 | } | 832 | } |
| 831 | 833 | ||
| 834 | fn analyzeInstUnwrapErrCode(mod: *Module, scope: *Scope, unwrap: *zir.Inst.UnOp) InnerError!*Inst { | ||
| 835 | return mod.fail(scope, unwrap.base.src, "TODO implement analyzeInstUnwrapErrCode", .{}); | ||
| 836 | } | ||
| 837 | |||
| 832 | fn analyzeInstEnsureErrPayloadVoid(mod: *Module, scope: *Scope, unwrap: *zir.Inst.UnOp) InnerError!*Inst { | 838 | fn analyzeInstEnsureErrPayloadVoid(mod: *Module, scope: *Scope, unwrap: *zir.Inst.UnOp) InnerError!*Inst { |
| 833 | return mod.fail(scope, unwrap.base.src, "TODO implement analyzeInstEnsureErrPayloadVoid", .{}); | 839 | return mod.fail(scope, unwrap.base.src, "TODO implement analyzeInstEnsureErrPayloadVoid", .{}); |
| 834 | } | 840 | } |
| ... | @@ -964,7 +970,8 @@ fn analyzeInstFieldPtr(mod: *Module, scope: *Scope, fieldptr: *zir.Inst.FieldPtr | ... | @@ -964,7 +970,8 @@ fn analyzeInstFieldPtr(mod: *Module, scope: *Scope, fieldptr: *zir.Inst.FieldPtr |
| 964 | const entry = if (val.cast(Value.Payload.ErrorSet)) |payload| | 970 | const entry = if (val.cast(Value.Payload.ErrorSet)) |payload| |
| 965 | (payload.fields.getEntry(field_name) orelse | 971 | (payload.fields.getEntry(field_name) orelse |
| 966 | return mod.fail(scope, fieldptr.base.src, "no error named '{}' in '{}'", .{ field_name, child_type })).* | 972 | return mod.fail(scope, fieldptr.base.src, "no error named '{}' in '{}'", .{ field_name, child_type })).* |
| 967 | else try mod.getErrorValue(field_name); | 973 | else |
| 974 | try mod.getErrorValue(field_name); | ||
| 968 | 975 | ||
| 969 | const error_payload = try scope.arena().create(Value.Payload.Error); | 976 | const error_payload = try scope.arena().create(Value.Payload.Error); |
| 970 | error_payload.* = .{ | 977 | error_payload.* = .{ |
| ... | @@ -1298,17 +1305,7 @@ fn analyzeInstCmp( | ... | @@ -1298,17 +1305,7 @@ fn analyzeInstCmp( |
| 1298 | { | 1305 | { |
| 1299 | // comparing null with optionals | 1306 | // comparing null with optionals |
| 1300 | const opt_operand = if (lhs_ty_tag == .Optional) lhs else rhs; | 1307 | const opt_operand = if (lhs_ty_tag == .Optional) lhs else rhs; |
| 1301 | if (opt_operand.value()) |opt_val| { | 1308 | return mod.analyzeIsNull(scope, inst.base.src, opt_operand, op == .neq); |
| 1302 | const is_null = opt_val.isNull(); | ||
| 1303 | return mod.constBool(scope, inst.base.src, if (op == .eq) is_null else !is_null); | ||
| 1304 | } | ||
| 1305 | const b = try mod.requireRuntimeBlock(scope, inst.base.src); | ||
| 1306 | const inst_tag: Inst.Tag = switch (op) { | ||
| 1307 | .eq => .isnull, | ||
| 1308 | .neq => .isnonnull, | ||
| 1309 | else => unreachable, | ||
| 1310 | }; | ||
| 1311 | return mod.addUnOp(b, inst.base.src, Type.initTag(.bool), inst_tag, opt_operand); | ||
| 1312 | } else if (is_equality_cmp and | 1309 | } else if (is_equality_cmp and |
| 1313 | ((lhs_ty_tag == .Null and rhs.ty.isCPtr()) or (rhs_ty_tag == .Null and lhs.ty.isCPtr()))) | 1310 | ((lhs_ty_tag == .Null and rhs.ty.isCPtr()) or (rhs_ty_tag == .Null and lhs.ty.isCPtr()))) |
| 1314 | { | 1311 | { |
| ... | @@ -1356,8 +1353,9 @@ fn analyzeInstIsNonNull(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp, inver | ... | @@ -1356,8 +1353,9 @@ fn analyzeInstIsNonNull(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp, inver |
| 1356 | return mod.analyzeIsNull(scope, inst.base.src, operand, invert_logic); | 1353 | return mod.analyzeIsNull(scope, inst.base.src, operand, invert_logic); |
| 1357 | } | 1354 | } |
| 1358 | 1355 | ||
| 1359 | fn analyzeInstIsErr(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp, invert_logic: bool) InnerError!*Inst { | 1356 | fn analyzeInstIsErr(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp) InnerError!*Inst { |
| 1360 | return mod.fail(scope, inst.base.src, "TODO implement analyzeInstIsErr", .{}); | 1357 | const operand = try resolveInst(mod, scope, inst.positionals.operand); |
| 1358 | return mod.analyzeIsErr(scope, inst.base.src, operand); | ||
| 1361 | } | 1359 | } |
| 1362 | 1360 | ||
| 1363 | fn analyzeInstCondBr(mod: *Module, scope: *Scope, inst: *zir.Inst.CondBr) InnerError!*Inst { | 1361 | fn analyzeInstCondBr(mod: *Module, scope: *Scope, inst: *zir.Inst.CondBr) InnerError!*Inst { |