| ... | ... | @@ -372,14 +372,14 @@ pub fn analyzeBody( |
| 372 | 372 | //.error_set_decl_anon => try sema.zirErrorSetDecl(block, inst, .anon), |
| 373 | 373 | //.error_set_decl_func => try sema.zirErrorSetDecl(block, inst, .func), |
| 374 | 374 | |
| 375 | | //.add => try sema.zirArithmetic(block, inst), |
| 376 | | //.addwrap => try sema.zirArithmetic(block, inst), |
| 377 | | //.div => try sema.zirArithmetic(block, inst), |
| 378 | | //.mod_rem => try sema.zirArithmetic(block, inst), |
| 379 | | //.mul => try sema.zirArithmetic(block, inst), |
| 380 | | //.mulwrap => try sema.zirArithmetic(block, inst), |
| 381 | | //.sub => try sema.zirArithmetic(block, inst), |
| 382 | | //.subwrap => try sema.zirArithmetic(block, inst), |
| 375 | .add => try sema.zirArithmetic(block, inst), |
| 376 | .addwrap => try sema.zirArithmetic(block, inst), |
| 377 | .div => try sema.zirArithmetic(block, inst), |
| 378 | .mod_rem => try sema.zirArithmetic(block, inst), |
| 379 | .mul => try sema.zirArithmetic(block, inst), |
| 380 | .mulwrap => try sema.zirArithmetic(block, inst), |
| 381 | .sub => try sema.zirArithmetic(block, inst), |
| 382 | .subwrap => try sema.zirArithmetic(block, inst), |
| 383 | 383 | |
| 384 | 384 | //// Instructions that we know to *always* be noreturn based solely on their tag. |
| 385 | 385 | //// These functions match the return type of analyzeBody so that we can |
| ... | ... | @@ -505,35 +505,35 @@ pub fn analyzeBody( |
| 505 | 505 | i = 0; |
| 506 | 506 | continue; |
| 507 | 507 | }, |
| 508 | | //.block_inline => blk: { |
| 509 | | // // Directly analyze the block body without introducing a new block. |
| 510 | | // const inst_data = datas[inst].pl_node; |
| 511 | | // const extra = sema.code.extraData(Zir.Inst.Block, inst_data.payload_index); |
| 512 | | // const inline_body = sema.code.extra[extra.end..][0..extra.data.body_len]; |
| 513 | | // const break_inst = try sema.analyzeBody(block, inline_body); |
| 514 | | // const break_data = datas[break_inst].@"break"; |
| 515 | | // if (inst == break_data.block_inst) { |
| 516 | | // break :blk sema.resolveInst(break_data.operand); |
| 517 | | // } else { |
| 518 | | // return break_inst; |
| 519 | | // } |
| 520 | | //}, |
| 521 | | //.condbr_inline => blk: { |
| 522 | | // const inst_data = datas[inst].pl_node; |
| 523 | | // const cond_src: LazySrcLoc = .{ .node_offset_if_cond = inst_data.src_node }; |
| 524 | | // const extra = sema.code.extraData(Zir.Inst.CondBr, inst_data.payload_index); |
| 525 | | // const then_body = sema.code.extra[extra.end..][0..extra.data.then_body_len]; |
| 526 | | // const else_body = sema.code.extra[extra.end + then_body.len ..][0..extra.data.else_body_len]; |
| 527 | | // const cond = try sema.resolveInstConst(block, cond_src, extra.data.condition); |
| 528 | | // const inline_body = if (cond.val.toBool()) then_body else else_body; |
| 529 | | // const break_inst = try sema.analyzeBody(block, inline_body); |
| 530 | | // const break_data = datas[break_inst].@"break"; |
| 531 | | // if (inst == break_data.block_inst) { |
| 532 | | // break :blk sema.resolveInst(break_data.operand); |
| 533 | | // } else { |
| 534 | | // return break_inst; |
| 535 | | // } |
| 536 | | //}, |
| 508 | .block_inline => blk: { |
| 509 | // Directly analyze the block body without introducing a new block. |
| 510 | const inst_data = datas[inst].pl_node; |
| 511 | const extra = sema.code.extraData(Zir.Inst.Block, inst_data.payload_index); |
| 512 | const inline_body = sema.code.extra[extra.end..][0..extra.data.body_len]; |
| 513 | const break_inst = try sema.analyzeBody(block, inline_body); |
| 514 | const break_data = datas[break_inst].@"break"; |
| 515 | if (inst == break_data.block_inst) { |
| 516 | break :blk sema.resolveInst(break_data.operand); |
| 517 | } else { |
| 518 | return break_inst; |
| 519 | } |
| 520 | }, |
| 521 | .condbr_inline => blk: { |
| 522 | const inst_data = datas[inst].pl_node; |
| 523 | const cond_src: LazySrcLoc = .{ .node_offset_if_cond = inst_data.src_node }; |
| 524 | const extra = sema.code.extraData(Zir.Inst.CondBr, inst_data.payload_index); |
| 525 | const then_body = sema.code.extra[extra.end..][0..extra.data.then_body_len]; |
| 526 | const else_body = sema.code.extra[extra.end + then_body.len ..][0..extra.data.else_body_len]; |
| 527 | const cond = try sema.resolveInstConst(block, cond_src, extra.data.condition); |
| 528 | const inline_body = if (cond.val.toBool()) then_body else else_body; |
| 529 | const break_inst = try sema.analyzeBody(block, inline_body); |
| 530 | const break_data = datas[break_inst].@"break"; |
| 531 | if (inst == break_data.block_inst) { |
| 532 | break :blk sema.resolveInst(break_data.operand); |
| 533 | } else { |
| 534 | return break_inst; |
| 535 | } |
| 536 | }, |
| 537 | 537 | else => @panic("TODO finish updating Sema for AIR memory layout changes and then remove this else prong"), |
| 538 | 538 | }; |
| 539 | 539 | if (sema.getTypeOf(air_inst).isNoReturn()) |
| ... | ... | @@ -1186,7 +1186,7 @@ fn zirRetPtr( |
| 1186 | 1186 | const fn_ty = sema.func.?.owner_decl.ty; |
| 1187 | 1187 | const ret_type = fn_ty.fnReturnType(); |
| 1188 | 1188 | const ptr_type = try Module.simplePtrType(sema.arena, ret_type, true, .One); |
| 1189 | | return block.addNoOp(src, ptr_type, .alloc); |
| 1189 | return block.addTy(.alloc, ptr_type); |
| 1190 | 1190 | } |
| 1191 | 1191 | |
| 1192 | 1192 | fn zirRef(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| ... | ... | @@ -1230,7 +1230,8 @@ fn ensureResultUsed( |
| 1230 | 1230 | operand: Air.Inst.Ref, |
| 1231 | 1231 | src: LazySrcLoc, |
| 1232 | 1232 | ) CompileError!void { |
| 1233 | | switch (operand.ty.zigTypeTag()) { |
| 1233 | const operand_ty = sema.getTypeOf(operand); |
| 1234 | switch (operand_ty.zigTypeTag()) { |
| 1234 | 1235 | .Void, .NoReturn => return, |
| 1235 | 1236 | else => return sema.mod.fail(&block.base, src, "expression value is ignored", .{}), |
| 1236 | 1237 | } |
| ... | ... | @@ -1243,7 +1244,8 @@ fn zirEnsureResultNonError(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Inde |
| 1243 | 1244 | const inst_data = sema.code.instructions.items(.data)[inst].un_node; |
| 1244 | 1245 | const operand = sema.resolveInst(inst_data.operand); |
| 1245 | 1246 | const src = inst_data.src(); |
| 1246 | | switch (operand.ty.zigTypeTag()) { |
| 1247 | const operand_ty = sema.getTypeOf(operand); |
| 1248 | switch (operand_ty.zigTypeTag()) { |
| 1247 | 1249 | .ErrorSet, .ErrorUnion => return sema.mod.fail(&block.base, src, "error is discarded", .{}), |
| 1248 | 1250 | else => return, |
| 1249 | 1251 | } |
| ... | ... | @@ -1257,7 +1259,7 @@ fn zirIndexablePtrLen(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Co |
| 1257 | 1259 | const src = inst_data.src(); |
| 1258 | 1260 | const array_ptr = sema.resolveInst(inst_data.operand); |
| 1259 | 1261 | |
| 1260 | | const elem_ty = array_ptr.ty.elemType(); |
| 1262 | const elem_ty = sema.getTypeOf(array_ptr).elemType(); |
| 1261 | 1263 | if (!elem_ty.isIndexable()) { |
| 1262 | 1264 | const cond_src: LazySrcLoc = .{ .node_offset_for_cond = inst_data.src_node }; |
| 1263 | 1265 | const msg = msg: { |
| ... | ... | @@ -1317,7 +1319,6 @@ fn zirAllocComptime(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Comp |
| 1317 | 1319 | defer tracy.end(); |
| 1318 | 1320 | |
| 1319 | 1321 | const inst_data = sema.code.instructions.items(.data)[inst].un_node; |
| 1320 | | const src = inst_data.src(); |
| 1321 | 1322 | const ty_src: LazySrcLoc = .{ .node_offset_var_decl_ty = inst_data.src_node }; |
| 1322 | 1323 | const var_type = try sema.resolveType(block, ty_src, inst_data.operand); |
| 1323 | 1324 | const ptr_type = try Module.simplePtrType(sema.arena, var_type, true, .One); |
| ... | ... | @@ -1329,10 +1330,7 @@ fn zirAllocComptime(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Comp |
| 1329 | 1330 | .val = undefined, // astgen guarantees there will be a store before the first load |
| 1330 | 1331 | }, |
| 1331 | 1332 | }; |
| 1332 | | return sema.mod.constInst(sema.arena, src, .{ |
| 1333 | | .ty = ptr_type, |
| 1334 | | .val = Value.initPayload(&val_payload.base), |
| 1335 | | }); |
| 1333 | return sema.addConstant(ptr_type, Value.initPayload(&val_payload.base)); |
| 1336 | 1334 | } |
| 1337 | 1335 | |
| 1338 | 1336 | fn zirAllocInferredComptime(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| ... | ... | @@ -1351,7 +1349,7 @@ fn zirAlloc(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError |
| 1351 | 1349 | const var_type = try sema.resolveType(block, ty_src, inst_data.operand); |
| 1352 | 1350 | const ptr_type = try Module.simplePtrType(sema.arena, var_type, true, .One); |
| 1353 | 1351 | try sema.requireRuntimeBlock(block, var_decl_src); |
| 1354 | | return block.addNoOp(var_decl_src, ptr_type, .alloc); |
| 1352 | return block.addTy(.alloc, ptr_type); |
| 1355 | 1353 | } |
| 1356 | 1354 | |
| 1357 | 1355 | fn zirAllocMut(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| ... | ... | @@ -1365,7 +1363,7 @@ fn zirAllocMut(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileEr |
| 1365 | 1363 | try sema.validateVarType(block, ty_src, var_type); |
| 1366 | 1364 | const ptr_type = try Module.simplePtrType(sema.arena, var_type, true, .One); |
| 1367 | 1365 | try sema.requireRuntimeBlock(block, var_decl_src); |
| 1368 | | return block.addNoOp(var_decl_src, ptr_type, .alloc); |
| 1366 | return block.addTy(.alloc, ptr_type); |
| 1369 | 1367 | } |
| 1370 | 1368 | |
| 1371 | 1369 | fn zirAllocInferred( |
| ... | ... | @@ -1388,12 +1386,9 @@ fn zirAllocInferred( |
| 1388 | 1386 | // not needed in the case of constant values. However here, we plan to "downgrade" |
| 1389 | 1387 | // to a normal instruction when we hit `resolve_inferred_alloc`. So we append |
| 1390 | 1388 | // to the block even though it is currently a `.constant`. |
| 1391 | | const result = try sema.mod.constInst(sema.arena, src, .{ |
| 1392 | | .ty = inferred_alloc_ty, |
| 1393 | | .val = Value.initPayload(&val_payload.base), |
| 1394 | | }); |
| 1389 | const result = try sema.addConstant(inferred_alloc_ty, Value.initPayload(&val_payload.base)); |
| 1395 | 1390 | try sema.requireFunctionBlock(block, src); |
| 1396 | | try block.instructions.append(sema.gpa, result); |
| 1391 | try block.instructions.append(sema.gpa, refToIndex(result).?); |
| 1397 | 1392 | return result; |
| 1398 | 1393 | } |
| 1399 | 1394 | |
| ... | ... | @@ -1630,18 +1625,21 @@ fn zirParamType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileE |
| 1630 | 1625 | const tracy = trace(@src()); |
| 1631 | 1626 | defer tracy.end(); |
| 1632 | 1627 | |
| 1633 | | const src: LazySrcLoc = .unneeded; |
| 1628 | const src = sema.src; |
| 1629 | const fn_inst_src = sema.src; |
| 1630 | |
| 1634 | 1631 | const inst_data = sema.code.instructions.items(.data)[inst].param_type; |
| 1635 | 1632 | const fn_inst = sema.resolveInst(inst_data.callee); |
| 1633 | const fn_inst_ty = sema.getTypeOf(fn_inst); |
| 1636 | 1634 | const param_index = inst_data.param_index; |
| 1637 | 1635 | |
| 1638 | | const fn_ty: Type = switch (fn_inst.ty.zigTypeTag()) { |
| 1639 | | .Fn => fn_inst.ty, |
| 1636 | const fn_ty: Type = switch (fn_inst_ty.zigTypeTag()) { |
| 1637 | .Fn => fn_inst_ty, |
| 1640 | 1638 | .BoundFn => { |
| 1641 | | return sema.mod.fail(&block.base, fn_inst.src, "TODO implement zirParamType for method call syntax", .{}); |
| 1639 | return sema.mod.fail(&block.base, fn_inst_src, "TODO implement zirParamType for method call syntax", .{}); |
| 1642 | 1640 | }, |
| 1643 | 1641 | else => { |
| 1644 | | return sema.mod.fail(&block.base, fn_inst.src, "expected function, found '{}'", .{fn_inst.ty}); |
| 1642 | return sema.mod.fail(&block.base, fn_inst_src, "expected function, found '{}'", .{fn_inst_ty}); |
| 1645 | 1643 | }, |
| 1646 | 1644 | }; |
| 1647 | 1645 | |
| ... | ... | @@ -1711,23 +1709,20 @@ fn zirIntBig(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileErro |
| 1711 | 1709 | const limbs = try arena.alloc(std.math.big.Limb, int.len); |
| 1712 | 1710 | mem.copy(u8, mem.sliceAsBytes(limbs), limb_bytes); |
| 1713 | 1711 | |
| 1714 | | return sema.mod.constInst(arena, .unneeded, .{ |
| 1715 | | .ty = Type.initTag(.comptime_int), |
| 1716 | | .val = try Value.Tag.int_big_positive.create(arena, limbs), |
| 1717 | | }); |
| 1712 | return sema.addConstant( |
| 1713 | Type.initTag(.comptime_int), |
| 1714 | try Value.Tag.int_big_positive.create(arena, limbs), |
| 1715 | ); |
| 1718 | 1716 | } |
| 1719 | 1717 | |
| 1720 | 1718 | fn zirFloat(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 1721 | 1719 | _ = block; |
| 1722 | 1720 | const arena = sema.arena; |
| 1723 | | const inst_data = sema.code.instructions.items(.data)[inst].float; |
| 1724 | | const src = inst_data.src(); |
| 1725 | | const number = inst_data.number; |
| 1726 | | |
| 1727 | | return sema.mod.constInst(arena, src, .{ |
| 1728 | | .ty = Type.initTag(.comptime_float), |
| 1729 | | .val = try Value.Tag.float_32.create(arena, number), |
| 1730 | | }); |
| 1721 | const number = sema.code.instructions.items(.data)[inst].float; |
| 1722 | return sema.addConstant( |
| 1723 | Type.initTag(.comptime_float), |
| 1724 | try Value.Tag.float_64.create(arena, number), |
| 1725 | ); |
| 1731 | 1726 | } |
| 1732 | 1727 | |
| 1733 | 1728 | fn zirFloat128(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| ... | ... | @@ -1735,13 +1730,11 @@ fn zirFloat128(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileEr |
| 1735 | 1730 | const arena = sema.arena; |
| 1736 | 1731 | const inst_data = sema.code.instructions.items(.data)[inst].pl_node; |
| 1737 | 1732 | const extra = sema.code.extraData(Zir.Inst.Float128, inst_data.payload_index).data; |
| 1738 | | const src = inst_data.src(); |
| 1739 | 1733 | const number = extra.get(); |
| 1740 | | |
| 1741 | | return sema.mod.constInst(arena, src, .{ |
| 1742 | | .ty = Type.initTag(.comptime_float), |
| 1743 | | .val = try Value.Tag.float_128.create(arena, number), |
| 1744 | | }); |
| 1734 | return sema.addConstant( |
| 1735 | Type.initTag(.comptime_float), |
| 1736 | try Value.Tag.float_128.create(arena, number), |
| 1737 | ); |
| 1745 | 1738 | } |
| 1746 | 1739 | |
| 1747 | 1740 | fn zirCompileError(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Zir.Inst.Index { |
| ... | ... | @@ -1785,10 +1778,7 @@ fn zirCompileLog( |
| 1785 | 1778 | if (!gop.found_existing) { |
| 1786 | 1779 | gop.value_ptr.* = src_node; |
| 1787 | 1780 | } |
| 1788 | | return sema.mod.constInst(sema.arena, src, .{ |
| 1789 | | .ty = Type.initTag(.void), |
| 1790 | | .val = Value.initTag(.void_value), |
| 1791 | | }); |
| 1781 | return Air.Inst.Ref.void_value; |
| 1792 | 1782 | } |
| 1793 | 1783 | |
| 1794 | 1784 | fn zirRepeat(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Zir.Inst.Index { |
| ... | ... | @@ -1817,18 +1807,26 @@ fn zirLoop(sema: *Sema, parent_block: *Scope.Block, inst: Zir.Inst.Index) Compil |
| 1817 | 1807 | const src = inst_data.src(); |
| 1818 | 1808 | const extra = sema.code.extraData(Zir.Inst.Block, inst_data.payload_index); |
| 1819 | 1809 | const body = sema.code.extra[extra.end..][0..extra.data.body_len]; |
| 1810 | const gpa = sema.gpa; |
| 1820 | 1811 | |
| 1821 | 1812 | // AIR expects a block outside the loop block too. |
| 1822 | | const block_inst = try sema.arena.create(Inst.Block); |
| 1823 | | block_inst.* = .{ |
| 1824 | | .base = .{ |
| 1825 | | .tag = Inst.Block.base_tag, |
| 1826 | | .ty = undefined, |
| 1827 | | .src = src, |
| 1828 | | }, |
| 1829 | | .body = undefined, |
| 1830 | | }; |
| 1831 | | |
| 1813 | // Reserve space for a Loop instruction so that generated Break instructions can |
| 1814 | // point to it, even if it doesn't end up getting used because the code ends up being |
| 1815 | // comptime evaluated. |
| 1816 | const block_inst = @intCast(Air.Inst.Index, sema.air_instructions.len); |
| 1817 | const loop_inst = block_inst + 1; |
| 1818 | try sema.air_instructions.ensureUnusedCapacity(gpa, 2); |
| 1819 | sema.air_instructions.appendAssumeCapacity(.{ |
| 1820 | .tag = .block, |
| 1821 | .data = undefined, |
| 1822 | }); |
| 1823 | sema.air_instructions.appendAssumeCapacity(.{ |
| 1824 | .tag = .loop, |
| 1825 | .data = .{ .ty_pl = .{ |
| 1826 | .ty = .noreturn_type, |
| 1827 | .payload = undefined, |
| 1828 | } }, |
| 1829 | }); |
| 1832 | 1830 | var label: Scope.Block.Label = .{ |
| 1833 | 1831 | .zir_block = inst, |
| 1834 | 1832 | .merges = .{ |
| ... | ... | @@ -1844,33 +1842,24 @@ fn zirLoop(sema: *Sema, parent_block: *Scope.Block, inst: Zir.Inst.Index) Compil |
| 1844 | 1842 | child_block.runtime_index += 1; |
| 1845 | 1843 | const merges = &child_block.label.?.merges; |
| 1846 | 1844 | |
| 1847 | | defer child_block.instructions.deinit(sema.gpa); |
| 1848 | | defer merges.results.deinit(sema.gpa); |
| 1849 | | defer merges.br_list.deinit(sema.gpa); |
| 1850 | | |
| 1851 | | // Reserve space for a Loop instruction so that generated Break instructions can |
| 1852 | | // point to it, even if it doesn't end up getting used because the code ends up being |
| 1853 | | // comptime evaluated. |
| 1854 | | const loop_inst = try sema.arena.create(Inst.Loop); |
| 1855 | | loop_inst.* = .{ |
| 1856 | | .base = .{ |
| 1857 | | .tag = Inst.Loop.base_tag, |
| 1858 | | .ty = Type.initTag(.noreturn), |
| 1859 | | .src = src, |
| 1860 | | }, |
| 1861 | | .body = undefined, |
| 1862 | | }; |
| 1845 | defer child_block.instructions.deinit(gpa); |
| 1846 | defer merges.results.deinit(gpa); |
| 1847 | defer merges.br_list.deinit(gpa); |
| 1863 | 1848 | |
| 1864 | 1849 | var loop_block = child_block.makeSubBlock(); |
| 1865 | | defer loop_block.instructions.deinit(sema.gpa); |
| 1850 | defer loop_block.instructions.deinit(gpa); |
| 1866 | 1851 | |
| 1867 | 1852 | _ = try sema.analyzeBody(&loop_block, body); |
| 1868 | 1853 | |
| 1869 | 1854 | // Loop repetition is implied so the last instruction may or may not be a noreturn instruction. |
| 1855 | try child_block.instructions.append(gpa, loop_inst); |
| 1870 | 1856 | |
| 1871 | | try child_block.instructions.append(sema.gpa, &loop_inst.base); |
| 1872 | | loop_inst.body = .{ .instructions = try sema.arena.dupe(Air.Inst.Index, loop_block.instructions.items) }; |
| 1873 | | |
| 1857 | try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.Block).Struct.fields.len + |
| 1858 | loop_block.instructions.items.len); |
| 1859 | sema.air_instructions.items(.data)[loop_inst].ty_pl.payload = sema.addExtraAssumeCapacity( |
| 1860 | Air.Block{ .body_len = @intCast(u32, loop_block.instructions.items.len) }, |
| 1861 | ); |
| 1862 | sema.air_extra.appendAssumeCapacity(loop_block.instructions.items); |
| 1874 | 1863 | return sema.analyzeBlockBody(parent_block, src, &child_block, merges); |
| 1875 | 1864 | } |
| 1876 | 1865 | |
| ... | ... | @@ -1890,27 +1879,28 @@ fn zirSuspendBlock(sema: *Sema, parent_block: *Scope.Block, inst: Zir.Inst.Index |
| 1890 | 1879 | return sema.mod.fail(&parent_block.base, src, "TODO: implement Sema.zirSuspendBlock", .{}); |
| 1891 | 1880 | } |
| 1892 | 1881 | |
| 1893 | | fn zirBlock(sema: *Sema, parent_block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 1882 | fn zirBlock( |
| 1883 | sema: *Sema, |
| 1884 | parent_block: *Scope.Block, |
| 1885 | inst: Zir.Inst.Index, |
| 1886 | ) CompileError!Air.Inst.Ref { |
| 1894 | 1887 | const tracy = trace(@src()); |
| 1895 | 1888 | defer tracy.end(); |
| 1896 | 1889 | |
| 1897 | | const inst_data = sema.code.instructions.items(.data)[inst].pl_node; |
| 1898 | | const src = inst_data.src(); |
| 1899 | | const extra = sema.code.extraData(Zir.Inst.Block, inst_data.payload_index); |
| 1890 | const pl_node = sema.code.instructions.items(.data)[inst].pl_node; |
| 1891 | const src = pl_node.src(); |
| 1892 | const extra = sema.code.extraData(Zir.Inst.Block, pl_node.payload_index); |
| 1900 | 1893 | const body = sema.code.extra[extra.end..][0..extra.data.body_len]; |
| 1894 | const gpa = sema.gpa; |
| 1901 | 1895 | |
| 1902 | 1896 | // Reserve space for a Block instruction so that generated Break instructions can |
| 1903 | 1897 | // point to it, even if it doesn't end up getting used because the code ends up being |
| 1904 | 1898 | // comptime evaluated. |
| 1905 | | const block_inst = try sema.arena.create(Inst.Block); |
| 1906 | | block_inst.* = .{ |
| 1907 | | .base = .{ |
| 1908 | | .tag = Inst.Block.base_tag, |
| 1909 | | .ty = undefined, // Set after analysis. |
| 1910 | | .src = src, |
| 1911 | | }, |
| 1912 | | .body = undefined, |
| 1913 | | }; |
| 1899 | const block_inst = @intCast(Air.Inst.Index, sema.air_instructions.len); |
| 1900 | try sema.air_instructions.append(gpa, .{ |
| 1901 | .tag = .block, |
| 1902 | .data = undefined, |
| 1903 | }); |
| 1914 | 1904 | |
| 1915 | 1905 | var label: Scope.Block.Label = .{ |
| 1916 | 1906 | .zir_block = inst, |
| ... | ... | @@ -1932,9 +1922,9 @@ fn zirBlock(sema: *Sema, parent_block: *Scope.Block, inst: Zir.Inst.Index) Compi |
| 1932 | 1922 | }; |
| 1933 | 1923 | const merges = &child_block.label.?.merges; |
| 1934 | 1924 | |
| 1935 | | defer child_block.instructions.deinit(sema.gpa); |
| 1936 | | defer merges.results.deinit(sema.gpa); |
| 1937 | | defer merges.br_list.deinit(sema.gpa); |
| 1925 | defer child_block.instructions.deinit(gpa); |
| 1926 | defer merges.results.deinit(gpa); |
| 1927 | defer merges.br_list.deinit(gpa); |
| 1938 | 1928 | |
| 1939 | 1929 | _ = try sema.analyzeBody(&child_block, body); |
| 1940 | 1930 | |
| ... | ... | @@ -1963,6 +1953,8 @@ fn analyzeBlockBody( |
| 1963 | 1953 | const tracy = trace(@src()); |
| 1964 | 1954 | defer tracy.end(); |
| 1965 | 1955 | |
| 1956 | const gpa = sema.gpa; |
| 1957 | |
| 1966 | 1958 | // Blocks must terminate with noreturn instruction. |
| 1967 | 1959 | assert(child_block.instructions.items.len != 0); |
| 1968 | 1960 | assert(child_block.instructions.items[child_block.instructions.items.len - 1].ty.isNoReturn()); |
| ... | ... | @@ -1971,7 +1963,7 @@ fn analyzeBlockBody( |
| 1971 | 1963 | // No need for a block instruction. We can put the new instructions |
| 1972 | 1964 | // directly into the parent block. |
| 1973 | 1965 | const copied_instructions = try sema.arena.dupe(Air.Inst.Index, child_block.instructions.items); |
| 1974 | | try parent_block.instructions.appendSlice(sema.gpa, copied_instructions); |
| 1966 | try parent_block.instructions.appendSlice(gpa, copied_instructions); |
| 1975 | 1967 | return copied_instructions[copied_instructions.len - 1]; |
| 1976 | 1968 | } |
| 1977 | 1969 | if (merges.results.items.len == 1) { |
| ... | ... | @@ -1982,7 +1974,7 @@ fn analyzeBlockBody( |
| 1982 | 1974 | // No need for a block instruction. We can put the new instructions directly |
| 1983 | 1975 | // into the parent block. Here we omit the break instruction. |
| 1984 | 1976 | const copied_instructions = try sema.arena.dupe(Air.Inst.Index, child_block.instructions.items[0..last_inst_index]); |
| 1985 | | try parent_block.instructions.appendSlice(sema.gpa, copied_instructions); |
| 1977 | try parent_block.instructions.appendSlice(gpa, copied_instructions); |
| 1986 | 1978 | return merges.results.items[0]; |
| 1987 | 1979 | } |
| 1988 | 1980 | } |
| ... | ... | @@ -1992,21 +1984,26 @@ fn analyzeBlockBody( |
| 1992 | 1984 | |
| 1993 | 1985 | // Need to set the type and emit the Block instruction. This allows machine code generation |
| 1994 | 1986 | // to emit a jump instruction to after the block when it encounters the break. |
| 1995 | | try parent_block.instructions.append(sema.gpa, &merges.block_inst.base); |
| 1987 | try parent_block.instructions.append(gpa, merges.block_inst); |
| 1996 | 1988 | const resolved_ty = try sema.resolvePeerTypes(parent_block, src, merges.results.items); |
| 1997 | | merges.block_inst.base.ty = resolved_ty; |
| 1998 | | merges.block_inst.body = .{ |
| 1999 | | .instructions = try sema.arena.dupe(Air.Inst.Index, child_block.instructions.items), |
| 2000 | | }; |
| 1989 | try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.Block).Struct.fields.len + |
| 1990 | child_block.instructions.items.len); |
| 1991 | sema.air_instructions.items(.data)[merges.block_inst] = .{ .ty_pl = .{ |
| 1992 | .ty = try sema.addType(resolved_ty), |
| 1993 | .payload = sema.addExtraAssumeCapacity(Air.Block{ |
| 1994 | .body_len = @intCast(u32, child_block.instructions.items.len), |
| 1995 | }), |
| 1996 | } }; |
| 1997 | sema.air_extra.appendSliceAssumeCapacity(child_block.instructions.items); |
| 2001 | 1998 | // Now that the block has its type resolved, we need to go back into all the break |
| 2002 | 1999 | // instructions, and insert type coercion on the operands. |
| 2003 | 2000 | for (merges.br_list.items) |br| { |
| 2004 | | if (br.operand.ty.eql(resolved_ty)) { |
| 2001 | if (sema.getTypeOf(br.operand).eql(resolved_ty)) { |
| 2005 | 2002 | // No type coercion needed. |
| 2006 | 2003 | continue; |
| 2007 | 2004 | } |
| 2008 | 2005 | var coerce_block = parent_block.makeSubBlock(); |
| 2009 | | defer coerce_block.instructions.deinit(sema.gpa); |
| 2006 | defer coerce_block.instructions.deinit(gpa); |
| 2010 | 2007 | const coerced_operand = try sema.coerce(&coerce_block, resolved_ty, br.operand, br.operand.src); |
| 2011 | 2008 | // If no instructions were produced, such as in the case of a coercion of a |
| 2012 | 2009 | // constant value to a new type, we can simply point the br operand to it. |
| ... | ... | @@ -2032,7 +2029,7 @@ fn analyzeBlockBody( |
| 2032 | 2029 | }, |
| 2033 | 2030 | }; |
| 2034 | 2031 | } |
| 2035 | | return &merges.block_inst.base; |
| 2032 | return indexToRef(merges.block_inst); |
| 2036 | 2033 | } |
| 2037 | 2034 | |
| 2038 | 2035 | fn zirExport(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!void { |
| ... | ... | @@ -2104,7 +2101,7 @@ fn zirBreakpoint(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Compile |
| 2104 | 2101 | const src_node = sema.code.instructions.items(.data)[inst].node; |
| 2105 | 2102 | const src: LazySrcLoc = .{ .node_offset = src_node }; |
| 2106 | 2103 | try sema.requireRuntimeBlock(block, src); |
| 2107 | | _ = try block.addNoOp(src, Type.initTag(.void), .breakpoint); |
| 2104 | _ = try block.addNoOp(.breakpoint); |
| 2108 | 2105 | } |
| 2109 | 2106 | |
| 2110 | 2107 | fn zirFence(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!void { |
| ... | ... | @@ -2311,6 +2308,8 @@ fn analyzeCall( |
| 2311 | 2308 | }), |
| 2312 | 2309 | } |
| 2313 | 2310 | |
| 2311 | const gpa = sema.gpa; |
| 2312 | |
| 2314 | 2313 | const ret_type = func.ty.fnReturnType(); |
| 2315 | 2314 | |
| 2316 | 2315 | const is_comptime_call = block.is_comptime or modifier == .compile_time; |
| ... | ... | @@ -2331,15 +2330,11 @@ fn analyzeCall( |
| 2331 | 2330 | // set to in the `Scope.Block`. |
| 2332 | 2331 | // This block instruction will be used to capture the return value from the |
| 2333 | 2332 | // inlined function. |
| 2334 | | const block_inst = try sema.arena.create(Inst.Block); |
| 2335 | | block_inst.* = .{ |
| 2336 | | .base = .{ |
| 2337 | | .tag = Inst.Block.base_tag, |
| 2338 | | .ty = ret_type, |
| 2339 | | .src = call_src, |
| 2340 | | }, |
| 2341 | | .body = undefined, |
| 2342 | | }; |
| 2333 | const block_inst = @intCast(Air.Inst.Index, sema.air_instructions.len); |
| 2334 | try sema.air_instructions.append(gpa, .{ |
| 2335 | .tag = .block, |
| 2336 | .data = undefined, |
| 2337 | }); |
| 2343 | 2338 | // This one is shared among sub-blocks within the same callee, but not |
| 2344 | 2339 | // shared among the entire inline/comptime call stack. |
| 2345 | 2340 | var inlining: Scope.Block.Inlining = .{ |
| ... | ... | @@ -2358,7 +2353,7 @@ fn analyzeCall( |
| 2358 | 2353 | const parent_inst_map = sema.inst_map; |
| 2359 | 2354 | sema.inst_map = .{}; |
| 2360 | 2355 | defer { |
| 2361 | | sema.inst_map.deinit(sema.gpa); |
| 2356 | sema.inst_map.deinit(gpa); |
| 2362 | 2357 | sema.inst_map = parent_inst_map; |
| 2363 | 2358 | } |
| 2364 | 2359 | |
| ... | ... | @@ -2390,9 +2385,9 @@ fn analyzeCall( |
| 2390 | 2385 | |
| 2391 | 2386 | const merges = &child_block.inlining.?.merges; |
| 2392 | 2387 | |
| 2393 | | defer child_block.instructions.deinit(sema.gpa); |
| 2394 | | defer merges.results.deinit(sema.gpa); |
| 2395 | | defer merges.br_list.deinit(sema.gpa); |
| 2388 | defer child_block.instructions.deinit(gpa); |
| 2389 | defer merges.results.deinit(gpa); |
| 2390 | defer merges.br_list.deinit(gpa); |
| 2396 | 2391 | |
| 2397 | 2392 | try sema.emitBackwardBranch(&child_block, call_src); |
| 2398 | 2393 | |
| ... | ... | @@ -2525,17 +2520,16 @@ fn zirErrorValue(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Compile |
| 2525 | 2520 | defer tracy.end(); |
| 2526 | 2521 | |
| 2527 | 2522 | const inst_data = sema.code.instructions.items(.data)[inst].str_tok; |
| 2528 | | const src = inst_data.src(); |
| 2529 | 2523 | |
| 2530 | 2524 | // Create an anonymous error set type with only this error value, and return the value. |
| 2531 | 2525 | const kv = try sema.mod.getErrorValue(inst_data.get(sema.code)); |
| 2532 | 2526 | const result_type = try Type.Tag.error_set_single.create(sema.arena, kv.key); |
| 2533 | | return sema.mod.constInst(sema.arena, src, .{ |
| 2534 | | .ty = result_type, |
| 2535 | | .val = try Value.Tag.@"error".create(sema.arena, .{ |
| 2527 | return sema.addConstant( |
| 2528 | result_type, |
| 2529 | try Value.Tag.@"error".create(sema.arena, .{ |
| 2536 | 2530 | .name = kv.key, |
| 2537 | 2531 | }), |
| 2538 | | }); |
| 2532 | ); |
| 2539 | 2533 | } |
| 2540 | 2534 | |
| 2541 | 2535 | fn zirErrorToInt(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| ... | ... | @@ -2558,10 +2552,7 @@ fn zirErrorToInt(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Compile |
| 2558 | 2552 | .base = .{ .tag = .int_u64 }, |
| 2559 | 2553 | .data = (try sema.mod.getErrorValue(val.castTag(.@"error").?.data.name)).value, |
| 2560 | 2554 | }; |
| 2561 | | return sema.mod.constInst(sema.arena, src, .{ |
| 2562 | | .ty = result_ty, |
| 2563 | | .val = Value.initPayload(&payload.base), |
| 2564 | | }); |
| 2555 | return sema.addConstant(result_ty, Value.initPayload(&payload.base)); |
| 2565 | 2556 | } |
| 2566 | 2557 | |
| 2567 | 2558 | try sema.requireRuntimeBlock(block, src); |
| ... | ... | @@ -2587,10 +2578,7 @@ fn zirIntToError(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Compile |
| 2587 | 2578 | .base = .{ .tag = .@"error" }, |
| 2588 | 2579 | .data = .{ .name = sema.mod.error_name_list.items[@intCast(usize, int)] }, |
| 2589 | 2580 | }; |
| 2590 | | return sema.mod.constInst(sema.arena, src, .{ |
| 2591 | | .ty = Type.initTag(.anyerror), |
| 2592 | | .val = Value.initPayload(&payload.base), |
| 2593 | | }); |
| 2581 | return sema.addConstant(Type.initTag(.anyerror), Value.initPayload(&payload.base)); |
| 2594 | 2582 | } |
| 2595 | 2583 | try sema.requireRuntimeBlock(block, src); |
| 2596 | 2584 | if (block.wantSafety()) { |
| ... | ... | @@ -2630,10 +2618,7 @@ fn zirMergeErrorSets(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Com |
| 2630 | 2618 | |
| 2631 | 2619 | // Anything merged with anyerror is anyerror. |
| 2632 | 2620 | if (lhs_ty.tag() == .anyerror or rhs_ty.tag() == .anyerror) { |
| 2633 | | return sema.mod.constInst(sema.arena, src, .{ |
| 2634 | | .ty = Type.initTag(.type), |
| 2635 | | .val = Value.initTag(.anyerror_type), |
| 2636 | | }); |
| 2621 | return Air.Inst.Ref.anyerror_type; |
| 2637 | 2622 | } |
| 2638 | 2623 | // When we support inferred error sets, we'll want to use a data structure that can |
| 2639 | 2624 | // represent a merged set of errors without forcing them to be resolved here. Until then |
| ... | ... | @@ -2685,10 +2670,7 @@ fn zirMergeErrorSets(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Com |
| 2685 | 2670 | .names_len = @intCast(u32, new_names.len), |
| 2686 | 2671 | }; |
| 2687 | 2672 | const error_set_ty = try Type.Tag.error_set.create(sema.arena, new_error_set); |
| 2688 | | return sema.mod.constInst(sema.arena, src, .{ |
| 2689 | | .ty = Type.initTag(.type), |
| 2690 | | .val = try Value.Tag.ty.create(sema.arena, error_set_ty), |
| 2691 | | }); |
| 2673 | return sema.addConstant(Type.initTag(.type), try Value.Tag.ty.create(sema.arena, error_set_ty)); |
| 2692 | 2674 | } |
| 2693 | 2675 | |
| 2694 | 2676 | fn zirEnumLiteral(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| ... | ... | @@ -2697,12 +2679,11 @@ fn zirEnumLiteral(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Compil |
| 2697 | 2679 | defer tracy.end(); |
| 2698 | 2680 | |
| 2699 | 2681 | const inst_data = sema.code.instructions.items(.data)[inst].str_tok; |
| 2700 | | const src = inst_data.src(); |
| 2701 | 2682 | const duped_name = try sema.arena.dupe(u8, inst_data.get(sema.code)); |
| 2702 | | return sema.mod.constInst(sema.arena, src, .{ |
| 2703 | | .ty = Type.initTag(.enum_literal), |
| 2704 | | .val = try Value.Tag.enum_literal.create(sema.arena, duped_name), |
| 2705 | | }); |
| 2683 | return sema.addConstant( |
| 2684 | Type.initTag(.enum_literal), |
| 2685 | try Value.Tag.enum_literal.create(sema.arena, duped_name), |
| 2686 | ); |
| 2706 | 2687 | } |
| 2707 | 2688 | |
| 2708 | 2689 | fn zirEnumToInt(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| ... | ... | @@ -2712,11 +2693,12 @@ fn zirEnumToInt(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileE |
| 2712 | 2693 | const src = inst_data.src(); |
| 2713 | 2694 | const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; |
| 2714 | 2695 | const operand = sema.resolveInst(inst_data.operand); |
| 2696 | const operand_ty = sema.getTypeOf(operand); |
| 2715 | 2697 | |
| 2716 | | const enum_tag: Air.Inst.Ref = switch (operand.ty.zigTypeTag()) { |
| 2698 | const enum_tag: Air.Inst.Ref = switch (operand_ty.zigTypeTag()) { |
| 2717 | 2699 | .Enum => operand, |
| 2718 | 2700 | .Union => { |
| 2719 | | //if (!operand.ty.unionHasTag()) { |
| 2701 | //if (!operand_ty.unionHasTag()) { |
| 2720 | 2702 | // return mod.fail( |
| 2721 | 2703 | // &block.base, |
| 2722 | 2704 | // operand_src, |
| ... | ... | @@ -2728,58 +2710,44 @@ fn zirEnumToInt(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileE |
| 2728 | 2710 | }, |
| 2729 | 2711 | else => { |
| 2730 | 2712 | return mod.fail(&block.base, operand_src, "expected enum or tagged union, found {}", .{ |
| 2731 | | operand.ty, |
| 2713 | operand_ty, |
| 2732 | 2714 | }); |
| 2733 | 2715 | }, |
| 2734 | 2716 | }; |
| 2717 | const enum_tag_ty = sema.getTypeOf(enum_tag); |
| 2735 | 2718 | |
| 2736 | 2719 | var int_tag_type_buffer: Type.Payload.Bits = undefined; |
| 2737 | | const int_tag_ty = try enum_tag.ty.intTagType(&int_tag_type_buffer).copy(arena); |
| 2720 | const int_tag_ty = try enum_tag_ty.intTagType(&int_tag_type_buffer).copy(arena); |
| 2738 | 2721 | |
| 2739 | | if (try sema.typeHasOnePossibleValue(block, src, enum_tag.ty)) |opv| { |
| 2740 | | return mod.constInst(arena, src, .{ |
| 2741 | | .ty = int_tag_ty, |
| 2742 | | .val = opv, |
| 2743 | | }); |
| 2722 | if (try sema.typeHasOnePossibleValue(block, src, enum_tag_ty)) |opv| { |
| 2723 | return sema.addConstant(int_tag_ty, opv); |
| 2744 | 2724 | } |
| 2745 | 2725 | |
| 2746 | 2726 | if (try sema.resolvePossiblyUndefinedValue(block, operand_src, enum_tag)) |enum_tag_val| { |
| 2747 | 2727 | if (enum_tag_val.castTag(.enum_field_index)) |enum_field_payload| { |
| 2748 | 2728 | const field_index = enum_field_payload.data; |
| 2749 | | switch (enum_tag.ty.tag()) { |
| 2729 | switch (enum_tag_ty.tag()) { |
| 2750 | 2730 | .enum_full => { |
| 2751 | | const enum_full = enum_tag.ty.castTag(.enum_full).?.data; |
| 2731 | const enum_full = enum_tag_ty.castTag(.enum_full).?.data; |
| 2752 | 2732 | if (enum_full.values.count() != 0) { |
| 2753 | 2733 | const val = enum_full.values.keys()[field_index]; |
| 2754 | | return mod.constInst(arena, src, .{ |
| 2755 | | .ty = int_tag_ty, |
| 2756 | | .val = val, |
| 2757 | | }); |
| 2734 | return sema.addConstant(int_tag_ty, val); |
| 2758 | 2735 | } else { |
| 2759 | 2736 | // Field index and integer values are the same. |
| 2760 | 2737 | const val = try Value.Tag.int_u64.create(arena, field_index); |
| 2761 | | return mod.constInst(arena, src, .{ |
| 2762 | | .ty = int_tag_ty, |
| 2763 | | .val = val, |
| 2764 | | }); |
| 2738 | return sema.addConstant(int_tag_ty, val); |
| 2765 | 2739 | } |
| 2766 | 2740 | }, |
| 2767 | 2741 | .enum_simple => { |
| 2768 | 2742 | // Field index and integer values are the same. |
| 2769 | 2743 | const val = try Value.Tag.int_u64.create(arena, field_index); |
| 2770 | | return mod.constInst(arena, src, .{ |
| 2771 | | .ty = int_tag_ty, |
| 2772 | | .val = val, |
| 2773 | | }); |
| 2744 | return sema.addConstant(int_tag_ty, val); |
| 2774 | 2745 | }, |
| 2775 | 2746 | else => unreachable, |
| 2776 | 2747 | } |
| 2777 | 2748 | } else { |
| 2778 | 2749 | // Assume it is already an integer and return it directly. |
| 2779 | | return mod.constInst(arena, src, .{ |
| 2780 | | .ty = int_tag_ty, |
| 2781 | | .val = enum_tag_val, |
| 2782 | | }); |
| 2750 | return sema.addConstant(int_tag_ty, enum_tag_val); |
| 2783 | 2751 | } |
| 2784 | 2752 | } |
| 2785 | 2753 | |
| ... | ... | @@ -2790,7 +2758,6 @@ fn zirEnumToInt(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileE |
| 2790 | 2758 | fn zirIntToEnum(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 2791 | 2759 | const mod = sema.mod; |
| 2792 | 2760 | const target = mod.getTarget(); |
| 2793 | | const arena = sema.arena; |
| 2794 | 2761 | const inst_data = sema.code.instructions.items(.data)[inst].pl_node; |
| 2795 | 2762 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; |
| 2796 | 2763 | const src = inst_data.src(); |
| ... | ... | @@ -2805,10 +2772,7 @@ fn zirIntToEnum(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileE |
| 2805 | 2772 | |
| 2806 | 2773 | if (try sema.resolvePossiblyUndefinedValue(block, operand_src, operand)) |int_val| { |
| 2807 | 2774 | if (dest_ty.isNonexhaustiveEnum()) { |
| 2808 | | return mod.constInst(arena, src, .{ |
| 2809 | | .ty = dest_ty, |
| 2810 | | .val = int_val, |
| 2811 | | }); |
| 2775 | return sema.addConstant(dest_ty, int_val); |
| 2812 | 2776 | } |
| 2813 | 2777 | if (int_val.isUndef()) { |
| 2814 | 2778 | return sema.failWithUseOfUndef(block, operand_src); |
| ... | ... | @@ -2832,10 +2796,7 @@ fn zirIntToEnum(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileE |
| 2832 | 2796 | }; |
| 2833 | 2797 | return mod.failWithOwnedErrorMsg(&block.base, msg); |
| 2834 | 2798 | } |
| 2835 | | return mod.constInst(arena, src, .{ |
| 2836 | | .ty = dest_ty, |
| 2837 | | .val = int_val, |
| 2838 | | }); |
| 2799 | return sema.addConstant(dest_ty, int_val); |
| 2839 | 2800 | } |
| 2840 | 2801 | |
| 2841 | 2802 | try sema.requireRuntimeBlock(block, src); |
| ... | ... | @@ -2854,16 +2815,17 @@ fn zirOptionalPayloadPtr( |
| 2854 | 2815 | |
| 2855 | 2816 | const inst_data = sema.code.instructions.items(.data)[inst].un_node; |
| 2856 | 2817 | const optional_ptr = sema.resolveInst(inst_data.operand); |
| 2857 | | assert(optional_ptr.ty.zigTypeTag() == .Pointer); |
| 2818 | const optional_ptr_ty = sema.getTypeOf(optional_ptr); |
| 2819 | assert(optional_ptr_ty.zigTypeTag() == .Pointer); |
| 2858 | 2820 | const src = inst_data.src(); |
| 2859 | 2821 | |
| 2860 | | const opt_type = optional_ptr.ty.elemType(); |
| 2822 | const opt_type = optional_ptr_ty.elemType(); |
| 2861 | 2823 | if (opt_type.zigTypeTag() != .Optional) { |
| 2862 | 2824 | return sema.mod.fail(&block.base, src, "expected optional type, found {}", .{opt_type}); |
| 2863 | 2825 | } |
| 2864 | 2826 | |
| 2865 | 2827 | const child_type = try opt_type.optionalChildAlloc(sema.arena); |
| 2866 | | const child_pointer = try Module.simplePtrType(sema.arena, child_type, !optional_ptr.ty.isConstPtr(), .One); |
| 2828 | const child_pointer = try Module.simplePtrType(sema.arena, child_type, !optional_ptr_ty.isConstPtr(), .One); |
| 2867 | 2829 | |
| 2868 | 2830 | if (try sema.resolveDefinedValue(block, src, optional_ptr)) |pointer_val| { |
| 2869 | 2831 | const val = try pointer_val.pointerDeref(sema.arena); |
| ... | ... | @@ -2871,10 +2833,7 @@ fn zirOptionalPayloadPtr( |
| 2871 | 2833 | return sema.mod.fail(&block.base, src, "unable to unwrap null", .{}); |
| 2872 | 2834 | } |
| 2873 | 2835 | // The same Value represents the pointer to the optional and the payload. |
| 2874 | | return sema.mod.constInst(sema.arena, src, .{ |
| 2875 | | .ty = child_pointer, |
| 2876 | | .val = pointer_val, |
| 2877 | | }); |
| 2836 | return sema.addConstant(child_pointer, pointer_val); |
| 2878 | 2837 | } |
| 2879 | 2838 | |
| 2880 | 2839 | try sema.requireRuntimeBlock(block, src); |
| ... | ... | @@ -2898,7 +2857,8 @@ fn zirOptionalPayload( |
| 2898 | 2857 | const inst_data = sema.code.instructions.items(.data)[inst].un_node; |
| 2899 | 2858 | const src = inst_data.src(); |
| 2900 | 2859 | const operand = sema.resolveInst(inst_data.operand); |
| 2901 | | const opt_type = operand.ty; |
| 2860 | const operand_ty = sema.getTypeOf(operand); |
| 2861 | const opt_type = operand_ty; |
| 2902 | 2862 | if (opt_type.zigTypeTag() != .Optional) { |
| 2903 | 2863 | return sema.mod.fail(&block.base, src, "expected optional type, found {}", .{opt_type}); |
| 2904 | 2864 | } |
| ... | ... | @@ -2909,10 +2869,7 @@ fn zirOptionalPayload( |
| 2909 | 2869 | if (val.isNull()) { |
| 2910 | 2870 | return sema.mod.fail(&block.base, src, "unable to unwrap null", .{}); |
| 2911 | 2871 | } |
| 2912 | | return sema.mod.constInst(sema.arena, src, .{ |
| 2913 | | .ty = child_type, |
| 2914 | | .val = val, |
| 2915 | | }); |
| 2872 | return sema.addConstant(child_type, val); |
| 2916 | 2873 | } |
| 2917 | 2874 | |
| 2918 | 2875 | try sema.requireRuntimeBlock(block, src); |
| ... | ... | @@ -2936,25 +2893,27 @@ fn zirErrUnionPayload( |
| 2936 | 2893 | const inst_data = sema.code.instructions.items(.data)[inst].un_node; |
| 2937 | 2894 | const src = inst_data.src(); |
| 2938 | 2895 | const operand = sema.resolveInst(inst_data.operand); |
| 2939 | | if (operand.ty.zigTypeTag() != .ErrorUnion) |
| 2940 | | return sema.mod.fail(&block.base, operand.src, "expected error union type, found '{}'", .{operand.ty}); |
| 2896 | const operand_src = src; |
| 2897 | const operand_ty = sema.getTypeOf(operand); |
| 2898 | if (operand_ty.zigTypeTag() != .ErrorUnion) |
| 2899 | return sema.mod.fail(&block.base, operand_src, "expected error union type, found '{}'", .{operand_ty}); |
| 2941 | 2900 | |
| 2942 | 2901 | if (try sema.resolveDefinedValue(block, src, operand)) |val| { |
| 2943 | 2902 | if (val.getError()) |name| { |
| 2944 | 2903 | return sema.mod.fail(&block.base, src, "caught unexpected error '{s}'", .{name}); |
| 2945 | 2904 | } |
| 2946 | 2905 | const data = val.castTag(.error_union).?.data; |
| 2947 | | return sema.mod.constInst(sema.arena, src, .{ |
| 2948 | | .ty = operand.ty.castTag(.error_union).?.data.payload, |
| 2949 | | .val = data, |
| 2950 | | }); |
| 2906 | return sema.addConstant( |
| 2907 | operand_ty.castTag(.error_union).?.data.payload, |
| 2908 | data, |
| 2909 | ); |
| 2951 | 2910 | } |
| 2952 | 2911 | try sema.requireRuntimeBlock(block, src); |
| 2953 | 2912 | if (safety_check and block.wantSafety()) { |
| 2954 | 2913 | const is_non_err = try block.addUnOp(.is_err, operand); |
| 2955 | 2914 | try sema.addSafetyCheck(block, is_non_err, .unwrap_errunion); |
| 2956 | 2915 | } |
| 2957 | | const result_ty = operand.ty.castTag(.error_union).?.data.payload; |
| 2916 | const result_ty = operand_ty.castTag(.error_union).?.data.payload; |
| 2958 | 2917 | return block.addTyOp(.unwrap_errunion_payload, result_ty, operand); |
| 2959 | 2918 | } |
| 2960 | 2919 | |
| ... | ... | @@ -2971,12 +2930,13 @@ fn zirErrUnionPayloadPtr( |
| 2971 | 2930 | const inst_data = sema.code.instructions.items(.data)[inst].un_node; |
| 2972 | 2931 | const src = inst_data.src(); |
| 2973 | 2932 | const operand = sema.resolveInst(inst_data.operand); |
| 2974 | | assert(operand.ty.zigTypeTag() == .Pointer); |
| 2933 | const operand_ty = sema.getTypeOf(operand); |
| 2934 | assert(operand_ty.zigTypeTag() == .Pointer); |
| 2975 | 2935 | |
| 2976 | | if (operand.ty.elemType().zigTypeTag() != .ErrorUnion) |
| 2977 | | return sema.mod.fail(&block.base, src, "expected error union type, found {}", .{operand.ty.elemType()}); |
| 2936 | if (operand_ty.elemType().zigTypeTag() != .ErrorUnion) |
| 2937 | return sema.mod.fail(&block.base, src, "expected error union type, found {}", .{operand_ty.elemType()}); |
| 2978 | 2938 | |
| 2979 | | const operand_pointer_ty = try Module.simplePtrType(sema.arena, operand.ty.elemType().castTag(.error_union).?.data.payload, !operand.ty.isConstPtr(), .One); |
| 2939 | const operand_pointer_ty = try Module.simplePtrType(sema.arena, operand_ty.elemType().castTag(.error_union).?.data.payload, !operand_ty.isConstPtr(), .One); |
| 2980 | 2940 | |
| 2981 | 2941 | if (try sema.resolveDefinedValue(block, src, operand)) |pointer_val| { |
| 2982 | 2942 | const val = try pointer_val.pointerDeref(sema.arena); |
| ... | ... | @@ -2985,13 +2945,13 @@ fn zirErrUnionPayloadPtr( |
| 2985 | 2945 | } |
| 2986 | 2946 | const data = val.castTag(.error_union).?.data; |
| 2987 | 2947 | // The same Value represents the pointer to the error union and the payload. |
| 2988 | | return sema.mod.constInst(sema.arena, src, .{ |
| 2989 | | .ty = operand_pointer_ty, |
| 2990 | | .val = try Value.Tag.ref_val.create( |
| 2948 | return sema.addConstant( |
| 2949 | operand_pointer_ty, |
| 2950 | try Value.Tag.ref_val.create( |
| 2991 | 2951 | sema.arena, |
| 2992 | 2952 | data, |
| 2993 | 2953 | ), |
| 2994 | | }); |
| 2954 | ); |
| 2995 | 2955 | } |
| 2996 | 2956 | |
| 2997 | 2957 | try sema.requireRuntimeBlock(block, src); |
| ... | ... | @@ -3010,18 +2970,16 @@ fn zirErrUnionCode(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Compi |
| 3010 | 2970 | const inst_data = sema.code.instructions.items(.data)[inst].un_node; |
| 3011 | 2971 | const src = inst_data.src(); |
| 3012 | 2972 | const operand = sema.resolveInst(inst_data.operand); |
| 3013 | | if (operand.ty.zigTypeTag() != .ErrorUnion) |
| 3014 | | return sema.mod.fail(&block.base, src, "expected error union type, found '{}'", .{operand.ty}); |
| 2973 | const operand_ty = sema.getTypeOf(operand); |
| 2974 | if (operand_ty.zigTypeTag() != .ErrorUnion) |
| 2975 | return sema.mod.fail(&block.base, src, "expected error union type, found '{}'", .{operand_ty}); |
| 3015 | 2976 | |
| 3016 | | const result_ty = operand.ty.castTag(.error_union).?.data.error_set; |
| 2977 | const result_ty = operand_ty.castTag(.error_union).?.data.error_set; |
| 3017 | 2978 | |
| 3018 | 2979 | if (try sema.resolveDefinedValue(block, src, operand)) |val| { |
| 3019 | 2980 | assert(val.getError() != null); |
| 3020 | 2981 | const data = val.castTag(.error_union).?.data; |
| 3021 | | return sema.mod.constInst(sema.arena, src, .{ |
| 3022 | | .ty = result_ty, |
| 3023 | | .val = data, |
| 3024 | | }); |
| 2982 | return sema.addConstant(result_ty, data); |
| 3025 | 2983 | } |
| 3026 | 2984 | |
| 3027 | 2985 | try sema.requireRuntimeBlock(block, src); |
| ... | ... | @@ -3036,21 +2994,19 @@ fn zirErrUnionCodePtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Co |
| 3036 | 2994 | const inst_data = sema.code.instructions.items(.data)[inst].un_node; |
| 3037 | 2995 | const src = inst_data.src(); |
| 3038 | 2996 | const operand = sema.resolveInst(inst_data.operand); |
| 3039 | | assert(operand.ty.zigTypeTag() == .Pointer); |
| 2997 | const operand_ty = sema.getTypeOf(operand); |
| 2998 | assert(operand_ty.zigTypeTag() == .Pointer); |
| 3040 | 2999 | |
| 3041 | | if (operand.ty.elemType().zigTypeTag() != .ErrorUnion) |
| 3042 | | return sema.mod.fail(&block.base, src, "expected error union type, found {}", .{operand.ty.elemType()}); |
| 3000 | if (operand_ty.elemType().zigTypeTag() != .ErrorUnion) |
| 3001 | return sema.mod.fail(&block.base, src, "expected error union type, found {}", .{operand_ty.elemType()}); |
| 3043 | 3002 | |
| 3044 | | const result_ty = operand.ty.elemType().castTag(.error_union).?.data.error_set; |
| 3003 | const result_ty = operand_ty.elemType().castTag(.error_union).?.data.error_set; |
| 3045 | 3004 | |
| 3046 | 3005 | if (try sema.resolveDefinedValue(block, src, operand)) |pointer_val| { |
| 3047 | 3006 | const val = try pointer_val.pointerDeref(sema.arena); |
| 3048 | 3007 | assert(val.getError() != null); |
| 3049 | 3008 | const data = val.castTag(.error_union).?.data; |
| 3050 | | return sema.mod.constInst(sema.arena, src, .{ |
| 3051 | | .ty = result_ty, |
| 3052 | | .val = data, |
| 3053 | | }); |
| 3009 | return sema.addConstant(result_ty, data); |
| 3054 | 3010 | } |
| 3055 | 3011 | |
| 3056 | 3012 | try sema.requireRuntimeBlock(block, src); |
| ... | ... | @@ -3064,9 +3020,10 @@ fn zirEnsureErrPayloadVoid(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Inde |
| 3064 | 3020 | const inst_data = sema.code.instructions.items(.data)[inst].un_tok; |
| 3065 | 3021 | const src = inst_data.src(); |
| 3066 | 3022 | const operand = sema.resolveInst(inst_data.operand); |
| 3067 | | if (operand.ty.zigTypeTag() != .ErrorUnion) |
| 3068 | | return sema.mod.fail(&block.base, src, "expected error union type, found '{}'", .{operand.ty}); |
| 3069 | | if (operand.ty.castTag(.error_union).?.data.payload.zigTypeTag() != .Void) { |
| 3023 | const operand_ty = sema.getTypeOf(operand); |
| 3024 | if (operand_ty.zigTypeTag() != .ErrorUnion) |
| 3025 | return sema.mod.fail(&block.base, src, "expected error union type, found '{}'", .{operand_ty}); |
| 3026 | if (operand_ty.castTag(.error_union).?.data.payload.zigTypeTag() != .Void) { |
| 3070 | 3027 | return sema.mod.fail(&block.base, src, "expression value is ignored", .{}); |
| 3071 | 3028 | } |
| 3072 | 3029 | } |
| ... | ... | @@ -3233,10 +3190,10 @@ fn funcCommon( |
| 3233 | 3190 | } |
| 3234 | 3191 | |
| 3235 | 3192 | if (is_extern) { |
| 3236 | | return sema.mod.constInst(sema.arena, src, .{ |
| 3237 | | .ty = fn_ty, |
| 3238 | | .val = try Value.Tag.extern_fn.create(sema.arena, sema.owner_decl), |
| 3239 | | }); |
| 3193 | return sema.addConstant( |
| 3194 | fn_ty, |
| 3195 | try Value.Tag.extern_fn.create(sema.arena, sema.owner_decl), |
| 3196 | ); |
| 3240 | 3197 | } |
| 3241 | 3198 | |
| 3242 | 3199 | if (body_inst == 0) { |
| ... | ... | @@ -3261,11 +3218,7 @@ fn funcCommon( |
| 3261 | 3218 | .base = .{ .tag = .function }, |
| 3262 | 3219 | .data = new_func, |
| 3263 | 3220 | }; |
| 3264 | | const result = try sema.mod.constInst(sema.arena, src, .{ |
| 3265 | | .ty = fn_ty, |
| 3266 | | .val = Value.initPayload(&fn_payload.base), |
| 3267 | | }); |
| 3268 | | return result; |
| 3221 | return sema.addConstant(fn_ty, Value.initPayload(&fn_payload.base)); |
| 3269 | 3222 | } |
| 3270 | 3223 | |
| 3271 | 3224 | fn zirAs(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| ... | ... | @@ -3324,7 +3277,7 @@ fn zirFieldVal(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileEr |
| 3324 | 3277 | const extra = sema.code.extraData(Zir.Inst.Field, inst_data.payload_index).data; |
| 3325 | 3278 | const field_name = sema.code.nullTerminatedString(extra.field_name_start); |
| 3326 | 3279 | const object = sema.resolveInst(extra.lhs); |
| 3327 | | const object_ptr = if (object.ty.zigTypeTag() == .Pointer) |
| 3280 | const object_ptr = if (sema.getTypeOf(object).zigTypeTag() == .Pointer) |
| 3328 | 3281 | object |
| 3329 | 3282 | else |
| 3330 | 3283 | try sema.analyzeRef(block, src, object); |
| ... | ... | @@ -3397,13 +3350,14 @@ fn zirIntCast(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileErr |
| 3397 | 3350 | ), |
| 3398 | 3351 | }; |
| 3399 | 3352 | |
| 3400 | | switch (operand.ty.zigTypeTag()) { |
| 3353 | const operand_ty = sema.getTypeOf(operand); |
| 3354 | switch (operand_ty.zigTypeTag()) { |
| 3401 | 3355 | .ComptimeInt, .Int => {}, |
| 3402 | 3356 | else => return sema.mod.fail( |
| 3403 | 3357 | &block.base, |
| 3404 | 3358 | operand_src, |
| 3405 | 3359 | "expected integer type, found '{}'", |
| 3406 | | .{operand.ty}, |
| 3360 | .{operand_ty}, |
| 3407 | 3361 | ), |
| 3408 | 3362 | } |
| 3409 | 3363 | |
| ... | ... | @@ -3454,13 +3408,14 @@ fn zirFloatCast(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileE |
| 3454 | 3408 | ), |
| 3455 | 3409 | }; |
| 3456 | 3410 | |
| 3457 | | switch (operand.ty.zigTypeTag()) { |
| 3411 | const operand_ty = sema.getTypeOf(operand); |
| 3412 | switch (operand_ty.zigTypeTag()) { |
| 3458 | 3413 | .ComptimeFloat, .Float, .ComptimeInt => {}, |
| 3459 | 3414 | else => return sema.mod.fail( |
| 3460 | 3415 | &block.base, |
| 3461 | 3416 | operand_src, |
| 3462 | 3417 | "expected float type, found '{}'", |
| 3463 | | .{operand.ty}, |
| 3418 | .{operand_ty}, |
| 3464 | 3419 | ), |
| 3465 | 3420 | } |
| 3466 | 3421 | |
| ... | ... | @@ -3479,7 +3434,8 @@ fn zirElemVal(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileErr |
| 3479 | 3434 | |
| 3480 | 3435 | const bin_inst = sema.code.instructions.items(.data)[inst].bin; |
| 3481 | 3436 | const array = sema.resolveInst(bin_inst.lhs); |
| 3482 | | const array_ptr = if (array.ty.zigTypeTag() == .Pointer) |
| 3437 | const array_ty = sema.getTypeOf(array); |
| 3438 | const array_ptr = if (array_ty.zigTypeTag() == .Pointer) |
| 3483 | 3439 | array |
| 3484 | 3440 | else |
| 3485 | 3441 | try sema.analyzeRef(block, sema.src, array); |
| ... | ... | @@ -3497,7 +3453,8 @@ fn zirElemValNode(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Compil |
| 3497 | 3453 | const elem_index_src: LazySrcLoc = .{ .node_offset_array_access_index = inst_data.src_node }; |
| 3498 | 3454 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; |
| 3499 | 3455 | const array = sema.resolveInst(extra.lhs); |
| 3500 | | const array_ptr = if (array.ty.zigTypeTag() == .Pointer) |
| 3456 | const array_ty = sema.getTypeOf(array); |
| 3457 | const array_ptr = if (array_ty.zigTypeTag() == .Pointer) |
| 3501 | 3458 | array |
| 3502 | 3459 | else |
| 3503 | 3460 | try sema.analyzeRef(block, src, array); |
| ... | ... | @@ -3705,9 +3662,10 @@ fn analyzeSwitch( |
| 3705 | 3662 | const src: LazySrcLoc = .{ .node_offset = src_node_offset }; |
| 3706 | 3663 | const special_prong_src: LazySrcLoc = .{ .node_offset_switch_special_prong = src_node_offset }; |
| 3707 | 3664 | const operand_src: LazySrcLoc = .{ .node_offset_switch_operand = src_node_offset }; |
| 3665 | const operand_ty = sema.getTypeOf(operand); |
| 3708 | 3666 | |
| 3709 | 3667 | // Validate usage of '_' prongs. |
| 3710 | | if (special_prong == .under and !operand.ty.isNonexhaustiveEnum()) { |
| 3668 | if (special_prong == .under and !operand_ty.isNonexhaustiveEnum()) { |
| 3711 | 3669 | const msg = msg: { |
| 3712 | 3670 | const msg = try mod.errMsg( |
| 3713 | 3671 | &block.base, |
| ... | ... | @@ -3729,9 +3687,9 @@ fn analyzeSwitch( |
| 3729 | 3687 | } |
| 3730 | 3688 | |
| 3731 | 3689 | // Validate for duplicate items, missing else prong, and invalid range. |
| 3732 | | switch (operand.ty.zigTypeTag()) { |
| 3690 | switch (operand_ty.zigTypeTag()) { |
| 3733 | 3691 | .Enum => { |
| 3734 | | var seen_fields = try gpa.alloc(?Module.SwitchProngSrc, operand.ty.enumFieldCount()); |
| 3692 | var seen_fields = try gpa.alloc(?Module.SwitchProngSrc, operand_ty.enumFieldCount()); |
| 3735 | 3693 | defer gpa.free(seen_fields); |
| 3736 | 3694 | |
| 3737 | 3695 | mem.set(?Module.SwitchProngSrc, seen_fields, null); |
| ... | ... | @@ -3777,7 +3735,7 @@ fn analyzeSwitch( |
| 3777 | 3735 | ); |
| 3778 | 3736 | } |
| 3779 | 3737 | |
| 3780 | | try sema.validateSwitchNoRange(block, ranges_len, operand.ty, src_node_offset); |
| 3738 | try sema.validateSwitchNoRange(block, ranges_len, operand_ty, src_node_offset); |
| 3781 | 3739 | } |
| 3782 | 3740 | } |
| 3783 | 3741 | const all_tags_handled = for (seen_fields) |seen_src| { |
| ... | ... | @@ -3798,7 +3756,7 @@ fn analyzeSwitch( |
| 3798 | 3756 | for (seen_fields) |seen_src, i| { |
| 3799 | 3757 | if (seen_src != null) continue; |
| 3800 | 3758 | |
| 3801 | | const field_name = operand.ty.enumFieldName(i); |
| 3759 | const field_name = operand_ty.enumFieldName(i); |
| 3802 | 3760 | |
| 3803 | 3761 | // TODO have this point to the tag decl instead of here |
| 3804 | 3762 | try mod.errNote( |
| ... | ... | @@ -3810,10 +3768,10 @@ fn analyzeSwitch( |
| 3810 | 3768 | ); |
| 3811 | 3769 | } |
| 3812 | 3770 | try mod.errNoteNonLazy( |
| 3813 | | operand.ty.declSrcLoc(), |
| 3771 | operand_ty.declSrcLoc(), |
| 3814 | 3772 | msg, |
| 3815 | 3773 | "enum '{}' declared here", |
| 3816 | | .{operand.ty}, |
| 3774 | .{operand_ty}, |
| 3817 | 3775 | ); |
| 3818 | 3776 | break :msg msg; |
| 3819 | 3777 | }; |
| ... | ... | @@ -3908,12 +3866,12 @@ fn analyzeSwitch( |
| 3908 | 3866 | } |
| 3909 | 3867 | |
| 3910 | 3868 | check_range: { |
| 3911 | | if (operand.ty.zigTypeTag() == .Int) { |
| 3869 | if (operand_ty.zigTypeTag() == .Int) { |
| 3912 | 3870 | var arena = std.heap.ArenaAllocator.init(gpa); |
| 3913 | 3871 | defer arena.deinit(); |
| 3914 | 3872 | |
| 3915 | | const min_int = try operand.ty.minInt(&arena, mod.getTarget()); |
| 3916 | | const max_int = try operand.ty.maxInt(&arena, mod.getTarget()); |
| 3873 | const min_int = try operand_ty.minInt(&arena, mod.getTarget()); |
| 3874 | const max_int = try operand_ty.maxInt(&arena, mod.getTarget()); |
| 3917 | 3875 | if (try range_set.spans(min_int, max_int)) { |
| 3918 | 3876 | if (special_prong == .@"else") { |
| 3919 | 3877 | return mod.fail( |
| ... | ... | @@ -3983,7 +3941,7 @@ fn analyzeSwitch( |
| 3983 | 3941 | ); |
| 3984 | 3942 | } |
| 3985 | 3943 | |
| 3986 | | try sema.validateSwitchNoRange(block, ranges_len, operand.ty, src_node_offset); |
| 3944 | try sema.validateSwitchNoRange(block, ranges_len, operand_ty, src_node_offset); |
| 3987 | 3945 | } |
| 3988 | 3946 | } |
| 3989 | 3947 | switch (special_prong) { |
| ... | ... | @@ -4015,7 +3973,7 @@ fn analyzeSwitch( |
| 4015 | 3973 | &block.base, |
| 4016 | 3974 | src, |
| 4017 | 3975 | "else prong required when switching on type '{}'", |
| 4018 | | .{operand.ty}, |
| 3976 | .{operand_ty}, |
| 4019 | 3977 | ); |
| 4020 | 3978 | } |
| 4021 | 3979 | |
| ... | ... | @@ -4063,7 +4021,7 @@ fn analyzeSwitch( |
| 4063 | 4021 | ); |
| 4064 | 4022 | } |
| 4065 | 4023 | |
| 4066 | | try sema.validateSwitchNoRange(block, ranges_len, operand.ty, src_node_offset); |
| 4024 | try sema.validateSwitchNoRange(block, ranges_len, operand_ty, src_node_offset); |
| 4067 | 4025 | } |
| 4068 | 4026 | } |
| 4069 | 4027 | }, |
| ... | ... | @@ -4083,20 +4041,15 @@ fn analyzeSwitch( |
| 4083 | 4041 | .ComptimeFloat, |
| 4084 | 4042 | .Float, |
| 4085 | 4043 | => return mod.fail(&block.base, operand_src, "invalid switch operand type '{}'", .{ |
| 4086 | | operand.ty, |
| 4044 | operand_ty, |
| 4087 | 4045 | }), |
| 4088 | 4046 | } |
| 4089 | 4047 | |
| 4090 | | const block_inst = try sema.arena.create(Inst.Block); |
| 4091 | | block_inst.* = .{ |
| 4092 | | .base = .{ |
| 4093 | | .tag = Inst.Block.base_tag, |
| 4094 | | .ty = undefined, // Set after analysis. |
| 4095 | | .src = src, |
| 4096 | | }, |
| 4097 | | .body = undefined, |
| 4098 | | }; |
| 4099 | | |
| 4048 | const block_inst = @intCast(Air.Inst.Index, sema.air_instructions.len); |
| 4049 | try sema.air_instructions.append(gpa, .{ |
| 4050 | .tag = .block, |
| 4051 | .data = undefined, |
| 4052 | }); |
| 4100 | 4053 | var label: Scope.Block.Label = .{ |
| 4101 | 4054 | .zir_block = switch_inst, |
| 4102 | 4055 | .merges = .{ |
| ... | ... | @@ -4634,7 +4587,7 @@ fn zirBitwise( |
| 4634 | 4587 | const lhs_ty = sema.getTypeOf(lhs); |
| 4635 | 4588 | const rhs_ty = sema.getTypeOf(rhs); |
| 4636 | 4589 | |
| 4637 | | const instructions = &[_]Air.Inst.Index{ lhs, rhs }; |
| 4590 | const instructions = &[_]Air.Inst.Ref{ lhs, rhs }; |
| 4638 | 4591 | const resolved_type = try sema.resolvePeerTypes(block, src, instructions); |
| 4639 | 4592 | const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src); |
| 4640 | 4593 | const casted_rhs = try sema.coerce(block, resolved_type, rhs, rhs_src); |
| ... | ... | @@ -4763,18 +4716,8 @@ fn analyzeArithmetic( |
| 4763 | 4716 | lhs_src: LazySrcLoc, |
| 4764 | 4717 | rhs_src: LazySrcLoc, |
| 4765 | 4718 | ) CompileError!Air.Inst.Ref { |
| 4766 | | const instructions = &[_]Air.Inst.Index{ lhs, rhs }; |
| 4767 | | const resolved_type = try sema.resolvePeerTypes(block, src, instructions); |
| 4768 | | const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src); |
| 4769 | | const casted_rhs = try sema.coerce(block, resolved_type, rhs, rhs_src); |
| 4770 | | |
| 4771 | | const scalar_type = if (resolved_type.zigTypeTag() == .Vector) |
| 4772 | | resolved_type.elemType() |
| 4773 | | else |
| 4774 | | resolved_type; |
| 4775 | | |
| 4776 | | const scalar_tag = scalar_type.zigTypeTag(); |
| 4777 | | |
| 4719 | const lhs_ty = sema.getTypeOf(lhs); |
| 4720 | const rhs_ty = sema.getTypeOf(rhs); |
| 4778 | 4721 | if (lhs_ty.zigTypeTag() == .Vector and rhs_ty.zigTypeTag() == .Vector) { |
| 4779 | 4722 | if (lhs_ty.arrayLen() != rhs_ty.arrayLen()) { |
| 4780 | 4723 | return sema.mod.fail(&block.base, src, "vector length mismatch: {d} and {d}", .{ |
| ... | ... | @@ -4790,6 +4733,18 @@ fn analyzeArithmetic( |
| 4790 | 4733 | }); |
| 4791 | 4734 | } |
| 4792 | 4735 | |
| 4736 | const instructions = &[_]Air.Inst.Ref{ lhs, rhs }; |
| 4737 | const resolved_type = try sema.resolvePeerTypes(block, src, instructions); |
| 4738 | const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src); |
| 4739 | const casted_rhs = try sema.coerce(block, resolved_type, rhs, rhs_src); |
| 4740 | |
| 4741 | const scalar_type = if (resolved_type.zigTypeTag() == .Vector) |
| 4742 | resolved_type.elemType() |
| 4743 | else |
| 4744 | resolved_type; |
| 4745 | |
| 4746 | const scalar_tag = scalar_type.zigTypeTag(); |
| 4747 | |
| 4793 | 4748 | const is_int = scalar_tag == .Int or scalar_tag == .ComptimeInt; |
| 4794 | 4749 | const is_float = scalar_tag == .Float or scalar_tag == .ComptimeFloat; |
| 4795 | 4750 | |
| ... | ... | @@ -4807,10 +4762,7 @@ fn analyzeArithmetic( |
| 4807 | 4762 | if (rhs_val.compareWithZero(.eq)) { |
| 4808 | 4763 | switch (zir_tag) { |
| 4809 | 4764 | .add, .addwrap, .sub, .subwrap => { |
| 4810 | | return sema.mod.constInst(sema.arena, src, .{ |
| 4811 | | .ty = scalar_type, |
| 4812 | | .val = lhs_val, |
| 4813 | | }); |
| 4765 | return sema.addConstant(scalar_type, lhs_val); |
| 4814 | 4766 | }, |
| 4815 | 4767 | else => {}, |
| 4816 | 4768 | } |
| ... | ... | @@ -4850,10 +4802,7 @@ fn analyzeArithmetic( |
| 4850 | 4802 | |
| 4851 | 4803 | log.debug("{s}({}, {}) result: {}", .{ @tagName(zir_tag), lhs_val, rhs_val, value }); |
| 4852 | 4804 | |
| 4853 | | return sema.mod.constInst(sema.arena, src, .{ |
| 4854 | | .ty = scalar_type, |
| 4855 | | .val = value, |
| 4856 | | }); |
| 4805 | return sema.addConstant(scalar_type, value); |
| 4857 | 4806 | } |
| 4858 | 4807 | } |
| 4859 | 4808 | |
| ... | ... | @@ -5167,16 +5116,16 @@ fn zirTypeInfo(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileEr |
| 5167 | 5116 | // args: []const FnArg, |
| 5168 | 5117 | field_values[5] = Value.initTag(.null_value); // TODO |
| 5169 | 5118 | |
| 5170 | | return sema.mod.constInst(sema.arena, src, .{ |
| 5171 | | .ty = type_info_ty, |
| 5172 | | .val = try Value.Tag.@"union".create(sema.arena, .{ |
| 5119 | return sema.addConstant( |
| 5120 | type_info_ty, |
| 5121 | try Value.Tag.@"union".create(sema.arena, .{ |
| 5173 | 5122 | .tag = try Value.Tag.enum_field_index.create( |
| 5174 | 5123 | sema.arena, |
| 5175 | 5124 | @enumToInt(@typeInfo(std.builtin.TypeInfo).Union.tag_type.?.Fn), |
| 5176 | 5125 | ), |
| 5177 | 5126 | .val = try Value.Tag.@"struct".create(sema.arena, field_values.ptr), |
| 5178 | 5127 | }), |
| 5179 | | }); |
| 5128 | ); |
| 5180 | 5129 | }, |
| 5181 | 5130 | else => |t| return sema.mod.fail(&block.base, src, "TODO: implement zirTypeInfo for {s}", .{ |
| 5182 | 5131 | @tagName(t), |
| ... | ... | @@ -5189,7 +5138,8 @@ fn zirTypeof(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileErro |
| 5189 | 5138 | const zir_datas = sema.code.instructions.items(.data); |
| 5190 | 5139 | const inst_data = zir_datas[inst].un_node; |
| 5191 | 5140 | const operand = sema.resolveInst(inst_data.operand); |
| 5192 | | return sema.addType(operand.ty); |
| 5141 | const operand_ty = sema.getTypeOf(operand); |
| 5142 | return sema.addType(operand_ty); |
| 5193 | 5143 | } |
| 5194 | 5144 | |
| 5195 | 5145 | fn zirTypeofElem(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| ... | ... | @@ -5241,11 +5191,12 @@ fn zirBoolNot(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileErr |
| 5241 | 5191 | |
| 5242 | 5192 | const inst_data = sema.code.instructions.items(.data)[inst].un_node; |
| 5243 | 5193 | const src = inst_data.src(); |
| 5194 | const operand_src = src; // TODO put this on the operand, not the `!` |
| 5244 | 5195 | const uncasted_operand = sema.resolveInst(inst_data.operand); |
| 5245 | 5196 | |
| 5246 | 5197 | const bool_type = Type.initTag(.bool); |
| 5247 | | const operand = try sema.coerce(block, bool_type, uncasted_operand, uncasted_operand.src); |
| 5248 | | if (try sema.resolveDefinedValue(block, src, operand)) |val| { |
| 5198 | const operand = try sema.coerce(block, bool_type, uncasted_operand, operand_src); |
| 5199 | if (try sema.resolveDefinedValue(block, operand_src, operand)) |val| { |
| 5249 | 5200 | if (val.toBool()) { |
| 5250 | 5201 | return Air.Inst.Ref.bool_false; |
| 5251 | 5202 | } else { |
| ... | ... | @@ -5267,12 +5218,13 @@ fn zirBoolBr( |
| 5267 | 5218 | |
| 5268 | 5219 | const datas = sema.code.instructions.items(.data); |
| 5269 | 5220 | const inst_data = datas[inst].bool_br; |
| 5270 | | const src: LazySrcLoc = .unneeded; |
| 5271 | 5221 | const lhs = sema.resolveInst(inst_data.lhs); |
| 5222 | const lhs_src = sema.src; |
| 5272 | 5223 | const extra = sema.code.extraData(Zir.Inst.Block, inst_data.payload_index); |
| 5273 | 5224 | const body = sema.code.extra[extra.end..][0..extra.data.body_len]; |
| 5225 | const gpa = sema.gpa; |
| 5274 | 5226 | |
| 5275 | | if (try sema.resolveDefinedValue(parent_block, src, lhs)) |lhs_val| { |
| 5227 | if (try sema.resolveDefinedValue(parent_block, lhs_src, lhs)) |lhs_val| { |
| 5276 | 5228 | if (lhs_val.toBool() == is_bool_or) { |
| 5277 | 5229 | if (is_bool_or) { |
| 5278 | 5230 | return Air.Inst.Ref.bool_true; |
| ... | ... | @@ -5286,49 +5238,59 @@ fn zirBoolBr( |
| 5286 | 5238 | return sema.resolveBody(parent_block, body); |
| 5287 | 5239 | } |
| 5288 | 5240 | |
| 5289 | | const block_inst = try sema.arena.create(Inst.Block); |
| 5290 | | block_inst.* = .{ |
| 5291 | | .base = .{ |
| 5292 | | .tag = Inst.Block.base_tag, |
| 5293 | | .ty = Type.initTag(.bool), |
| 5294 | | .src = src, |
| 5295 | | }, |
| 5296 | | .body = undefined, |
| 5297 | | }; |
| 5241 | const block_inst = @intCast(Air.Inst.Index, sema.air_instructions.len); |
| 5242 | try sema.air_instructions.append(gpa, .{ |
| 5243 | .tag = .block, |
| 5244 | .data = .{ .ty_pl = .{ |
| 5245 | .ty = .bool_type, |
| 5246 | .payload = undefined, |
| 5247 | } }, |
| 5248 | }); |
| 5298 | 5249 | |
| 5299 | 5250 | var child_block = parent_block.makeSubBlock(); |
| 5300 | 5251 | child_block.runtime_loop = null; |
| 5301 | | child_block.runtime_cond = lhs.src; |
| 5252 | child_block.runtime_cond = lhs_src; |
| 5302 | 5253 | child_block.runtime_index += 1; |
| 5303 | | defer child_block.instructions.deinit(sema.gpa); |
| 5254 | defer child_block.instructions.deinit(gpa); |
| 5304 | 5255 | |
| 5305 | 5256 | var then_block = child_block.makeSubBlock(); |
| 5306 | | defer then_block.instructions.deinit(sema.gpa); |
| 5257 | defer then_block.instructions.deinit(gpa); |
| 5307 | 5258 | |
| 5308 | 5259 | var else_block = child_block.makeSubBlock(); |
| 5309 | | defer else_block.instructions.deinit(sema.gpa); |
| 5260 | defer else_block.instructions.deinit(gpa); |
| 5310 | 5261 | |
| 5311 | 5262 | const lhs_block = if (is_bool_or) &then_block else &else_block; |
| 5312 | 5263 | const rhs_block = if (is_bool_or) &else_block else &then_block; |
| 5313 | 5264 | |
| 5314 | | const lhs_result = try sema.mod.constInst(sema.arena, src, .{ |
| 5315 | | .ty = Type.initTag(.bool), |
| 5316 | | .val = if (is_bool_or) Value.initTag(.bool_true) else Value.initTag(.bool_false), |
| 5317 | | }); |
| 5318 | | _ = try lhs_block.addBr(src, block_inst, lhs_result); |
| 5265 | const lhs_result: Air.Inst.Ref = if (is_bool_or) .bool_true else .bool_false; |
| 5266 | _ = try lhs_block.addBr(block_inst, lhs_result); |
| 5319 | 5267 | |
| 5320 | 5268 | const rhs_result = try sema.resolveBody(rhs_block, body); |
| 5321 | | _ = try rhs_block.addBr(src, block_inst, rhs_result); |
| 5269 | _ = try rhs_block.addBr(block_inst, rhs_result); |
| 5322 | 5270 | |
| 5323 | | const air_then_body: ir.Body = .{ .instructions = try sema.arena.dupe(Air.Inst.Index, then_block.instructions.items) }; |
| 5324 | | const air_else_body: ir.Body = .{ .instructions = try sema.arena.dupe(Air.Inst.Index, else_block.instructions.items) }; |
| 5325 | | _ = try child_block.addCondBr(src, lhs, air_then_body, air_else_body); |
| 5271 | try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.CondBr).Struct.fields.len + |
| 5272 | then_block.instructions.items.len + else_block.instructions.items.len + |
| 5273 | @typeInfo(Air.Block).Struct.fields.len + child_block.instructions.items.len); |
| 5326 | 5274 | |
| 5327 | | block_inst.body = .{ |
| 5328 | | .instructions = try sema.arena.dupe(Air.Inst.Index, child_block.instructions.items), |
| 5329 | | }; |
| 5330 | | try parent_block.instructions.append(sema.gpa, &block_inst.base); |
| 5331 | | return &block_inst.base; |
| 5275 | sema.air_instructions.items(.data)[block_inst].ty_pl.payload = sema.addExtraAssumeCapacity( |
| 5276 | Air.Block{ .body_len = @intCast(u32, child_block.instructions.items.len) }, |
| 5277 | ); |
| 5278 | sema.air_extra.appendSliceAssumeCapacity(child_block.instructions.items); |
| 5279 | |
| 5280 | const cond_br_payload = sema.addExtraAssumeCapacity(Air.CondBr{ |
| 5281 | .then_body_len = @intCast(u32, then_block.instructions.items.len), |
| 5282 | .else_body_len = @intCast(u32, else_block.instructions.items.len), |
| 5283 | }); |
| 5284 | sema.air_extra.appendSliceAssumeCapacity(then_block.instructions.items); |
| 5285 | sema.air_extra.appendSliceAssumeCapacity(else_block.instructions.items); |
| 5286 | |
| 5287 | _ = try child_block.addInst(.{ .tag = .cond_br, .data = .{ .pl_op = .{ |
| 5288 | .operand = lhs, |
| 5289 | .payload = cond_br_payload, |
| 5290 | } } }); |
| 5291 | |
| 5292 | try parent_block.instructions.append(gpa, block_inst); |
| 5293 | return indexToRef(block_inst); |
| 5332 | 5294 | } |
| 5333 | 5295 | |
| 5334 | 5296 | fn zirIsNonNull( |
| ... | ... | @@ -5439,7 +5401,7 @@ fn zirUnreachable(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Compil |
| 5439 | 5401 | if (safety_check and block.wantSafety()) { |
| 5440 | 5402 | return sema.safetyPanic(block, src, .unreach); |
| 5441 | 5403 | } else { |
| 5442 | | _ = try block.addNoOp(src, Type.initTag(.noreturn), .unreach); |
| 5404 | _ = try block.addNoOp(.unreach); |
| 5443 | 5405 | return always_noreturn; |
| 5444 | 5406 | } |
| 5445 | 5407 | } |
| ... | ... | @@ -5461,10 +5423,10 @@ fn zirRetErrValue( |
| 5461 | 5423 | } |
| 5462 | 5424 | // Return the error code from the function. |
| 5463 | 5425 | const kv = try sema.mod.getErrorValue(err_name); |
| 5464 | | const result_inst = try sema.mod.constInst(sema.arena, src, .{ |
| 5465 | | .ty = try Type.Tag.error_set_single.create(sema.arena, kv.key), |
| 5466 | | .val = try Value.Tag.@"error".create(sema.arena, .{ .name = kv.key }), |
| 5467 | | }); |
| 5426 | const result_inst = try sema.addConstant( |
| 5427 | try Type.Tag.error_set_single.create(sema.arena, kv.key), |
| 5428 | try Value.Tag.@"error".create(sema.arena, .{ .name = kv.key }), |
| 5429 | ); |
| 5468 | 5430 | return sema.analyzeRet(block, result_inst, src, true); |
| 5469 | 5431 | } |
| 5470 | 5432 | |
| ... | ... | @@ -5505,7 +5467,7 @@ fn analyzeRet( |
| 5505 | 5467 | if (block.inlining) |inlining| { |
| 5506 | 5468 | // We are inlining a function call; rewrite the `ret` as a `break`. |
| 5507 | 5469 | try inlining.merges.results.append(sema.gpa, operand); |
| 5508 | | _ = try block.addBr(src, inlining.merges.block_inst, operand); |
| 5470 | _ = try block.addBr(inlining.merges.block_inst, operand); |
| 5509 | 5471 | return always_noreturn; |
| 5510 | 5472 | } |
| 5511 | 5473 | |
| ... | ... | @@ -5613,10 +5575,7 @@ fn zirStructInitEmpty(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Co |
| 5613 | 5575 | const src = inst_data.src(); |
| 5614 | 5576 | const struct_type = try sema.resolveType(block, src, inst_data.operand); |
| 5615 | 5577 | |
| 5616 | | return sema.mod.constInst(sema.arena, src, .{ |
| 5617 | | .ty = struct_type, |
| 5618 | | .val = Value.initTag(.empty_struct_value), |
| 5619 | | }); |
| 5578 | return sema.addConstant(struct_type, Value.initTag(.empty_struct_value)); |
| 5620 | 5579 | } |
| 5621 | 5580 | |
| 5622 | 5581 | fn zirUnionInitPtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| ... | ... | @@ -5696,10 +5655,7 @@ fn zirStructInit(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index, is_ref: |
| 5696 | 5655 | root_msg = try mod.errMsg(&block.base, src, template, args); |
| 5697 | 5656 | } |
| 5698 | 5657 | } else { |
| 5699 | | field_inits[i] = try mod.constInst(sema.arena, src, .{ |
| 5700 | | .ty = field.ty, |
| 5701 | | .val = field.default_val, |
| 5702 | | }); |
| 5658 | field_inits[i] = try sema.addConstant(field.ty, field.default_val); |
| 5703 | 5659 | } |
| 5704 | 5660 | } |
| 5705 | 5661 | if (root_msg) |msg| { |
| ... | ... | @@ -5729,10 +5685,7 @@ fn zirStructInit(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index, is_ref: |
| 5729 | 5685 | for (field_inits) |field_init, i| { |
| 5730 | 5686 | values[i] = field_init.value().?; |
| 5731 | 5687 | } |
| 5732 | | return mod.constInst(sema.arena, src, .{ |
| 5733 | | .ty = struct_ty, |
| 5734 | | .val = try Value.Tag.@"struct".create(sema.arena, values.ptr), |
| 5735 | | }); |
| 5688 | return sema.addConstant(struct_ty, try Value.Tag.@"struct".create(sema.arena, values.ptr)); |
| 5736 | 5689 | } |
| 5737 | 5690 | |
| 5738 | 5691 | return mod.fail(&block.base, src, "TODO: Sema.zirStructInit for runtime-known struct values", .{}); |
| ... | ... | @@ -5913,20 +5866,13 @@ fn zirIntToPtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileEr |
| 5913 | 5866 | .base = .{ .tag = .int_u64 }, |
| 5914 | 5867 | .data = addr, |
| 5915 | 5868 | }; |
| 5916 | | return sema.mod.constInst(sema.arena, src, .{ |
| 5917 | | .ty = type_res, |
| 5918 | | .val = Value.initPayload(&val_payload.base), |
| 5919 | | }); |
| 5869 | return sema.addConstant(type_res, Value.initPayload(&val_payload.base)); |
| 5920 | 5870 | } |
| 5921 | 5871 | |
| 5922 | 5872 | try sema.requireRuntimeBlock(block, src); |
| 5923 | 5873 | if (block.wantSafety()) { |
| 5924 | | const zero = try sema.mod.constInst(sema.arena, src, .{ |
| 5925 | | .ty = Type.initTag(.u64), |
| 5926 | | .val = Value.initTag(.zero), |
| 5927 | | }); |
| 5928 | 5874 | if (!type_res.isAllowzeroPtr()) { |
| 5929 | | const is_non_zero = try block.addBinOp(.cmp_neq, operand_coerced, zero); |
| 5875 | const is_non_zero = try block.addBinOp(.cmp_neq, operand_coerced, .zero_usize); |
| 5930 | 5876 | try sema.addSafetyCheck(block, is_non_zero, .cast_to_null); |
| 5931 | 5877 | } |
| 5932 | 5878 | |
| ... | ... | @@ -5936,12 +5882,12 @@ fn zirIntToPtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileEr |
| 5936 | 5882 | .base = .{ .tag = .int_u64 }, |
| 5937 | 5883 | .data = ptr_align - 1, |
| 5938 | 5884 | }; |
| 5939 | | const align_minus_1 = try sema.mod.constInst(sema.arena, src, .{ |
| 5940 | | .ty = Type.initTag(.u64), |
| 5941 | | .val = Value.initPayload(&val_payload.base), |
| 5942 | | }); |
| 5885 | const align_minus_1 = try sema.addConstant( |
| 5886 | Type.initTag(.usize), |
| 5887 | Value.initPayload(&val_payload.base), |
| 5888 | ); |
| 5943 | 5889 | const remainder = try block.addBinOp(.bit_and, operand_coerced, align_minus_1); |
| 5944 | | const is_aligned = try block.addBinOp(.cmp_eq, remainder, zero); |
| 5890 | const is_aligned = try block.addBinOp(.cmp_eq, remainder, .zero_usize); |
| 5945 | 5891 | try sema.addSafetyCheck(block, is_aligned, .incorrect_alignment); |
| 5946 | 5892 | } |
| 5947 | 5893 | } |
| ... | ... | @@ -6217,10 +6163,10 @@ fn zirVarExtended( |
| 6217 | 6163 | .is_mutable = true, // TODO get rid of this unused field |
| 6218 | 6164 | .is_threadlocal = small.is_threadlocal, |
| 6219 | 6165 | }; |
| 6220 | | const result = try sema.mod.constInst(sema.arena, src, .{ |
| 6221 | | .ty = var_ty, |
| 6222 | | .val = try Value.Tag.variable.create(sema.arena, new_var), |
| 6223 | | }); |
| 6166 | const result = try sema.addConstant( |
| 6167 | var_ty, |
| 6168 | try Value.Tag.variable.create(sema.arena, new_var), |
| 6169 | ); |
| 6224 | 6170 | return result; |
| 6225 | 6171 | } |
| 6226 | 6172 | |
| ... | ... | @@ -6380,32 +6326,13 @@ pub const PanicId = enum { |
| 6380 | 6326 | invalid_error_code, |
| 6381 | 6327 | }; |
| 6382 | 6328 | |
| 6383 | | fn addSafetyCheck(sema: *Sema, parent_block: *Scope.Block, ok: Air.Inst.Ref, panic_id: PanicId) !void { |
| 6384 | | const block_inst = try sema.arena.create(Inst.Block); |
| 6385 | | block_inst.* = .{ |
| 6386 | | .base = .{ |
| 6387 | | .tag = Inst.Block.base_tag, |
| 6388 | | .ty = Type.initTag(.void), |
| 6389 | | .src = ok.src, |
| 6390 | | }, |
| 6391 | | .body = .{ |
| 6392 | | .instructions = try sema.arena.alloc(Air.Inst.Index, 1), // Only need space for the condbr. |
| 6393 | | }, |
| 6394 | | }; |
| 6395 | | |
| 6396 | | const ok_body: ir.Body = .{ |
| 6397 | | .instructions = try sema.arena.alloc(Air.Inst.Index, 1), // Only need space for the br_void. |
| 6398 | | }; |
| 6399 | | const br_void = try sema.arena.create(Inst.BrVoid); |
| 6400 | | br_void.* = .{ |
| 6401 | | .base = .{ |
| 6402 | | .tag = .br_void, |
| 6403 | | .ty = Type.initTag(.noreturn), |
| 6404 | | .src = ok.src, |
| 6405 | | }, |
| 6406 | | .block = block_inst, |
| 6407 | | }; |
| 6408 | | ok_body.instructions[0] = &br_void.base; |
| 6329 | fn addSafetyCheck( |
| 6330 | sema: *Sema, |
| 6331 | parent_block: *Scope.Block, |
| 6332 | ok: Air.Inst.Ref, |
| 6333 | panic_id: PanicId, |
| 6334 | ) !void { |
| 6335 | const gpa = sema.gpa; |
| 6409 | 6336 | |
| 6410 | 6337 | var fail_block: Scope.Block = .{ |
| 6411 | 6338 | .parent = parent_block, |
| ... | ... | @@ -6416,26 +6343,55 @@ fn addSafetyCheck(sema: *Sema, parent_block: *Scope.Block, ok: Air.Inst.Ref, pan |
| 6416 | 6343 | .is_comptime = parent_block.is_comptime, |
| 6417 | 6344 | }; |
| 6418 | 6345 | |
| 6419 | | defer fail_block.instructions.deinit(sema.gpa); |
| 6346 | defer fail_block.instructions.deinit(gpa); |
| 6420 | 6347 | |
| 6421 | | _ = try sema.safetyPanic(&fail_block, ok.src, panic_id); |
| 6348 | _ = try sema.safetyPanic(&fail_block, .unneeded, panic_id); |
| 6422 | 6349 | |
| 6423 | | const fail_body: ir.Body = .{ .instructions = try sema.arena.dupe(Air.Inst.Index, fail_block.instructions.items) }; |
| 6350 | try parent_block.instructions.ensureUnusedCapacity(gpa, 1); |
| 6424 | 6351 | |
| 6425 | | const condbr = try sema.arena.create(Inst.CondBr); |
| 6426 | | condbr.* = .{ |
| 6427 | | .base = .{ |
| 6428 | | .tag = .condbr, |
| 6429 | | .ty = Type.initTag(.noreturn), |
| 6430 | | .src = ok.src, |
| 6431 | | }, |
| 6432 | | .condition = ok, |
| 6433 | | .then_body = ok_body, |
| 6434 | | .else_body = fail_body, |
| 6435 | | }; |
| 6436 | | block_inst.body.instructions[0] = &condbr.base; |
| 6352 | try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.Block).Struct.fields.len + |
| 6353 | 1 + // The main block only needs space for the cond_br. |
| 6354 | @typeInfo(Air.CondBr).Struct.fields.len + |
| 6355 | 1 + // The ok branch of the cond_br only needs space for the br. |
| 6356 | fail_block.instructions.items.len); |
| 6437 | 6357 | |
| 6438 | | try parent_block.instructions.append(sema.gpa, &block_inst.base); |
| 6358 | try sema.air_instructions.ensureUnusedCapacity(gpa, 3); |
| 6359 | const block_inst = @intCast(Air.Inst.Index, sema.air_instructions.len); |
| 6360 | const cond_br_inst = block_inst + 1; |
| 6361 | const br_inst = cond_br_inst + 1; |
| 6362 | sema.air_instructions.appendAssumeCapacity(gpa, .{ |
| 6363 | .tag = .block, |
| 6364 | .data = .{ .ty_pl = .{ |
| 6365 | .ty = .void_type, |
| 6366 | .payload = sema.addExtraAssumeCapacity(Air.Block{ |
| 6367 | .body_len = 1, |
| 6368 | }), |
| 6369 | } }, |
| 6370 | }); |
| 6371 | sema.air_extra.appendAssumeCapacity(cond_br_inst); |
| 6372 | |
| 6373 | sema.air_instructions.appendAssumeCapacity(gpa, .{ |
| 6374 | .tag = .cond_br, |
| 6375 | .data = .{ .pl_op = .{ |
| 6376 | .operand = ok, |
| 6377 | .payload = sema.addExtraAssumeCapacity(Air.CondBr{ |
| 6378 | .then_body_len = 1, |
| 6379 | .else_body_len = @intCast(u32, fail_block.instructions.items.len), |
| 6380 | }), |
| 6381 | } }, |
| 6382 | }); |
| 6383 | sema.air_extra.appendAssumeCapacity(br_inst); |
| 6384 | sema.air_extra.appendSliceAssumeCapacity(fail_block.instructions.items); |
| 6385 | |
| 6386 | sema.air_instructions.appendAssumeCapacity(gpa, .{ |
| 6387 | .tag = .br, |
| 6388 | .data = .{ .br = .{ |
| 6389 | .block_inst = block_inst, |
| 6390 | .operand = .void_value, |
| 6391 | } }, |
| 6392 | }); |
| 6393 | |
| 6394 | parent_block.instructions.appendAssumeCapacity(block_inst); |
| 6439 | 6395 | } |
| 6440 | 6396 | |
| 6441 | 6397 | fn panicWithMsg( |
| ... | ... | @@ -6451,18 +6407,18 @@ fn panicWithMsg( |
| 6451 | 6407 | mod.comp.bin_file.options.object_format == .c; |
| 6452 | 6408 | if (!this_feature_is_implemented_in_the_backend) { |
| 6453 | 6409 | // TODO implement this feature in all the backends and then delete this branch |
| 6454 | | _ = try block.addNoOp(src, Type.initTag(.void), .breakpoint); |
| 6455 | | _ = try block.addNoOp(src, Type.initTag(.noreturn), .unreach); |
| 6410 | _ = try block.addNoOp(.breakpoint); |
| 6411 | _ = try block.addNoOp(.unreach); |
| 6456 | 6412 | return always_noreturn; |
| 6457 | 6413 | } |
| 6458 | 6414 | const panic_fn = try sema.getBuiltin(block, src, "panic"); |
| 6459 | 6415 | const unresolved_stack_trace_ty = try sema.getBuiltinType(block, src, "StackTrace"); |
| 6460 | 6416 | const stack_trace_ty = try sema.resolveTypeFields(block, src, unresolved_stack_trace_ty); |
| 6461 | 6417 | const ptr_stack_trace_ty = try Module.simplePtrType(arena, stack_trace_ty, true, .One); |
| 6462 | | const null_stack_trace = try mod.constInst(arena, src, .{ |
| 6463 | | .ty = try mod.optionalType(arena, ptr_stack_trace_ty), |
| 6464 | | .val = Value.initTag(.null_value), |
| 6465 | | }); |
| 6418 | const null_stack_trace = try sema.addConstant( |
| 6419 | try mod.optionalType(arena, ptr_stack_trace_ty), |
| 6420 | Value.initTag(.null_value), |
| 6421 | ); |
| 6466 | 6422 | const args = try arena.create([2]Air.Inst.Index); |
| 6467 | 6423 | args.* = .{ msg_inst, null_stack_trace }; |
| 6468 | 6424 | _ = try sema.analyzeCall(block, panic_fn, src, src, .auto, false, args); |
| ... | ... | @@ -6503,7 +6459,6 @@ fn safetyPanic( |
| 6503 | 6459 | }; |
| 6504 | 6460 | |
| 6505 | 6461 | const casted_msg_inst = try sema.coerce(block, Type.initTag(.const_slice_u8), msg_inst, src); |
| 6506 | | |
| 6507 | 6462 | return sema.panicWithMsg(block, src, casted_msg_inst); |
| 6508 | 6463 | } |
| 6509 | 6464 | |
| ... | ... | @@ -6533,13 +6488,13 @@ fn namedFieldPtr( |
| 6533 | 6488 | switch (elem_ty.zigTypeTag()) { |
| 6534 | 6489 | .Array => { |
| 6535 | 6490 | if (mem.eql(u8, field_name, "len")) { |
| 6536 | | return mod.constInst(arena, src, .{ |
| 6537 | | .ty = Type.initTag(.single_const_pointer_to_comptime_int), |
| 6538 | | .val = try Value.Tag.ref_val.create( |
| 6491 | return sema.addConstant( |
| 6492 | Type.initTag(.single_const_pointer_to_comptime_int), |
| 6493 | try Value.Tag.ref_val.create( |
| 6539 | 6494 | arena, |
| 6540 | 6495 | try Value.Tag.int_u64.create(arena, elem_ty.arrayLen()), |
| 6541 | 6496 | ), |
| 6542 | | }); |
| 6497 | ); |
| 6543 | 6498 | } else { |
| 6544 | 6499 | return mod.fail( |
| 6545 | 6500 | &block.base, |
| ... | ... | @@ -6554,13 +6509,13 @@ fn namedFieldPtr( |
| 6554 | 6509 | switch (ptr_child.zigTypeTag()) { |
| 6555 | 6510 | .Array => { |
| 6556 | 6511 | if (mem.eql(u8, field_name, "len")) { |
| 6557 | | return mod.constInst(arena, src, .{ |
| 6558 | | .ty = Type.initTag(.single_const_pointer_to_comptime_int), |
| 6559 | | .val = try Value.Tag.ref_val.create( |
| 6512 | return sema.addConstant( |
| 6513 | Type.initTag(.single_const_pointer_to_comptime_int), |
| 6514 | try Value.Tag.ref_val.create( |
| 6560 | 6515 | arena, |
| 6561 | 6516 | try Value.Tag.int_u64.create(arena, ptr_child.arrayLen()), |
| 6562 | 6517 | ), |
| 6563 | | }); |
| 6518 | ); |
| 6564 | 6519 | } else { |
| 6565 | 6520 | return mod.fail( |
| 6566 | 6521 | &block.base, |
| ... | ... | @@ -6597,15 +6552,15 @@ fn namedFieldPtr( |
| 6597 | 6552 | }); |
| 6598 | 6553 | } else (try mod.getErrorValue(field_name)).key; |
| 6599 | 6554 | |
| 6600 | | return mod.constInst(arena, src, .{ |
| 6601 | | .ty = try Module.simplePtrType(arena, child_type, false, .One), |
| 6602 | | .val = try Value.Tag.ref_val.create( |
| 6555 | return sema.addConstant( |
| 6556 | try Module.simplePtrType(arena, child_type, false, .One), |
| 6557 | try Value.Tag.ref_val.create( |
| 6603 | 6558 | arena, |
| 6604 | 6559 | try Value.Tag.@"error".create(arena, .{ |
| 6605 | 6560 | .name = name, |
| 6606 | 6561 | }), |
| 6607 | 6562 | ), |
| 6608 | | }); |
| 6563 | ); |
| 6609 | 6564 | }, |
| 6610 | 6565 | .Struct, .Opaque, .Union => { |
| 6611 | 6566 | if (child_type.getNamespace()) |namespace| { |
| ... | ... | @@ -6651,10 +6606,10 @@ fn namedFieldPtr( |
| 6651 | 6606 | }; |
| 6652 | 6607 | const field_index_u32 = @intCast(u32, field_index); |
| 6653 | 6608 | const enum_val = try Value.Tag.enum_field_index.create(arena, field_index_u32); |
| 6654 | | return mod.constInst(arena, src, .{ |
| 6655 | | .ty = try Module.simplePtrType(arena, child_type, false, .One), |
| 6656 | | .val = try Value.Tag.ref_val.create(arena, enum_val), |
| 6657 | | }); |
| 6609 | return sema.addConstant( |
| 6610 | try Module.simplePtrType(arena, child_type, false, .One), |
| 6611 | try Value.Tag.ref_val.create(arena, enum_val), |
| 6612 | ); |
| 6658 | 6613 | }, |
| 6659 | 6614 | else => return mod.fail(&block.base, src, "type '{}' has no members", .{child_type}), |
| 6660 | 6615 | } |
| ... | ... | @@ -6701,7 +6656,6 @@ fn analyzeStructFieldPtr( |
| 6701 | 6656 | field_name_src: LazySrcLoc, |
| 6702 | 6657 | unresolved_struct_ty: Type, |
| 6703 | 6658 | ) CompileError!Air.Inst.Ref { |
| 6704 | | const mod = sema.mod; |
| 6705 | 6659 | const arena = sema.arena; |
| 6706 | 6660 | assert(unresolved_struct_ty.zigTypeTag() == .Struct); |
| 6707 | 6661 | |
| ... | ... | @@ -6714,13 +6668,13 @@ fn analyzeStructFieldPtr( |
| 6714 | 6668 | const ptr_field_ty = try Module.simplePtrType(arena, field.ty, true, .One); |
| 6715 | 6669 | |
| 6716 | 6670 | if (try sema.resolveDefinedValue(block, src, struct_ptr)) |struct_ptr_val| { |
| 6717 | | return mod.constInst(arena, src, .{ |
| 6718 | | .ty = ptr_field_ty, |
| 6719 | | .val = try Value.Tag.field_ptr.create(arena, .{ |
| 6671 | return sema.addConstant( |
| 6672 | ptr_field_ty, |
| 6673 | try Value.Tag.field_ptr.create(arena, .{ |
| 6720 | 6674 | .container_ptr = struct_ptr_val, |
| 6721 | 6675 | .field_index = field_index, |
| 6722 | 6676 | }), |
| 6723 | | }); |
| 6677 | ); |
| 6724 | 6678 | } |
| 6725 | 6679 | |
| 6726 | 6680 | try sema.requireRuntimeBlock(block, src); |
| ... | ... | @@ -6751,13 +6705,13 @@ fn analyzeUnionFieldPtr( |
| 6751 | 6705 | |
| 6752 | 6706 | if (try sema.resolveDefinedValue(block, src, union_ptr)) |union_ptr_val| { |
| 6753 | 6707 | // TODO detect inactive union field and emit compile error |
| 6754 | | return mod.constInst(arena, src, .{ |
| 6755 | | .ty = ptr_field_ty, |
| 6756 | | .val = try Value.Tag.field_ptr.create(arena, .{ |
| 6708 | return sema.addConstant( |
| 6709 | ptr_field_ty, |
| 6710 | try Value.Tag.field_ptr.create(arena, .{ |
| 6757 | 6711 | .container_ptr = union_ptr_val, |
| 6758 | 6712 | .field_index = field_index, |
| 6759 | 6713 | }), |
| 6760 | | }); |
| 6714 | ); |
| 6761 | 6715 | } |
| 6762 | 6716 | |
| 6763 | 6717 | try sema.requireRuntimeBlock(block, src); |
| ... | ... | @@ -6808,10 +6762,10 @@ fn elemPtrArray( |
| 6808 | 6762 | const elem_ptr = try array_ptr_val.elemPtr(sema.arena, @intCast(usize, index_u64)); |
| 6809 | 6763 | const pointee_type = array_ptr.ty.elemType().elemType(); |
| 6810 | 6764 | |
| 6811 | | return sema.mod.constInst(sema.arena, src, .{ |
| 6812 | | .ty = try Type.Tag.single_const_pointer.create(sema.arena, pointee_type), |
| 6813 | | .val = elem_ptr, |
| 6814 | | }); |
| 6765 | return sema.addConstant( |
| 6766 | try Type.Tag.single_const_pointer.create(sema.arena, pointee_type), |
| 6767 | elem_ptr, |
| 6768 | ); |
| 6815 | 6769 | } |
| 6816 | 6770 | } |
| 6817 | 6771 | _ = elem_index; |
| ... | ... | @@ -6870,7 +6824,7 @@ fn coerce( |
| 6870 | 6824 | .Optional => { |
| 6871 | 6825 | // null to ?T |
| 6872 | 6826 | if (inst_ty.zigTypeTag() == .Null) { |
| 6873 | | return mod.constInst(arena, inst_src, .{ .ty = dest_type, .val = Value.initTag(.null_value) }); |
| 6827 | return sema.addConstant(dest_type, Value.initTag(.null_value)); |
| 6874 | 6828 | } |
| 6875 | 6829 | |
| 6876 | 6830 | // T to ?T |
| ... | ... | @@ -6981,10 +6935,10 @@ fn coerce( |
| 6981 | 6935 | }; |
| 6982 | 6936 | return mod.failWithOwnedErrorMsg(&block.base, msg); |
| 6983 | 6937 | }; |
| 6984 | | return mod.constInst(arena, inst_src, .{ |
| 6985 | | .ty = resolved_dest_type, |
| 6986 | | .val = try Value.Tag.enum_field_index.create(arena, @intCast(u32, field_index)), |
| 6987 | | }); |
| 6938 | return sema.addConstant( |
| 6939 | resolved_dest_type, |
| 6940 | try Value.Tag.enum_field_index.create(arena, @intCast(u32, field_index)), |
| 6941 | ); |
| 6988 | 6942 | } |
| 6989 | 6943 | }, |
| 6990 | 6944 | else => {}, |
| ... | ... | @@ -7024,7 +6978,7 @@ fn coerceNum(sema: *Sema, block: *Scope.Block, dest_type: Type, inst: Air.Inst.R |
| 7024 | 6978 | if (!val.intFitsInType(dest_type, target)) { |
| 7025 | 6979 | return sema.mod.fail(&block.base, inst.src, "type {} cannot represent integer value {}", .{ inst.ty, val }); |
| 7026 | 6980 | } |
| 7027 | | return sema.mod.constInst(sema.arena, inst.src, .{ .ty = dest_type, .val = val }); |
| 6981 | return sema.addConstant(dest_type, val); |
| 7028 | 6982 | } |
| 7029 | 6983 | } else if (dst_zig_tag == .ComptimeFloat or dst_zig_tag == .Float) { |
| 7030 | 6984 | if (src_zig_tag == .Float or src_zig_tag == .ComptimeFloat) { |
| ... | ... | @@ -7037,7 +6991,7 @@ fn coerceNum(sema: *Sema, block: *Scope.Block, dest_type: Type, inst: Air.Inst.R |
| 7037 | 6991 | ), |
| 7038 | 6992 | error.OutOfMemory => return error.OutOfMemory, |
| 7039 | 6993 | }; |
| 7040 | | return sema.mod.constInst(sema.arena, inst.src, .{ .ty = dest_type, .val = res }); |
| 6994 | return sema.addConstant(dest_type, res); |
| 7041 | 6995 | } else if (src_zig_tag == .Int or src_zig_tag == .ComptimeInt) { |
| 7042 | 6996 | return sema.mod.fail(&block.base, inst.src, "TODO int to float", .{}); |
| 7043 | 6997 | } |
| ... | ... | @@ -7132,7 +7086,7 @@ fn bitcast( |
| 7132 | 7086 | fn coerceArrayPtrToSlice(sema: *Sema, block: *Scope.Block, dest_type: Type, inst: Air.Inst.Ref) CompileError!Air.Inst.Ref { |
| 7133 | 7087 | if (inst.value()) |val| { |
| 7134 | 7088 | // The comptime Value representation is compatible with both types. |
| 7135 | | return sema.mod.constInst(sema.arena, inst.src, .{ .ty = dest_type, .val = val }); |
| 7089 | return sema.addConstant(dest_type, val); |
| 7136 | 7090 | } |
| 7137 | 7091 | return sema.mod.fail(&block.base, inst.src, "TODO implement coerceArrayPtrToSlice runtime instruction", .{}); |
| 7138 | 7092 | } |
| ... | ... | @@ -7140,7 +7094,7 @@ fn coerceArrayPtrToSlice(sema: *Sema, block: *Scope.Block, dest_type: Type, inst |
| 7140 | 7094 | fn coerceArrayPtrToMany(sema: *Sema, block: *Scope.Block, dest_type: Type, inst: Air.Inst.Ref) !Air.Inst.Ref { |
| 7141 | 7095 | if (inst.value()) |val| { |
| 7142 | 7096 | // The comptime Value representation is compatible with both types. |
| 7143 | | return sema.mod.constInst(sema.arena, inst.src, .{ .ty = dest_type, .val = val }); |
| 7097 | return sema.addConstant(dest_type, val); |
| 7144 | 7098 | } |
| 7145 | 7099 | return sema.mod.fail(&block.base, inst.src, "TODO implement coerceArrayPtrToMany runtime instruction", .{}); |
| 7146 | 7100 | } |
| ... | ... | @@ -7200,13 +7154,11 @@ fn analyzeRef( |
| 7200 | 7154 | src: LazySrcLoc, |
| 7201 | 7155 | operand: Air.Inst.Ref, |
| 7202 | 7156 | ) CompileError!Air.Inst.Ref { |
| 7203 | | const ptr_type = try sema.mod.simplePtrType(sema.arena, operand.ty, false, .One); |
| 7157 | const operand_ty = sema.getTypeOf(operand); |
| 7158 | const ptr_type = try sema.mod.simplePtrType(sema.arena, operand_ty, false, .One); |
| 7204 | 7159 | |
| 7205 | 7160 | if (try sema.resolvePossiblyUndefinedValue(block, src, operand)) |val| { |
| 7206 | | return sema.mod.constInst(sema.arena, src, .{ |
| 7207 | | .ty = ptr_type, |
| 7208 | | .val = try Value.Tag.ref_val.create(sema.arena, val), |
| 7209 | | }); |
| 7161 | return sema.addConstant(ptr_type, try Value.Tag.ref_val.create(sema.arena, val)); |
| 7210 | 7162 | } |
| 7211 | 7163 | |
| 7212 | 7164 | try sema.requireRuntimeBlock(block, src); |
| ... | ... | @@ -7267,7 +7219,8 @@ fn analyzeIsNonErr( |
| 7267 | 7219 | src: LazySrcLoc, |
| 7268 | 7220 | operand: Air.Inst.Ref, |
| 7269 | 7221 | ) CompileError!Air.Inst.Ref { |
| 7270 | | const ot = operand.ty.zigTypeTag(); |
| 7222 | const operand_ty = sema.getTypeOf(operand); |
| 7223 | const ot = operand_ty.zigTypeTag(); |
| 7271 | 7224 | if (ot != .ErrorSet and ot != .ErrorUnion) return Air.Inst.Ref.bool_true; |
| 7272 | 7225 | if (ot == .ErrorSet) return Air.Inst.Ref.bool_false; |
| 7273 | 7226 | assert(ot == .ErrorUnion); |
| ... | ... | @@ -7549,7 +7502,7 @@ fn cmpNumeric( |
| 7549 | 7502 | |
| 7550 | 7503 | fn wrapOptional(sema: *Sema, block: *Scope.Block, dest_type: Type, inst: Air.Inst.Ref) !Air.Inst.Index { |
| 7551 | 7504 | if (try sema.resolvePossiblyUndefinedValue(block, inst_src, inst)) |val| { |
| 7552 | | return sema.mod.constInst(sema.arena, inst_src, .{ .ty = dest_type, .val = val }); |
| 7505 | return sema.addConstant(dest_type, val); |
| 7553 | 7506 | } |
| 7554 | 7507 | |
| 7555 | 7508 | try sema.requireRuntimeBlock(block, inst.src); |
| ... | ... | @@ -7614,11 +7567,8 @@ fn wrapErrorUnion( |
| 7614 | 7567 | else => unreachable, |
| 7615 | 7568 | } |
| 7616 | 7569 | |
| 7617 | | return sema.mod.constInst(sema.arena, inst.src, .{ |
| 7618 | | .ty = dest_type, |
| 7619 | | // creating a SubValue for the error_union payload |
| 7620 | | .val = try Value.Tag.error_union.create(sema.arena, val), |
| 7621 | | }); |
| 7570 | // Create a SubValue for the error_union payload. |
| 7571 | return sema.addConstant(dest_type, try Value.Tag.error_union.create(sema.arena, val)); |
| 7622 | 7572 | } |
| 7623 | 7573 | |
| 7624 | 7574 | try sema.requireRuntimeBlock(block, inst.src); |