| ... | ... | @@ -876,104 +876,100 @@ pub fn deinit(sema: *Sema) void { |
| 876 | 876 | sema.* = undefined; |
| 877 | 877 | } |
| 878 | 878 | |
| 879 | | /// Returns only the result from the body that is specified. |
| 880 | | /// Only appropriate to call when it is determined at comptime that this body |
| 881 | | /// has no peers. |
| 882 | | fn resolveBody( |
| 883 | | sema: *Sema, |
| 884 | | block: *Block, |
| 885 | | body: []const Zir.Inst.Index, |
| 886 | | /// This is the instruction that a break instruction within `body` can |
| 887 | | /// use to return from the body. |
| 888 | | body_inst: Zir.Inst.Index, |
| 889 | | ) CompileError!Air.Inst.Ref { |
| 890 | | const break_data = (try sema.analyzeBodyBreak(block, body)) orelse |
| 891 | | return .unreachable_value; |
| 892 | | // For comptime control flow, we need to detect when `analyzeBody` reports |
| 893 | | // that we need to break from an outer block. In such case we |
| 894 | | // use Zig's error mechanism to send control flow up the stack until |
| 895 | | // we find the corresponding block to this break. |
| 896 | | if (block.is_comptime and break_data.block_inst != body_inst) { |
| 897 | | sema.comptime_break_inst = break_data.inst; |
| 898 | | return error.ComptimeBreak; |
| 899 | | } |
| 900 | | return try sema.resolveInst(break_data.operand); |
| 901 | | } |
| 902 | | |
| 879 | /// Performs semantic analysis of a ZIR body which is behind a runtime condition. If comptime |
| 880 | /// control flow happens here, Sema will convert it to runtime control flow by introducing post-hoc |
| 881 | /// blocks where necessary. |
| 903 | 882 | fn analyzeBodyRuntimeBreak(sema: *Sema, block: *Block, body: []const Zir.Inst.Index) !void { |
| 904 | | _ = sema.analyzeBodyInner(block, body) catch |err| switch (err) { |
| 883 | sema.analyzeBodyInner(block, body) catch |err| switch (err) { |
| 905 | 884 | error.ComptimeBreak => { |
| 906 | 885 | const zir_datas = sema.code.instructions.items(.data); |
| 907 | 886 | const break_data = zir_datas[@intFromEnum(sema.comptime_break_inst)].@"break"; |
| 908 | 887 | const extra = sema.code.extraData(Zir.Inst.Break, break_data.payload_index).data; |
| 909 | | try sema.addRuntimeBreak(block, .{ |
| 910 | | .block_inst = extra.block_inst, |
| 911 | | .operand = break_data.operand, |
| 912 | | .inst = sema.comptime_break_inst, |
| 913 | | }); |
| 888 | try sema.addRuntimeBreak(block, extra.block_inst, break_data.operand); |
| 914 | 889 | }, |
| 915 | 890 | else => |e| return e, |
| 916 | 891 | }; |
| 917 | 892 | } |
| 918 | 893 | |
| 919 | | pub fn analyzeBody( |
| 894 | /// Semantically analyze a ZIR function body. It is guranteed by AstGen that such a body cannot |
| 895 | /// trigger comptime control flow to move above the function body. |
| 896 | pub fn analyzeFnBody( |
| 920 | 897 | sema: *Sema, |
| 921 | 898 | block: *Block, |
| 922 | 899 | body: []const Zir.Inst.Index, |
| 923 | 900 | ) !void { |
| 924 | | _ = sema.analyzeBodyInner(block, body) catch |err| switch (err) { |
| 901 | sema.analyzeBodyInner(block, body) catch |err| switch (err) { |
| 925 | 902 | error.ComptimeBreak => unreachable, // unexpected comptime control flow |
| 926 | 903 | else => |e| return e, |
| 927 | 904 | }; |
| 928 | 905 | } |
| 929 | 906 | |
| 930 | | const BreakData = struct { |
| 931 | | block_inst: Zir.Inst.Index, |
| 932 | | operand: Zir.Inst.Ref, |
| 933 | | inst: Zir.Inst.Index, |
| 934 | | }; |
| 935 | | |
| 936 | | pub fn analyzeBodyBreak( |
| 907 | /// Given a ZIR body which can be exited via a `break_inline` instruction, or a non-inline body which |
| 908 | /// we are evaluating at comptime, semantically analyze the body and return the result from it. |
| 909 | /// Returns `null` if control flow did not break from this block, but instead terminated with some |
| 910 | /// other runtime noreturn instruction. Compile-time breaks to blocks further up the stack still |
| 911 | /// return `error.ComptimeBreak`. If `block.is_comptime`, this function will never return `null`. |
| 912 | fn analyzeInlineBody( |
| 937 | 913 | sema: *Sema, |
| 938 | 914 | block: *Block, |
| 939 | 915 | body: []const Zir.Inst.Index, |
| 940 | | ) CompileError!?BreakData { |
| 941 | | const break_inst = sema.analyzeBodyInner(block, body) catch |err| switch (err) { |
| 942 | | error.ComptimeBreak => sema.comptime_break_inst, |
| 943 | | else => |e| return e, |
| 944 | | }; |
| 945 | | if (block.instructions.items.len != 0 and |
| 946 | | sema.isNoReturn(block.instructions.items[block.instructions.items.len - 1].toRef())) |
| 916 | /// The index which a break instruction can target to break from this body. |
| 917 | break_target: Zir.Inst.Index, |
| 918 | ) CompileError!?Air.Inst.Ref { |
| 919 | if (sema.analyzeBodyInner(block, body)) |_| { |
| 947 | 920 | return null; |
| 921 | } else |err| switch (err) { |
| 922 | error.ComptimeBreak => {}, |
| 923 | else => |e| return e, |
| 924 | } |
| 925 | const break_inst = sema.comptime_break_inst; |
| 948 | 926 | const break_data = sema.code.instructions.items(.data)[@intFromEnum(break_inst)].@"break"; |
| 949 | 927 | const extra = sema.code.extraData(Zir.Inst.Break, break_data.payload_index).data; |
| 950 | | return BreakData{ |
| 951 | | .block_inst = extra.block_inst, |
| 952 | | .operand = break_data.operand, |
| 953 | | .inst = break_inst, |
| 954 | | }; |
| 955 | | } |
| 956 | | |
| 957 | | /// ZIR instructions which are always `noreturn` return this. This matches the |
| 958 | | /// return type of `analyzeBody` so that we can tail call them. |
| 959 | | /// Only appropriate to return when the instruction is known to be NoReturn |
| 960 | | /// solely based on the ZIR tag. |
| 961 | | const always_noreturn: CompileError!Zir.Inst.Index = @as(Zir.Inst.Index, undefined); |
| 962 | | |
| 963 | | /// This function is the main loop of `Sema` and it can be used in two different ways: |
| 964 | | /// * The traditional way where there are N breaks out of the block and peer type |
| 965 | | /// resolution is done on the break operands. In this case, the `Zir.Inst.Index` |
| 966 | | /// part of the return value will be `undefined`, and callsites should ignore it, |
| 967 | | /// finding the block result value via the block scope. |
| 968 | | /// * The "flat" way. There is only 1 break out of the block, and it is with a `break_inline` |
| 969 | | /// instruction. In this case, the `Zir.Inst.Index` part of the return value will be |
| 970 | | /// the break instruction. This communicates both which block the break applies to, as |
| 971 | | /// well as the operand. No block scope needs to be created for this strategy. |
| 928 | if (extra.block_inst != break_target) { |
| 929 | // This control flow goes further up the stack. |
| 930 | return error.ComptimeBreak; |
| 931 | } |
| 932 | return try sema.resolveInst(break_data.operand); |
| 933 | } |
| 934 | |
| 935 | /// Like `analyzeInlineBody`, but if the body does not break with a value, returns |
| 936 | /// `.unreachable_value` instead of `null`. Notably, use this to evaluate an arbitrary |
| 937 | /// body at comptime to a single result value. |
| 938 | pub fn resolveInlineBody( |
| 939 | sema: *Sema, |
| 940 | block: *Block, |
| 941 | body: []const Zir.Inst.Index, |
| 942 | /// The index which a break instruction can target to break from this body. |
| 943 | break_target: Zir.Inst.Index, |
| 944 | ) CompileError!Air.Inst.Ref { |
| 945 | return (try sema.analyzeInlineBody(block, body, break_target)) orelse .unreachable_value; |
| 946 | } |
| 947 | |
| 948 | /// This function is the main loop of `Sema`. It analyzes a single body of ZIR instructions. |
| 949 | /// |
| 950 | /// If this function returns normally, the merges of `block` were populated with all possible |
| 951 | /// (runtime) results of this block. Peer type resolution should be performed on the result, |
| 952 | /// and relevant runtime instructions written to perform necessary coercions and breaks. See |
| 953 | /// `resolveAnalyzedBlock`. This form of return is impossible if `block.is_comptime == true`. |
| 954 | /// |
| 955 | /// Alternatively, this function may return `error.ComptimeBreak`. This indicates that comptime |
| 956 | /// control flow is happening, and we are breaking at comptime from a block indicated by the |
| 957 | /// break instruction in `sema.comptime_break_inst`. This occurs for any `break_inline`, or for a |
| 958 | /// standard `break` at comptime. This error is pushed up the stack until the target block is |
| 959 | /// reached, at which point the break operand will be fetched. |
| 960 | /// |
| 961 | /// It is rare to call this function directly. Usually, you want one of the following wrappers: |
| 962 | /// * If the body is exited via a `break_inline`, or is being evaluated at comptime, |
| 963 | /// use `Sema.analyzeInlineBody` or `Sema.resolveInlineBody`. |
| 964 | /// * If the body is behind a fresh runtime condition, use `Sema.analyzeBodyRuntimeBreak`. |
| 965 | /// * If the body is an entire function body, use `Sema.analyzeFnBody`. |
| 966 | /// * If the body is to be generated into an AIR `block`, use `Sema.resolveBlockBody`. |
| 967 | /// * Otherwise, direct usage of `Sema.analyzeBodyInner` may be necessary. |
| 972 | 968 | fn analyzeBodyInner( |
| 973 | 969 | sema: *Sema, |
| 974 | 970 | block: *Block, |
| 975 | 971 | body: []const Zir.Inst.Index, |
| 976 | | ) CompileError!Zir.Inst.Index { |
| 972 | ) CompileError!void { |
| 977 | 973 | // No tracy calls here, to avoid interfering with the tail call mechanism. |
| 978 | 974 | |
| 979 | 975 | try sema.inst_map.ensureSpaceForInstructions(sema.gpa, body); |
| ... | ... | @@ -997,7 +993,7 @@ fn analyzeBodyInner( |
| 997 | 993 | // the loop. The only way to break out of the loop is with a `noreturn` |
| 998 | 994 | // instruction. |
| 999 | 995 | var i: u32 = 0; |
| 1000 | | const result = while (true) { |
| 996 | while (true) { |
| 1001 | 997 | crash_info.setBodyIndex(i); |
| 1002 | 998 | const inst = body[i]; |
| 1003 | 999 | std.log.scoped(.sema_zir).debug("sema ZIR {s} %{d}", .{ |
| ... | ... | @@ -1214,14 +1210,14 @@ fn analyzeBodyInner( |
| 1214 | 1210 | // Instructions that we know to *always* be noreturn based solely on their tag. |
| 1215 | 1211 | // These functions match the return type of analyzeBody so that we can |
| 1216 | 1212 | // tail call them here. |
| 1217 | | .compile_error => break sema.zirCompileError(block, inst), |
| 1218 | | .ret_implicit => break sema.zirRetImplicit(block, inst), |
| 1219 | | .ret_node => break sema.zirRetNode(block, inst), |
| 1220 | | .ret_load => break sema.zirRetLoad(block, inst), |
| 1221 | | .ret_err_value => break sema.zirRetErrValue(block, inst), |
| 1222 | | .@"unreachable" => break sema.zirUnreachable(block, inst), |
| 1223 | | .panic => break sema.zirPanic(block, inst), |
| 1224 | | .trap => break sema.zirTrap(block, inst), |
| 1213 | .compile_error => break try sema.zirCompileError(block, inst), |
| 1214 | .ret_implicit => break try sema.zirRetImplicit(block, inst), |
| 1215 | .ret_node => break try sema.zirRetNode(block, inst), |
| 1216 | .ret_load => break try sema.zirRetLoad(block, inst), |
| 1217 | .ret_err_value => break try sema.zirRetErrValue(block, inst), |
| 1218 | .@"unreachable" => break try sema.zirUnreachable(block, inst), |
| 1219 | .panic => break try sema.zirPanic(block, inst), |
| 1220 | .trap => break try sema.zirTrap(block, inst), |
| 1225 | 1221 | // zig fmt: on |
| 1226 | 1222 | |
| 1227 | 1223 | // This instruction never exists in an analyzed body. It exists only in the declaration |
| ... | ... | @@ -1247,7 +1243,7 @@ fn analyzeBodyInner( |
| 1247 | 1243 | .builtin_extern => try sema.zirBuiltinExtern( block, extended), |
| 1248 | 1244 | .@"asm" => try sema.zirAsm( block, extended, false), |
| 1249 | 1245 | .asm_expr => try sema.zirAsm( block, extended, true), |
| 1250 | | .typeof_peer => try sema.zirTypeofPeer( block, extended), |
| 1246 | .typeof_peer => try sema.zirTypeofPeer( block, extended, inst), |
| 1251 | 1247 | .compile_log => try sema.zirCompileLog( extended), |
| 1252 | 1248 | .min_multi => try sema.zirMinMaxMulti( block, extended, .min), |
| 1253 | 1249 | .max_multi => try sema.zirMinMaxMulti( block, extended, .max), |
| ... | ... | @@ -1522,18 +1518,16 @@ fn analyzeBodyInner( |
| 1522 | 1518 | // Special case instructions to handle comptime control flow. |
| 1523 | 1519 | .@"break" => { |
| 1524 | 1520 | if (block.is_comptime) { |
| 1525 | | break inst; // same as break_inline |
| 1521 | sema.comptime_break_inst = inst; |
| 1522 | return error.ComptimeBreak; |
| 1526 | 1523 | } else { |
| 1527 | | break sema.zirBreak(block, inst); |
| 1524 | try sema.zirBreak(block, inst); |
| 1525 | break; |
| 1528 | 1526 | } |
| 1529 | 1527 | }, |
| 1530 | 1528 | .break_inline => { |
| 1531 | | if (block.is_comptime) { |
| 1532 | | break inst; |
| 1533 | | } else { |
| 1534 | | sema.comptime_break_inst = inst; |
| 1535 | | return error.ComptimeBreak; |
| 1536 | | } |
| 1529 | sema.comptime_break_inst = inst; |
| 1530 | return error.ComptimeBreak; |
| 1537 | 1531 | }, |
| 1538 | 1532 | .repeat => { |
| 1539 | 1533 | if (block.is_comptime) { |
| ... | ... | @@ -1548,7 +1542,10 @@ fn analyzeBodyInner( |
| 1548 | 1542 | i = 0; |
| 1549 | 1543 | continue; |
| 1550 | 1544 | } else { |
| 1551 | | break always_noreturn; |
| 1545 | // We are definitely called by `zirLoop`, which will treat the |
| 1546 | // fact that this body does not terminate `noreturn` as an |
| 1547 | // implicit repeat. |
| 1548 | break; |
| 1552 | 1549 | } |
| 1553 | 1550 | }, |
| 1554 | 1551 | .repeat_inline => { |
| ... | ... | @@ -1584,13 +1581,8 @@ fn analyzeBodyInner( |
| 1584 | 1581 | child_block.instructions = block.instructions; |
| 1585 | 1582 | defer block.instructions = child_block.instructions; |
| 1586 | 1583 | |
| 1587 | | const break_data = (try sema.analyzeBodyBreak(&child_block, inline_body)) orelse |
| 1588 | | break always_noreturn; |
| 1589 | | if (inst == break_data.block_inst) { |
| 1590 | | break :blk try sema.resolveInst(break_data.operand); |
| 1591 | | } else { |
| 1592 | | break break_data.inst; |
| 1593 | | } |
| 1584 | const result = try sema.analyzeInlineBody(&child_block, inline_body, inst) orelse break; |
| 1585 | break :blk result; |
| 1594 | 1586 | }, |
| 1595 | 1587 | .block, .block_comptime => blk: { |
| 1596 | 1588 | if (!block.is_comptime) { |
| ... | ... | @@ -1615,13 +1607,8 @@ fn analyzeBodyInner( |
| 1615 | 1607 | child_block.instructions = block.instructions; |
| 1616 | 1608 | defer block.instructions = child_block.instructions; |
| 1617 | 1609 | |
| 1618 | | const break_data = (try sema.analyzeBodyBreak(&child_block, inline_body)) orelse |
| 1619 | | break always_noreturn; |
| 1620 | | if (inst == break_data.block_inst) { |
| 1621 | | break :blk try sema.resolveInst(break_data.operand); |
| 1622 | | } else { |
| 1623 | | break break_data.inst; |
| 1624 | | } |
| 1610 | const result = try sema.analyzeInlineBody(&child_block, inline_body, inst) orelse break; |
| 1611 | break :blk result; |
| 1625 | 1612 | }, |
| 1626 | 1613 | .block_inline => blk: { |
| 1627 | 1614 | // Directly analyze the block body without introducing a new block. |
| ... | ... | @@ -1634,7 +1621,12 @@ fn analyzeBodyInner( |
| 1634 | 1621 | const inline_body = sema.code.bodySlice(extra.end, extra.data.body_len); |
| 1635 | 1622 | const gpa = sema.gpa; |
| 1636 | 1623 | |
| 1637 | | const opt_break_data, const need_debug_scope = b: { |
| 1624 | const BreakResult = struct { |
| 1625 | block_inst: Zir.Inst.Index, |
| 1626 | operand: Zir.Inst.Ref, |
| 1627 | }; |
| 1628 | |
| 1629 | const opt_break_data: ?BreakResult, const need_debug_scope = b: { |
| 1638 | 1630 | // Create a temporary child block so that this inline block is properly |
| 1639 | 1631 | // labeled for any .restore_err_ret_index instructions |
| 1640 | 1632 | var child_block = block.makeSubBlock(); |
| ... | ... | @@ -1660,11 +1652,26 @@ fn analyzeBodyInner( |
| 1660 | 1652 | child_block.instructions = block.instructions; |
| 1661 | 1653 | defer block.instructions = child_block.instructions; |
| 1662 | 1654 | |
| 1663 | | const result = try sema.analyzeBodyBreak(&child_block, inline_body); |
| 1655 | const break_result: ?BreakResult = if (sema.analyzeBodyInner(&child_block, inline_body)) |_| r: { |
| 1656 | break :r null; |
| 1657 | } else |err| switch (err) { |
| 1658 | error.ComptimeBreak => brk_res: { |
| 1659 | const break_inst = sema.comptime_break_inst; |
| 1660 | const break_data = sema.code.instructions.items(.data)[@intFromEnum(break_inst)].@"break"; |
| 1661 | const break_extra = sema.code.extraData(Zir.Inst.Break, break_data.payload_index).data; |
| 1662 | break :brk_res .{ |
| 1663 | .block_inst = break_extra.block_inst, |
| 1664 | .operand = break_data.operand, |
| 1665 | }; |
| 1666 | }, |
| 1667 | else => |e| return e, |
| 1668 | }; |
| 1669 | |
| 1664 | 1670 | if (need_debug_scope) { |
| 1665 | 1671 | _ = try sema.ensurePostHoc(block, inst); |
| 1666 | 1672 | } |
| 1667 | | break :b .{ result, need_debug_scope }; |
| 1673 | |
| 1674 | break :b .{ break_result, need_debug_scope }; |
| 1668 | 1675 | }; |
| 1669 | 1676 | |
| 1670 | 1677 | // A runtime conditional branch that needs a post-hoc block to be |
| ... | ... | @@ -1686,13 +1693,13 @@ fn analyzeBodyInner( |
| 1686 | 1693 | // It may pass through our currently being analyzed block_inline or it |
| 1687 | 1694 | // may point directly to it. In the latter case, this modifies the |
| 1688 | 1695 | // block that we looked up in the post_hoc_blocks map above. |
| 1689 | | try sema.addRuntimeBreak(block, break_data); |
| 1696 | try sema.addRuntimeBreak(block, break_data.block_inst, break_data.operand); |
| 1690 | 1697 | } |
| 1691 | 1698 | |
| 1692 | 1699 | try labeled_block.block.instructions.appendSlice(gpa, block.instructions.items[block_index..]); |
| 1693 | 1700 | block.instructions.items.len = block_index; |
| 1694 | 1701 | |
| 1695 | | const block_result = try sema.analyzeBlockBody(block, inst_data.src(), &labeled_block.block, &labeled_block.label.merges, need_debug_scope); |
| 1702 | const block_result = try sema.resolveAnalyzedBlock(block, inst_data.src(), &labeled_block.block, &labeled_block.label.merges, need_debug_scope); |
| 1696 | 1703 | { |
| 1697 | 1704 | // Destroy the ad-hoc block entry so that it does not interfere with |
| 1698 | 1705 | // the next iteration of comptime control flow, if any. |
| ... | ... | @@ -1703,15 +1710,19 @@ fn analyzeBodyInner( |
| 1703 | 1710 | break :blk block_result; |
| 1704 | 1711 | } |
| 1705 | 1712 | |
| 1706 | | const break_data = opt_break_data orelse break always_noreturn; |
| 1713 | const break_data = opt_break_data orelse break; |
| 1707 | 1714 | if (inst == break_data.block_inst) { |
| 1708 | 1715 | break :blk try sema.resolveInst(break_data.operand); |
| 1709 | 1716 | } else { |
| 1710 | | break break_data.inst; |
| 1717 | // `comptime_break_inst` preserved from `analyzeBodyInner` above. |
| 1718 | return error.ComptimeBreak; |
| 1711 | 1719 | } |
| 1712 | 1720 | }, |
| 1713 | 1721 | .condbr => blk: { |
| 1714 | | if (!block.is_comptime) break sema.zirCondbr(block, inst); |
| 1722 | if (!block.is_comptime) { |
| 1723 | try sema.zirCondbr(block, inst); |
| 1724 | break; |
| 1725 | } |
| 1715 | 1726 | // Same as condbr_inline. TODO https://github.com/ziglang/zig/issues/8220 |
| 1716 | 1727 | const inst_data = datas[@intFromEnum(inst)].pl_node; |
| 1717 | 1728 | const cond_src: LazySrcLoc = .{ .node_offset_if_cond = inst_data.src_node }; |
| ... | ... | @@ -1728,13 +1739,9 @@ fn analyzeBodyInner( |
| 1728 | 1739 | const inline_body = if (cond.val.toBool()) then_body else else_body; |
| 1729 | 1740 | |
| 1730 | 1741 | try sema.maybeErrorUnwrapCondbr(block, inline_body, extra.data.condition, cond_src); |
| 1731 | | const break_data = (try sema.analyzeBodyBreak(block, inline_body)) orelse |
| 1732 | | break always_noreturn; |
| 1733 | | if (inst == break_data.block_inst) { |
| 1734 | | break :blk try sema.resolveInst(break_data.operand); |
| 1735 | | } else { |
| 1736 | | break break_data.inst; |
| 1737 | | } |
| 1742 | |
| 1743 | const result = try sema.analyzeInlineBody(block, inline_body, inst) orelse break; |
| 1744 | break :blk result; |
| 1738 | 1745 | }, |
| 1739 | 1746 | .condbr_inline => blk: { |
| 1740 | 1747 | const inst_data = datas[@intFromEnum(inst)].pl_node; |
| ... | ... | @@ -1754,13 +1761,9 @@ fn analyzeBodyInner( |
| 1754 | 1761 | try sema.maybeErrorUnwrapCondbr(block, inline_body, extra.data.condition, cond_src); |
| 1755 | 1762 | const old_runtime_index = block.runtime_index; |
| 1756 | 1763 | defer block.runtime_index = old_runtime_index; |
| 1757 | | const break_data = (try sema.analyzeBodyBreak(block, inline_body)) orelse |
| 1758 | | break always_noreturn; |
| 1759 | | if (inst == break_data.block_inst) { |
| 1760 | | break :blk try sema.resolveInst(break_data.operand); |
| 1761 | | } else { |
| 1762 | | break break_data.inst; |
| 1763 | | } |
| 1764 | |
| 1765 | const result = try sema.analyzeInlineBody(block, inline_body, inst) orelse break; |
| 1766 | break :blk result; |
| 1764 | 1767 | }, |
| 1765 | 1768 | .@"try" => blk: { |
| 1766 | 1769 | if (!block.is_comptime) break :blk try sema.zirTry(block, inst); |
| ... | ... | @@ -1785,13 +1788,8 @@ fn analyzeBodyInner( |
| 1785 | 1788 | if (is_non_err_val.toBool()) { |
| 1786 | 1789 | break :blk try sema.analyzeErrUnionPayload(block, src, err_union_ty, err_union, operand_src, false); |
| 1787 | 1790 | } |
| 1788 | | const break_data = (try sema.analyzeBodyBreak(block, inline_body)) orelse |
| 1789 | | break always_noreturn; |
| 1790 | | if (inst == break_data.block_inst) { |
| 1791 | | break :blk try sema.resolveInst(break_data.operand); |
| 1792 | | } else { |
| 1793 | | break break_data.inst; |
| 1794 | | } |
| 1791 | const result = try sema.analyzeInlineBody(block, inline_body, inst) orelse break; |
| 1792 | break :blk result; |
| 1795 | 1793 | }, |
| 1796 | 1794 | .try_ptr => blk: { |
| 1797 | 1795 | if (!block.is_comptime) break :blk try sema.zirTryPtr(block, inst); |
| ... | ... | @@ -1811,22 +1809,22 @@ fn analyzeBodyInner( |
| 1811 | 1809 | if (is_non_err_val.toBool()) { |
| 1812 | 1810 | break :blk try sema.analyzeErrUnionPayloadPtr(block, src, operand, false, false); |
| 1813 | 1811 | } |
| 1814 | | const break_data = (try sema.analyzeBodyBreak(block, inline_body)) orelse |
| 1815 | | break always_noreturn; |
| 1816 | | if (inst == break_data.block_inst) { |
| 1817 | | break :blk try sema.resolveInst(break_data.operand); |
| 1818 | | } else { |
| 1819 | | break break_data.inst; |
| 1820 | | } |
| 1812 | const result = try sema.analyzeInlineBody(block, inline_body, inst) orelse break; |
| 1813 | break :blk result; |
| 1821 | 1814 | }, |
| 1822 | 1815 | .@"defer" => blk: { |
| 1823 | 1816 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].@"defer"; |
| 1824 | 1817 | const defer_body = sema.code.bodySlice(inst_data.index, inst_data.len); |
| 1825 | | const break_inst = sema.analyzeBodyInner(block, defer_body) catch |err| switch (err) { |
| 1826 | | error.ComptimeBreak => sema.comptime_break_inst, |
| 1818 | if (sema.analyzeBodyInner(block, defer_body)) |_| { |
| 1819 | // The defer terminated noreturn - no more analysis needed. |
| 1820 | break; |
| 1821 | } else |err| switch (err) { |
| 1822 | error.ComptimeBreak => {}, |
| 1827 | 1823 | else => |e| return e, |
| 1828 | | }; |
| 1829 | | if (break_inst != defer_body[defer_body.len - 1]) break always_noreturn; |
| 1824 | } |
| 1825 | if (sema.comptime_break_inst != defer_body[defer_body.len - 1]) { |
| 1826 | return error.ComptimeBreak; |
| 1827 | } |
| 1830 | 1828 | break :blk .void_value; |
| 1831 | 1829 | }, |
| 1832 | 1830 | .defer_err_code => blk: { |
| ... | ... | @@ -1835,11 +1833,16 @@ fn analyzeBodyInner( |
| 1835 | 1833 | const defer_body = sema.code.bodySlice(extra.index, extra.len); |
| 1836 | 1834 | const err_code = try sema.resolveInst(inst_data.err_code); |
| 1837 | 1835 | map.putAssumeCapacity(extra.remapped_err_code, err_code); |
| 1838 | | const break_inst = sema.analyzeBodyInner(block, defer_body) catch |err| switch (err) { |
| 1839 | | error.ComptimeBreak => sema.comptime_break_inst, |
| 1836 | if (sema.analyzeBodyInner(block, defer_body)) |_| { |
| 1837 | // The defer terminated noreturn - no more analysis needed. |
| 1838 | break; |
| 1839 | } else |err| switch (err) { |
| 1840 | error.ComptimeBreak => {}, |
| 1840 | 1841 | else => |e| return e, |
| 1841 | | }; |
| 1842 | | if (break_inst != defer_body[defer_body.len - 1]) break always_noreturn; |
| 1842 | } |
| 1843 | if (sema.comptime_break_inst != defer_body[defer_body.len - 1]) { |
| 1844 | return error.ComptimeBreak; |
| 1845 | } |
| 1843 | 1846 | break :blk .void_value; |
| 1844 | 1847 | }, |
| 1845 | 1848 | }; |
| ... | ... | @@ -1847,17 +1850,15 @@ fn analyzeBodyInner( |
| 1847 | 1850 | // We're going to assume that the body itself is noreturn, so let's ensure that now |
| 1848 | 1851 | assert(block.instructions.items.len > 0); |
| 1849 | 1852 | assert(sema.isNoReturn(block.instructions.items[block.instructions.items.len - 1].toRef())); |
| 1850 | | break always_noreturn; |
| 1853 | break; |
| 1851 | 1854 | } |
| 1852 | 1855 | map.putAssumeCapacity(inst, air_inst); |
| 1853 | 1856 | i += 1; |
| 1854 | | }; |
| 1857 | } |
| 1855 | 1858 | |
| 1856 | 1859 | // We may have overwritten the capture scope due to a `repeat` instruction where |
| 1857 | 1860 | // the body had a capture; restore it now. |
| 1858 | 1861 | block.wip_capture_scope = parent_capture_scope; |
| 1859 | | |
| 1860 | | return result; |
| 1861 | 1862 | } |
| 1862 | 1863 | |
| 1863 | 1864 | pub fn resolveInstAllowNone(sema: *Sema, zir_ref: Zir.Inst.Ref) !Air.Inst.Ref { |
| ... | ... | @@ -1894,7 +1895,7 @@ fn resolveConstBool( |
| 1894 | 1895 | return val.toBool(); |
| 1895 | 1896 | } |
| 1896 | 1897 | |
| 1897 | | pub fn resolveConstString( |
| 1898 | fn resolveConstString( |
| 1898 | 1899 | sema: *Sema, |
| 1899 | 1900 | block: *Block, |
| 1900 | 1901 | src: LazySrcLoc, |
| ... | ... | @@ -1902,6 +1903,16 @@ pub fn resolveConstString( |
| 1902 | 1903 | reason: NeededComptimeReason, |
| 1903 | 1904 | ) ![]u8 { |
| 1904 | 1905 | const air_inst = try sema.resolveInst(zir_ref); |
| 1906 | return sema.toConstString(block, src, air_inst, reason); |
| 1907 | } |
| 1908 | |
| 1909 | pub fn toConstString( |
| 1910 | sema: *Sema, |
| 1911 | block: *Block, |
| 1912 | src: LazySrcLoc, |
| 1913 | air_inst: Air.Inst.Ref, |
| 1914 | reason: NeededComptimeReason, |
| 1915 | ) ![]u8 { |
| 1905 | 1916 | const wanted_type = Type.slice_const_u8; |
| 1906 | 1917 | const coerced_inst = try sema.coerce(block, wanted_type, air_inst, src); |
| 1907 | 1918 | const val = try sema.resolveConstDefinedValue(block, src, coerced_inst, reason); |
| ... | ... | @@ -2193,9 +2204,8 @@ fn resolveValueAllowVariables(sema: *Sema, inst: Air.Inst.Ref) CompileError!?Val |
| 2193 | 2204 | return val; |
| 2194 | 2205 | } |
| 2195 | 2206 | |
| 2196 | | /// Returns a compile error if the value has tag `variable`. See `resolveInstValue` for |
| 2197 | | /// a function that does not. |
| 2198 | | pub fn resolveInstConst( |
| 2207 | /// Returns a compile error if the value has tag `variable`. |
| 2208 | fn resolveInstConst( |
| 2199 | 2209 | sema: *Sema, |
| 2200 | 2210 | block: *Block, |
| 2201 | 2211 | src: LazySrcLoc, |
| ... | ... | @@ -2211,15 +2221,13 @@ pub fn resolveInstConst( |
| 2211 | 2221 | } |
| 2212 | 2222 | |
| 2213 | 2223 | /// Value Tag may be `undef` or `variable`. |
| 2214 | | /// See `resolveInstConst` for an alternative. |
| 2215 | | pub fn resolveInstValueAllowVariables( |
| 2224 | pub fn resolveConstValueAllowVariables( |
| 2216 | 2225 | sema: *Sema, |
| 2217 | 2226 | block: *Block, |
| 2218 | 2227 | src: LazySrcLoc, |
| 2219 | | zir_ref: Zir.Inst.Ref, |
| 2228 | air_ref: Air.Inst.Ref, |
| 2220 | 2229 | reason: NeededComptimeReason, |
| 2221 | 2230 | ) CompileError!TypedValue { |
| 2222 | | const air_ref = try sema.resolveInst(zir_ref); |
| 2223 | 2231 | const val = try sema.resolveValueAllowVariables(air_ref) orelse { |
| 2224 | 2232 | return sema.failWithNeededComptime(block, src, reason); |
| 2225 | 2233 | }; |
| ... | ... | @@ -2616,7 +2624,7 @@ fn reparentOwnedErrorMsg( |
| 2616 | 2624 | |
| 2617 | 2625 | const align_ty = Type.u29; |
| 2618 | 2626 | |
| 2619 | | fn analyzeAsAlign( |
| 2627 | pub fn analyzeAsAlign( |
| 2620 | 2628 | sema: *Sema, |
| 2621 | 2629 | block: *Block, |
| 2622 | 2630 | src: LazySrcLoc, |
| ... | ... | @@ -2654,7 +2662,7 @@ fn validateAlignAllowZero( |
| 2654 | 2662 | return Alignment.fromNonzeroByteUnits(alignment); |
| 2655 | 2663 | } |
| 2656 | 2664 | |
| 2657 | | pub fn resolveAlign( |
| 2665 | fn resolveAlign( |
| 2658 | 2666 | sema: *Sema, |
| 2659 | 2667 | block: *Block, |
| 2660 | 2668 | src: LazySrcLoc, |
| ... | ... | @@ -3054,7 +3062,7 @@ fn zirEnumDecl( |
| 3054 | 3062 | defer enum_block.instructions.deinit(sema.gpa); |
| 3055 | 3063 | |
| 3056 | 3064 | if (body.len != 0) { |
| 3057 | | try sema.analyzeBody(&enum_block, body); |
| 3065 | _ = try sema.analyzeInlineBody(&enum_block, body, inst); |
| 3058 | 3066 | } |
| 3059 | 3067 | |
| 3060 | 3068 | if (tag_type_ref != .none) { |
| ... | ... | @@ -5597,7 +5605,7 @@ fn zirFloat128(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 5597 | 5605 | return Air.internedToRef((try sema.mod.floatValue(Type.comptime_float, number)).toIntern()); |
| 5598 | 5606 | } |
| 5599 | 5607 | |
| 5600 | | fn zirCompileError(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Zir.Inst.Index { |
| 5608 | fn zirCompileError(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void { |
| 5601 | 5609 | const tracy = trace(@src()); |
| 5602 | 5610 | defer tracy.end(); |
| 5603 | 5611 | |
| ... | ... | @@ -5650,7 +5658,7 @@ fn zirCompileLog( |
| 5650 | 5658 | return .void_value; |
| 5651 | 5659 | } |
| 5652 | 5660 | |
| 5653 | | fn zirPanic(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Zir.Inst.Index { |
| 5661 | fn zirPanic(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void { |
| 5654 | 5662 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; |
| 5655 | 5663 | const src = inst_data.src(); |
| 5656 | 5664 | const msg_inst = try sema.resolveInst(inst_data.operand); |
| ... | ... | @@ -5663,16 +5671,14 @@ fn zirPanic(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Zir.I |
| 5663 | 5671 | return sema.fail(block, src, "encountered @panic at comptime", .{}); |
| 5664 | 5672 | } |
| 5665 | 5673 | try sema.panicWithMsg(block, src, coerced_msg, .@"@panic"); |
| 5666 | | return always_noreturn; |
| 5667 | 5674 | } |
| 5668 | 5675 | |
| 5669 | | fn zirTrap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Zir.Inst.Index { |
| 5676 | fn zirTrap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void { |
| 5670 | 5677 | const src_node = sema.code.instructions.items(.data)[@intFromEnum(inst)].node; |
| 5671 | 5678 | const src = LazySrcLoc.nodeOffset(src_node); |
| 5672 | 5679 | if (block.is_comptime) |
| 5673 | 5680 | return sema.fail(block, src, "encountered @trap at comptime", .{}); |
| 5674 | 5681 | _ = try block.addNoOp(.trap); |
| 5675 | | return always_noreturn; |
| 5676 | 5682 | } |
| 5677 | 5683 | |
| 5678 | 5684 | fn zirLoop(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| ... | ... | @@ -5726,7 +5732,8 @@ fn zirLoop(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError |
| 5726 | 5732 | var loop_block = child_block.makeSubBlock(); |
| 5727 | 5733 | defer loop_block.instructions.deinit(gpa); |
| 5728 | 5734 | |
| 5729 | | try sema.analyzeBody(&loop_block, body); |
| 5735 | // Use `analyzeBodyInner` directly to push any comptime control flow up the stack. |
| 5736 | try sema.analyzeBodyInner(&loop_block, body); |
| 5730 | 5737 | |
| 5731 | 5738 | const loop_block_len = loop_block.instructions.items.len; |
| 5732 | 5739 | if (loop_block_len > 0 and sema.typeOf(loop_block.instructions.items[loop_block_len - 1].toRef()).isNoReturn(mod)) { |
| ... | ... | @@ -5742,7 +5749,7 @@ fn zirLoop(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError |
| 5742 | 5749 | ); |
| 5743 | 5750 | sema.air_extra.appendSliceAssumeCapacity(@ptrCast(loop_block.instructions.items)); |
| 5744 | 5751 | } |
| 5745 | | return sema.analyzeBlockBody(parent_block, src, &child_block, merges, false); |
| 5752 | return sema.resolveAnalyzedBlock(parent_block, src, &child_block, merges, false); |
| 5746 | 5753 | } |
| 5747 | 5754 | |
| 5748 | 5755 | fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| ... | ... | @@ -5785,8 +5792,7 @@ fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileEr |
| 5785 | 5792 | }; |
| 5786 | 5793 | defer child_block.instructions.deinit(gpa); |
| 5787 | 5794 | |
| 5788 | | // Ignore the result, all the relevant operations have written to c_import_buf already. |
| 5789 | | _ = try sema.analyzeBodyBreak(&child_block, body); |
| 5795 | _ = try sema.analyzeInlineBody(&child_block, body, inst); |
| 5790 | 5796 | |
| 5791 | 5797 | var c_import_res = comp.cImport(c_import_buf.items, parent_block.ownerModule()) catch |err| |
| 5792 | 5798 | return sema.fail(&child_block, src, "C import failed: {s}", .{@errorName(err)}); |
| ... | ... | @@ -5916,6 +5922,9 @@ fn zirBlock(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index, force_compt |
| 5916 | 5922 | return sema.resolveBlockBody(parent_block, src, &child_block, body, inst, &label.merges); |
| 5917 | 5923 | } |
| 5918 | 5924 | |
| 5925 | /// Semantically analyze the given ZIR body, emitting any resulting runtime code into the AIR block |
| 5926 | /// specified by `child_block` if necessary (and emitting this block into `parent_block`). |
| 5927 | /// TODO: `merges` is known from `child_block`, remove this parameter. |
| 5919 | 5928 | fn resolveBlockBody( |
| 5920 | 5929 | sema: *Sema, |
| 5921 | 5930 | parent_block: *Block, |
| ... | ... | @@ -5928,12 +5937,12 @@ fn resolveBlockBody( |
| 5928 | 5937 | merges: *Block.Merges, |
| 5929 | 5938 | ) CompileError!Air.Inst.Ref { |
| 5930 | 5939 | if (child_block.is_comptime) { |
| 5931 | | return sema.resolveBody(child_block, body, body_inst); |
| 5940 | return sema.resolveInlineBody(child_block, body, body_inst); |
| 5932 | 5941 | } else { |
| 5933 | 5942 | var need_debug_scope = false; |
| 5934 | 5943 | child_block.need_debug_scope = &need_debug_scope; |
| 5935 | 5944 | if (sema.analyzeBodyInner(child_block, body)) |_| { |
| 5936 | | return sema.analyzeBlockBody(parent_block, src, child_block, merges, need_debug_scope); |
| 5945 | return sema.resolveAnalyzedBlock(parent_block, src, child_block, merges, need_debug_scope); |
| 5937 | 5946 | } else |err| switch (err) { |
| 5938 | 5947 | error.ComptimeBreak => { |
| 5939 | 5948 | // Comptime control flow is happening, however child_block may still contain |
| ... | ... | @@ -5970,7 +5979,12 @@ fn resolveBlockBody( |
| 5970 | 5979 | } |
| 5971 | 5980 | } |
| 5972 | 5981 | |
| 5973 | | fn analyzeBlockBody( |
| 5982 | /// After a body corresponding to an AIR `block` has been analyzed, this function places them into |
| 5983 | /// the block pointed at by `merges.block_inst` if necessary, or the block may be elided in favor of |
| 5984 | /// inlining the instructions directly into the parent block. Either way, it considers all merges of |
| 5985 | /// this block, and combines them appropriately using peer type resolution, returning the final |
| 5986 | /// value of the block. |
| 5987 | fn resolveAnalyzedBlock( |
| 5974 | 5988 | sema: *Sema, |
| 5975 | 5989 | parent_block: *Block, |
| 5976 | 5990 | src: LazySrcLoc, |
| ... | ... | @@ -6360,7 +6374,7 @@ fn zirFence(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) Co |
| 6360 | 6374 | }); |
| 6361 | 6375 | } |
| 6362 | 6376 | |
| 6363 | | fn zirBreak(sema: *Sema, start_block: *Block, inst: Zir.Inst.Index) CompileError!Zir.Inst.Index { |
| 6377 | fn zirBreak(sema: *Sema, start_block: *Block, inst: Zir.Inst.Index) CompileError!void { |
| 6364 | 6378 | const tracy = trace(@src()); |
| 6365 | 6379 | defer tracy.end(); |
| 6366 | 6380 | |
| ... | ... | @@ -6386,7 +6400,7 @@ fn zirBreak(sema: *Sema, start_block: *Block, inst: Zir.Inst.Index) CompileError |
| 6386 | 6400 | block.runtime_cond = start_block.runtime_cond orelse start_block.runtime_loop; |
| 6387 | 6401 | block.runtime_loop = start_block.runtime_loop; |
| 6388 | 6402 | } |
| 6389 | | return inst; |
| 6403 | return; |
| 6390 | 6404 | } |
| 6391 | 6405 | } |
| 6392 | 6406 | block = block.parent.?; |
| ... | ... | @@ -7096,7 +7110,7 @@ const CallArgsInfo = union(enum) { |
| 7096 | 7110 | // Give the arg its result type |
| 7097 | 7111 | sema.inst_map.putAssumeCapacity(zir_call.call_inst, Air.internedToRef(param_ty.toIntern())); |
| 7098 | 7112 | // Resolve the arg! |
| 7099 | | const uncoerced_arg = try sema.resolveBody(block, arg_body, zir_call.call_inst); |
| 7113 | const uncoerced_arg = try sema.resolveInlineBody(block, arg_body, zir_call.call_inst); |
| 7100 | 7114 | |
| 7101 | 7115 | if (sema.typeOf(uncoerced_arg).zigTypeTag(mod) == .NoReturn) { |
| 7102 | 7116 | // This terminates resolution of arguments. The caller should |
| ... | ... | @@ -7539,7 +7553,7 @@ fn analyzeCall( |
| 7539 | 7553 | // each of the parameters, resolving the return type and providing it to the child |
| 7540 | 7554 | // `Sema` so that it can be used for the `ret_ptr` instruction. |
| 7541 | 7555 | const ret_ty_inst = if (fn_info.ret_ty_body.len != 0) |
| 7542 | | try sema.resolveBody(&child_block, fn_info.ret_ty_body, module_fn.zir_body_inst.resolve(ip)) |
| 7556 | try sema.resolveInlineBody(&child_block, fn_info.ret_ty_body, module_fn.zir_body_inst.resolve(ip)) |
| 7543 | 7557 | else |
| 7544 | 7558 | try sema.resolveInst(fn_info.ret_ty_ref); |
| 7545 | 7559 | const ret_ty_src: LazySrcLoc = .{ .node_offset_fn_type_ret_ty = 0 }; |
| ... | ... | @@ -7608,11 +7622,11 @@ fn analyzeCall( |
| 7608 | 7622 | } |
| 7609 | 7623 | |
| 7610 | 7624 | const result = result: { |
| 7611 | | sema.analyzeBody(&child_block, fn_info.body) catch |err| switch (err) { |
| 7625 | sema.analyzeFnBody(&child_block, fn_info.body) catch |err| switch (err) { |
| 7612 | 7626 | error.ComptimeReturn => break :result inlining.comptime_result, |
| 7613 | 7627 | else => |e| return e, |
| 7614 | 7628 | }; |
| 7615 | | break :result try sema.analyzeBlockBody(block, call_src, &child_block, merges, false); |
| 7629 | break :result try sema.resolveAnalyzedBlock(block, call_src, &child_block, merges, false); |
| 7616 | 7630 | }; |
| 7617 | 7631 | |
| 7618 | 7632 | if (!is_comptime_call and !block.is_typeof and |
| ... | ... | @@ -7791,7 +7805,7 @@ fn analyzeInlineCallArg( |
| 7791 | 7805 | const param_ty = param_ty: { |
| 7792 | 7806 | const raw_param_ty = func_ty_info.param_types.get(ip)[arg_i.*]; |
| 7793 | 7807 | if (raw_param_ty != .generic_poison_type) break :param_ty raw_param_ty; |
| 7794 | | const param_ty_inst = try ics.callee().resolveBody(param_block, param_body, inst); |
| 7808 | const param_ty_inst = try ics.callee().resolveInlineBody(param_block, param_body, inst); |
| 7795 | 7809 | const param_ty = try ics.callee().analyzeAsType(param_block, param_src, param_ty_inst); |
| 7796 | 7810 | break :param_ty param_ty.toIntern(); |
| 7797 | 7811 | }; |
| ... | ... | @@ -8026,7 +8040,7 @@ fn instantiateGenericCall( |
| 8026 | 8040 | child_sema.generic_call_decl = prev_generic_call_decl; |
| 8027 | 8041 | } |
| 8028 | 8042 | |
| 8029 | | const param_ty_inst = try child_sema.resolveBody(&child_block, param_ty_body, param_inst); |
| 8043 | const param_ty_inst = try child_sema.resolveInlineBody(&child_block, param_ty_body, param_inst); |
| 8030 | 8044 | break :param_ty try child_sema.analyzeAsType(&child_block, param_data.src(), param_ty_inst); |
| 8031 | 8045 | }, |
| 8032 | 8046 | else => unreachable, |
| ... | ... | @@ -8118,7 +8132,7 @@ fn instantiateGenericCall( |
| 8118 | 8132 | |
| 8119 | 8133 | // We've already handled parameters, so don't resolve the whole body. Instead, just |
| 8120 | 8134 | // do the instructions after the params (i.e. the func itself). |
| 8121 | | const new_func_inst = try child_sema.resolveBody(&child_block, fn_info.param_body[args_info.count()..], fn_info.param_body_inst); |
| 8135 | const new_func_inst = try child_sema.resolveInlineBody(&child_block, fn_info.param_body[args_info.count()..], fn_info.param_body_inst); |
| 8122 | 8136 | const callee_index = (child_sema.resolveConstDefinedValue(&child_block, .unneeded, new_func_inst, undefined) catch unreachable).toIntern(); |
| 8123 | 8137 | |
| 8124 | 8138 | const callee = mod.funcInfo(callee_index); |
| ... | ... | @@ -9176,7 +9190,7 @@ fn resolveGenericBody( |
| 9176 | 9190 | sema.generic_call_decl = prev_generic_call_decl; |
| 9177 | 9191 | } |
| 9178 | 9192 | |
| 9179 | | const uncasted = sema.resolveBody(block, body, func_inst) catch |err| break :err err; |
| 9193 | const uncasted = sema.resolveInlineBody(block, body, func_inst) catch |err| break :err err; |
| 9180 | 9194 | const result = sema.coerce(block, dest_ty, uncasted, src) catch |err| break :err err; |
| 9181 | 9195 | const val = sema.resolveConstDefinedValue(block, src, result, reason) catch |err| break :err err; |
| 9182 | 9196 | return val; |
| ... | ... | @@ -9810,7 +9824,7 @@ fn zirParam( |
| 9810 | 9824 | sema.generic_call_decl = prev_generic_call_decl; |
| 9811 | 9825 | } |
| 9812 | 9826 | |
| 9813 | | if (sema.resolveBody(block, body, inst)) |param_ty_inst| { |
| 9827 | if (sema.resolveInlineBody(block, body, inst)) |param_ty_inst| { |
| 9814 | 9828 | if (sema.analyzeAsType(block, src, param_ty_inst)) |param_ty| { |
| 9815 | 9829 | break :param_ty param_ty; |
| 9816 | 9830 | } else |err| break :err err; |
| ... | ... | @@ -11494,6 +11508,7 @@ fn zirSwitchBlockErrUnion(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Comp |
| 11494 | 11508 | sub_block.runtime_loop = null; |
| 11495 | 11509 | sub_block.runtime_cond = mod.declPtr(child_block.src_decl).toSrcLoc(main_operand_src, mod); |
| 11496 | 11510 | sub_block.runtime_index.increment(); |
| 11511 | sub_block.need_debug_scope = null; // this body is emitted regardless |
| 11497 | 11512 | defer sub_block.instructions.deinit(gpa); |
| 11498 | 11513 | |
| 11499 | 11514 | try sema.analyzeBodyRuntimeBreak(&sub_block, non_error_case.body); |
| ... | ... | @@ -11556,7 +11571,7 @@ fn zirSwitchBlockErrUnion(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Comp |
| 11556 | 11571 | sema.air_extra.appendSliceAssumeCapacity(@ptrCast(true_instructions)); |
| 11557 | 11572 | sema.air_extra.appendSliceAssumeCapacity(@ptrCast(sub_block.instructions.items)); |
| 11558 | 11573 | |
| 11559 | | return sema.analyzeBlockBody(block, main_src, &child_block, merges, false); |
| 11574 | return sema.resolveAnalyzedBlock(block, main_src, &child_block, merges, false); |
| 11560 | 11575 | } |
| 11561 | 11576 | |
| 11562 | 11577 | fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_ref: bool) CompileError!Air.Inst.Ref { |
| ... | ... | @@ -12178,7 +12193,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r |
| 12178 | 12193 | false, |
| 12179 | 12194 | ); |
| 12180 | 12195 | |
| 12181 | | return sema.analyzeBlockBody(block, src, &child_block, merges, false); |
| 12196 | return sema.resolveAnalyzedBlock(block, src, &child_block, merges, false); |
| 12182 | 12197 | } |
| 12183 | 12198 | |
| 12184 | 12199 | const SpecialProng = struct { |
| ... | ... | @@ -12229,6 +12244,7 @@ fn analyzeSwitchRuntimeBlock( |
| 12229 | 12244 | case_block.runtime_loop = null; |
| 12230 | 12245 | case_block.runtime_cond = mod.declPtr(child_block.src_decl).toSrcLoc(operand_src, mod); |
| 12231 | 12246 | case_block.runtime_index.increment(); |
| 12247 | case_block.need_debug_scope = null; // this body is emitted regardless |
| 12232 | 12248 | defer case_block.instructions.deinit(gpa); |
| 12233 | 12249 | |
| 12234 | 12250 | var extra_index: usize = special.end; |
| ... | ... | @@ -18602,7 +18618,7 @@ fn zirTypeofBuiltin(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr |
| 18602 | 18618 | }; |
| 18603 | 18619 | defer child_block.instructions.deinit(sema.gpa); |
| 18604 | 18620 | |
| 18605 | | const operand = try sema.resolveBody(&child_block, body, inst); |
| 18621 | const operand = try sema.resolveInlineBody(&child_block, body, inst); |
| 18606 | 18622 | const operand_ty = sema.typeOf(operand); |
| 18607 | 18623 | if (operand_ty.isGenericPoison()) return error.GenericPoison; |
| 18608 | 18624 | return Air.internedToRef(operand_ty.toIntern()); |
| ... | ... | @@ -18657,6 +18673,7 @@ fn zirTypeofPeer( |
| 18657 | 18673 | sema: *Sema, |
| 18658 | 18674 | block: *Block, |
| 18659 | 18675 | extended: Zir.Inst.Extended.InstData, |
| 18676 | inst: Zir.Inst.Index, |
| 18660 | 18677 | ) CompileError!Air.Inst.Ref { |
| 18661 | 18678 | const tracy = trace(@src()); |
| 18662 | 18679 | defer tracy.end(); |
| ... | ... | @@ -18681,7 +18698,7 @@ fn zirTypeofPeer( |
| 18681 | 18698 | }; |
| 18682 | 18699 | defer child_block.instructions.deinit(sema.gpa); |
| 18683 | 18700 | // Ignore the result, we only care about the instructions in `args`. |
| 18684 | | _ = try sema.analyzeBodyBreak(&child_block, body); |
| 18701 | _ = try sema.analyzeInlineBody(&child_block, body, inst); |
| 18685 | 18702 | |
| 18686 | 18703 | const args = sema.code.refSlice(extra.end, extended.small); |
| 18687 | 18704 | |
| ... | ... | @@ -18748,7 +18765,7 @@ fn zirBoolBr( |
| 18748 | 18765 | // comptime-known left-hand side. No need for a block here; the result |
| 18749 | 18766 | // is simply the rhs expression. Here we rely on there only being 1 |
| 18750 | 18767 | // break instruction (`break_inline`). |
| 18751 | | const rhs_result = try sema.resolveBody(parent_block, body, inst); |
| 18768 | const rhs_result = try sema.resolveInlineBody(parent_block, body, inst); |
| 18752 | 18769 | if (sema.typeOf(rhs_result).isNoReturn(mod)) { |
| 18753 | 18770 | return rhs_result; |
| 18754 | 18771 | } |
| ... | ... | @@ -18782,7 +18799,7 @@ fn zirBoolBr( |
| 18782 | 18799 | const lhs_result: Air.Inst.Ref = if (is_bool_or) .bool_true else .bool_false; |
| 18783 | 18800 | _ = try lhs_block.addBr(block_inst, lhs_result); |
| 18784 | 18801 | |
| 18785 | | const rhs_result = try sema.resolveBody(rhs_block, body, inst); |
| 18802 | const rhs_result = try sema.resolveInlineBody(rhs_block, body, inst); |
| 18786 | 18803 | const rhs_noret = sema.typeOf(rhs_result).isNoReturn(mod); |
| 18787 | 18804 | const coerced_rhs_result = if (!rhs_noret) rhs: { |
| 18788 | 18805 | const coerced_result = try sema.coerce(rhs_block, Type.bool, rhs_result, rhs_src); |
| ... | ... | @@ -18933,7 +18950,7 @@ fn zirCondbr( |
| 18933 | 18950 | sema: *Sema, |
| 18934 | 18951 | parent_block: *Block, |
| 18935 | 18952 | inst: Zir.Inst.Index, |
| 18936 | | ) CompileError!Zir.Inst.Index { |
| 18953 | ) CompileError!void { |
| 18937 | 18954 | const tracy = trace(@src()); |
| 18938 | 18955 | defer tracy.end(); |
| 18939 | 18956 | |
| ... | ... | @@ -18952,8 +18969,7 @@ fn zirCondbr( |
| 18952 | 18969 | const body = if (cond_val.toBool()) then_body else else_body; |
| 18953 | 18970 | |
| 18954 | 18971 | try sema.maybeErrorUnwrapCondbr(parent_block, body, extra.data.condition, cond_src); |
| 18955 | | // We use `analyzeBodyInner` since we want to propagate any possible |
| 18956 | | // `error.ComptimeBreak` to the caller. |
| 18972 | // We use `analyzeBodyInner` since we want to propagate any comptime control flow to the caller. |
| 18957 | 18973 | return sema.analyzeBodyInner(parent_block, body); |
| 18958 | 18974 | } |
| 18959 | 18975 | |
| ... | ... | @@ -18965,6 +18981,7 @@ fn zirCondbr( |
| 18965 | 18981 | sub_block.runtime_loop = null; |
| 18966 | 18982 | sub_block.runtime_cond = mod.declPtr(parent_block.src_decl).toSrcLoc(cond_src, mod); |
| 18967 | 18983 | sub_block.runtime_index.increment(); |
| 18984 | sub_block.need_debug_scope = null; // this body is emitted regardless |
| 18968 | 18985 | defer sub_block.instructions.deinit(gpa); |
| 18969 | 18986 | |
| 18970 | 18987 | try sema.analyzeBodyRuntimeBreak(&sub_block, then_body); |
| ... | ... | @@ -19002,7 +19019,6 @@ fn zirCondbr( |
| 19002 | 19019 | }); |
| 19003 | 19020 | sema.air_extra.appendSliceAssumeCapacity(@ptrCast(true_instructions)); |
| 19004 | 19021 | sema.air_extra.appendSliceAssumeCapacity(@ptrCast(sub_block.instructions.items)); |
| 19005 | | return always_noreturn; |
| 19006 | 19022 | } |
| 19007 | 19023 | |
| 19008 | 19024 | fn zirTry(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| ... | ... | @@ -19027,14 +19043,15 @@ fn zirTry(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError! |
| 19027 | 19043 | } |
| 19028 | 19044 | // We can analyze the body directly in the parent block because we know there are |
| 19029 | 19045 | // no breaks from the body possible, and that the body is noreturn. |
| 19030 | | return sema.resolveBody(parent_block, body, inst); |
| 19046 | try sema.analyzeBodyInner(parent_block, body); |
| 19047 | return .unreachable_value; |
| 19031 | 19048 | } |
| 19032 | 19049 | |
| 19033 | 19050 | var sub_block = parent_block.makeSubBlock(); |
| 19034 | 19051 | defer sub_block.instructions.deinit(sema.gpa); |
| 19035 | 19052 | |
| 19036 | 19053 | // This body is guaranteed to end with noreturn and has no breaks. |
| 19037 | | _ = try sema.analyzeBodyInner(&sub_block, body); |
| 19054 | try sema.analyzeBodyInner(&sub_block, body); |
| 19038 | 19055 | |
| 19039 | 19056 | try sema.air_extra.ensureUnusedCapacity(sema.gpa, @typeInfo(Air.Try).Struct.fields.len + |
| 19040 | 19057 | sub_block.instructions.items.len); |
| ... | ... | @@ -19074,14 +19091,15 @@ fn zirTryPtr(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileErr |
| 19074 | 19091 | } |
| 19075 | 19092 | // We can analyze the body directly in the parent block because we know there are |
| 19076 | 19093 | // no breaks from the body possible, and that the body is noreturn. |
| 19077 | | return sema.resolveBody(parent_block, body, inst); |
| 19094 | try sema.analyzeBodyInner(parent_block, body); |
| 19095 | return .unreachable_value; |
| 19078 | 19096 | } |
| 19079 | 19097 | |
| 19080 | 19098 | var sub_block = parent_block.makeSubBlock(); |
| 19081 | 19099 | defer sub_block.instructions.deinit(sema.gpa); |
| 19082 | 19100 | |
| 19083 | 19101 | // This body is guaranteed to end with noreturn and has no breaks. |
| 19084 | | _ = try sema.analyzeBodyInner(&sub_block, body); |
| 19102 | try sema.analyzeBodyInner(&sub_block, body); |
| 19085 | 19103 | |
| 19086 | 19104 | const operand_ty = sema.typeOf(operand); |
| 19087 | 19105 | const ptr_info = operand_ty.ptrInfo(mod); |
| ... | ... | @@ -19156,13 +19174,13 @@ fn ensurePostHoc(sema: *Sema, block: *Block, dest_block: Zir.Inst.Index) !*Label |
| 19156 | 19174 | return labeled_block; |
| 19157 | 19175 | } |
| 19158 | 19176 | |
| 19159 | | // A `break` statement is inside a runtime condition, but trying to |
| 19160 | | // break from an inline loop. In such case we must convert it to |
| 19161 | | // a runtime break. |
| 19162 | | fn addRuntimeBreak(sema: *Sema, child_block: *Block, break_data: BreakData) !void { |
| 19163 | | const labeled_block = try sema.ensurePostHoc(child_block, break_data.block_inst); |
| 19177 | /// A `break` statement is inside a runtime condition, but trying to |
| 19178 | /// break from an inline loop. In such case we must convert it to |
| 19179 | /// a runtime break. |
| 19180 | fn addRuntimeBreak(sema: *Sema, child_block: *Block, block_inst: Zir.Inst.Index, break_operand: Zir.Inst.Ref) !void { |
| 19181 | const labeled_block = try sema.ensurePostHoc(child_block, block_inst); |
| 19164 | 19182 | |
| 19165 | | const operand = try sema.resolveInst(break_data.operand); |
| 19183 | const operand = try sema.resolveInst(break_operand); |
| 19166 | 19184 | const br_ref = try child_block.addBr(labeled_block.label.merges.block_inst, operand); |
| 19167 | 19185 | |
| 19168 | 19186 | try labeled_block.label.merges.results.append(sema.gpa, operand); |
| ... | ... | @@ -19176,7 +19194,7 @@ fn addRuntimeBreak(sema: *Sema, child_block: *Block, break_data: BreakData) !voi |
| 19176 | 19194 | } |
| 19177 | 19195 | } |
| 19178 | 19196 | |
| 19179 | | fn zirUnreachable(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Zir.Inst.Index { |
| 19197 | fn zirUnreachable(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void { |
| 19180 | 19198 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].@"unreachable"; |
| 19181 | 19199 | const src = inst_data.src(); |
| 19182 | 19200 | |
| ... | ... | @@ -19193,14 +19211,13 @@ fn zirUnreachable(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 19193 | 19211 | }, |
| 19194 | 19212 | else => |e| return e, |
| 19195 | 19213 | }; |
| 19196 | | return always_noreturn; |
| 19197 | 19214 | } |
| 19198 | 19215 | |
| 19199 | 19216 | fn zirRetErrValue( |
| 19200 | 19217 | sema: *Sema, |
| 19201 | 19218 | block: *Block, |
| 19202 | 19219 | inst: Zir.Inst.Index, |
| 19203 | | ) CompileError!Zir.Inst.Index { |
| 19220 | ) CompileError!void { |
| 19204 | 19221 | const mod = sema.mod; |
| 19205 | 19222 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].str_tok; |
| 19206 | 19223 | const err_name = try mod.intern_pool.getOrPutString(sema.gpa, inst_data.get(sema.code)); |
| ... | ... | @@ -19219,7 +19236,7 @@ fn zirRetImplicit( |
| 19219 | 19236 | sema: *Sema, |
| 19220 | 19237 | block: *Block, |
| 19221 | 19238 | inst: Zir.Inst.Index, |
| 19222 | | ) CompileError!Zir.Inst.Index { |
| 19239 | ) CompileError!void { |
| 19223 | 19240 | const tracy = trace(@src()); |
| 19224 | 19241 | defer tracy.end(); |
| 19225 | 19242 | |
| ... | ... | @@ -19234,7 +19251,7 @@ fn zirRetImplicit( |
| 19234 | 19251 | } else { |
| 19235 | 19252 | try block.addUnreachable(r_brace_src, false); |
| 19236 | 19253 | } |
| 19237 | | return always_noreturn; |
| 19254 | return; |
| 19238 | 19255 | } |
| 19239 | 19256 | |
| 19240 | 19257 | const operand = try sema.resolveInst(inst_data.operand); |
| ... | ... | @@ -19265,7 +19282,7 @@ fn zirRetImplicit( |
| 19265 | 19282 | return sema.analyzeRet(block, operand, r_brace_src, r_brace_src); |
| 19266 | 19283 | } |
| 19267 | 19284 | |
| 19268 | | fn zirRetNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Zir.Inst.Index { |
| 19285 | fn zirRetNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void { |
| 19269 | 19286 | const tracy = trace(@src()); |
| 19270 | 19287 | defer tracy.end(); |
| 19271 | 19288 | |
| ... | ... | @@ -19276,7 +19293,7 @@ fn zirRetNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Zir |
| 19276 | 19293 | return sema.analyzeRet(block, operand, src, .{ .node_offset_return_operand = inst_data.src_node }); |
| 19277 | 19294 | } |
| 19278 | 19295 | |
| 19279 | | fn zirRetLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Zir.Inst.Index { |
| 19296 | fn zirRetLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void { |
| 19280 | 19297 | const tracy = trace(@src()); |
| 19281 | 19298 | defer tracy.end(); |
| 19282 | 19299 | |
| ... | ... | @@ -19295,7 +19312,6 @@ fn zirRetLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Zir |
| 19295 | 19312 | } |
| 19296 | 19313 | |
| 19297 | 19314 | _ = try block.addUnOp(.ret_load, ret_ptr); |
| 19298 | | return always_noreturn; |
| 19299 | 19315 | } |
| 19300 | 19316 | |
| 19301 | 19317 | fn retWithErrTracing( |
| ... | ... | @@ -19305,12 +19321,12 @@ fn retWithErrTracing( |
| 19305 | 19321 | is_non_err: Air.Inst.Ref, |
| 19306 | 19322 | ret_tag: Air.Inst.Tag, |
| 19307 | 19323 | operand: Air.Inst.Ref, |
| 19308 | | ) CompileError!Zir.Inst.Index { |
| 19324 | ) CompileError!void { |
| 19309 | 19325 | const mod = sema.mod; |
| 19310 | 19326 | const need_check = switch (is_non_err) { |
| 19311 | 19327 | .bool_true => { |
| 19312 | 19328 | _ = try block.addUnOp(ret_tag, operand); |
| 19313 | | return always_noreturn; |
| 19329 | return; |
| 19314 | 19330 | }, |
| 19315 | 19331 | .bool_false => false, |
| 19316 | 19332 | else => true, |
| ... | ... | @@ -19326,7 +19342,7 @@ fn retWithErrTracing( |
| 19326 | 19342 | if (!need_check) { |
| 19327 | 19343 | try sema.callBuiltin(block, src, return_err_fn, .never_inline, &args, .@"error return"); |
| 19328 | 19344 | _ = try block.addUnOp(ret_tag, operand); |
| 19329 | | return always_noreturn; |
| 19345 | return; |
| 19330 | 19346 | } |
| 19331 | 19347 | |
| 19332 | 19348 | var then_block = block.makeSubBlock(); |
| ... | ... | @@ -19353,8 +19369,6 @@ fn retWithErrTracing( |
| 19353 | 19369 | .operand = is_non_err, |
| 19354 | 19370 | .payload = cond_br_payload, |
| 19355 | 19371 | } } }); |
| 19356 | | |
| 19357 | | return always_noreturn; |
| 19358 | 19372 | } |
| 19359 | 19373 | |
| 19360 | 19374 | fn wantErrorReturnTracing(sema: *Sema, fn_ret_ty: Type) bool { |
| ... | ... | @@ -19481,7 +19495,7 @@ fn analyzeRet( |
| 19481 | 19495 | uncasted_operand: Air.Inst.Ref, |
| 19482 | 19496 | src: LazySrcLoc, |
| 19483 | 19497 | operand_src: LazySrcLoc, |
| 19484 | | ) CompileError!Zir.Inst.Index { |
| 19498 | ) CompileError!void { |
| 19485 | 19499 | // Special case for returning an error to an inferred error set; we need to |
| 19486 | 19500 | // add the error tag to the inferred error set of the in-scope function, so |
| 19487 | 19501 | // that the coercion below works correctly. |
| ... | ... | @@ -19513,7 +19527,7 @@ fn analyzeRet( |
| 19513 | 19527 | try inlining.merges.results.append(sema.gpa, operand); |
| 19514 | 19528 | try inlining.merges.br_list.append(sema.gpa, br_inst.toIndex().?); |
| 19515 | 19529 | try inlining.merges.src_locs.append(sema.gpa, operand_src); |
| 19516 | | return always_noreturn; |
| 19530 | return; |
| 19517 | 19531 | } else if (block.is_comptime) { |
| 19518 | 19532 | return sema.fail(block, src, "function called at runtime cannot return value at comptime", .{}); |
| 19519 | 19533 | } else if (sema.func_is_naked) { |
| ... | ... | @@ -19538,8 +19552,6 @@ fn analyzeRet( |
| 19538 | 19552 | } |
| 19539 | 19553 | |
| 19540 | 19554 | _ = try block.addUnOp(air_tag, operand); |
| 19541 | | |
| 19542 | | return always_noreturn; |
| 19543 | 19555 | } |
| 19544 | 19556 | |
| 19545 | 19557 | fn floatOpAllowed(tag: Zir.Inst.Tag) bool { |
| ... | ... | @@ -19616,7 +19628,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 19616 | 19628 | const address_space: std.builtin.AddressSpace = if (inst_data.flags.has_addrspace) blk: { |
| 19617 | 19629 | const ref: Zir.Inst.Ref = @enumFromInt(sema.code.extra[extra_i]); |
| 19618 | 19630 | extra_i += 1; |
| 19619 | | break :blk try sema.analyzeAddressSpace(block, addrspace_src, ref, .pointer); |
| 19631 | break :blk try sema.resolveAddressSpace(block, addrspace_src, ref, .pointer); |
| 19620 | 19632 | } else if (elem_ty.zigTypeTag(mod) == .Fn and target.cpu.arch == .avr) .flash else .generic; |
| 19621 | 19633 | |
| 19622 | 19634 | const bit_offset: u16 = if (inst_data.flags.has_bit_range) blk: { |
| ... | ... | @@ -35737,7 +35749,7 @@ fn semaBackingIntType(mod: *Module, struct_type: InternPool.Key.StructType) Comp |
| 35737 | 35749 | break :blk try sema.resolveType(&block, backing_int_src, backing_int_ref); |
| 35738 | 35750 | } else { |
| 35739 | 35751 | const body = zir.bodySlice(extra_index, backing_int_body_len); |
| 35740 | | const ty_ref = try sema.resolveBody(&block, body, zir_index); |
| 35752 | const ty_ref = try sema.resolveInlineBody(&block, body, zir_index); |
| 35741 | 35753 | break :blk try sema.analyzeAsType(&block, backing_int_src, ty_ref); |
| 35742 | 35754 | } |
| 35743 | 35755 | }; |
| ... | ... | @@ -36618,7 +36630,7 @@ fn semaStructFields( |
| 36618 | 36630 | assert(zir_field.type_body_len != 0); |
| 36619 | 36631 | const body = zir.bodySlice(extra_index, zir_field.type_body_len); |
| 36620 | 36632 | extra_index += body.len; |
| 36621 | | const ty_ref = try sema.resolveBody(&block_scope, body, zir_index); |
| 36633 | const ty_ref = try sema.resolveInlineBody(&block_scope, body, zir_index); |
| 36622 | 36634 | break :ty sema.analyzeAsType(&block_scope, .unneeded, ty_ref) catch |err| switch (err) { |
| 36623 | 36635 | error.NeededSourceLocation => { |
| 36624 | 36636 | const ty_src = mod.fieldSrcLoc(decl_index, .{ |
| ... | ... | @@ -36704,7 +36716,7 @@ fn semaStructFields( |
| 36704 | 36716 | if (zir_field.align_body_len > 0) { |
| 36705 | 36717 | const body = zir.bodySlice(extra_index, zir_field.align_body_len); |
| 36706 | 36718 | extra_index += body.len; |
| 36707 | | const align_ref = try sema.resolveBody(&block_scope, body, zir_index); |
| 36719 | const align_ref = try sema.resolveInlineBody(&block_scope, body, zir_index); |
| 36708 | 36720 | const field_align = sema.analyzeAsAlign(&block_scope, .unneeded, align_ref) catch |err| switch (err) { |
| 36709 | 36721 | error.NeededSourceLocation => { |
| 36710 | 36722 | const align_src = mod.fieldSrcLoc(decl_index, .{ |
| ... | ... | @@ -36854,7 +36866,7 @@ fn semaStructFieldInits( |
| 36854 | 36866 | try sema.inst_map.ensureSpaceForInstructions(sema.gpa, &.{zir_index}); |
| 36855 | 36867 | sema.inst_map.putAssumeCapacity(zir_index, type_ref); |
| 36856 | 36868 | |
| 36857 | | const init = try sema.resolveBody(&block_scope, body, zir_index); |
| 36869 | const init = try sema.resolveInlineBody(&block_scope, body, zir_index); |
| 36858 | 36870 | const coerced = sema.coerce(&block_scope, field_ty, init, .unneeded) catch |err| switch (err) { |
| 36859 | 36871 | error.NeededSourceLocation => { |
| 36860 | 36872 | const init_src = mod.fieldSrcLoc(decl_index, .{ |
| ... | ... | @@ -36971,7 +36983,7 @@ fn semaUnionFields(mod: *Module, arena: Allocator, union_type: InternPool.Key.Un |
| 36971 | 36983 | defer assert(block_scope.instructions.items.len == 0); |
| 36972 | 36984 | |
| 36973 | 36985 | if (body.len != 0) { |
| 36974 | | try sema.analyzeBody(&block_scope, body); |
| 36986 | _ = try sema.analyzeInlineBody(&block_scope, body, zir_index); |
| 36975 | 36987 | } |
| 36976 | 36988 | |
| 36977 | 36989 | for (comptime_mutable_decls.items) |ct_decl_index| { |
| ... | ... | @@ -37914,15 +37926,25 @@ pub const AddressSpaceContext = enum { |
| 37914 | 37926 | pointer, |
| 37915 | 37927 | }; |
| 37916 | 37928 | |
| 37917 | | pub fn analyzeAddressSpace( |
| 37929 | fn resolveAddressSpace( |
| 37918 | 37930 | sema: *Sema, |
| 37919 | 37931 | block: *Block, |
| 37920 | 37932 | src: LazySrcLoc, |
| 37921 | 37933 | zir_ref: Zir.Inst.Ref, |
| 37922 | 37934 | ctx: AddressSpaceContext, |
| 37923 | 37935 | ) !std.builtin.AddressSpace { |
| 37924 | | const mod = sema.mod; |
| 37925 | 37936 | const air_ref = try sema.resolveInst(zir_ref); |
| 37937 | return sema.analyzeAsAddressSpace(block, src, air_ref, ctx); |
| 37938 | } |
| 37939 | |
| 37940 | pub fn analyzeAsAddressSpace( |
| 37941 | sema: *Sema, |
| 37942 | block: *Block, |
| 37943 | src: LazySrcLoc, |
| 37944 | air_ref: Air.Inst.Ref, |
| 37945 | ctx: AddressSpaceContext, |
| 37946 | ) !std.builtin.AddressSpace { |
| 37947 | const mod = sema.mod; |
| 37926 | 37948 | const coerced = try sema.coerce(block, Type.fromInterned(.address_space_type), air_ref, src); |
| 37927 | 37949 | const addrspace_val = try sema.resolveConstDefinedValue(block, src, coerced, .{ |
| 37928 | 37950 | .needed_comptime_reason = "address space must be comptime-known", |