| ... | @@ -876,104 +876,100 @@ pub fn deinit(sema: *Sema) void { | ... | @@ -876,104 +876,100 @@ pub fn deinit(sema: *Sema) void { |
| 876 | sema.* = undefined; | 876 | sema.* = undefined; |
| 877 | } | 877 | } |
| 878 | | 878 | |
| 879 | /// Returns only the result from the body that is specified. | 879 | /// Performs semantic analysis of a ZIR body which is behind a runtime condition. If comptime |
| 880 | /// Only appropriate to call when it is determined at comptime that this body | 880 | /// control flow happens here, Sema will convert it to runtime control flow by introducing post-hoc |
| 881 | /// has no peers. | 881 | /// blocks where necessary. |
| 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 | | | |
| 903 | fn analyzeBodyRuntimeBreak(sema: *Sema, block: *Block, body: []const Zir.Inst.Index) !void { | 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 | error.ComptimeBreak => { | 884 | error.ComptimeBreak => { |
| 906 | const zir_datas = sema.code.instructions.items(.data); | 885 | const zir_datas = sema.code.instructions.items(.data); |
| 907 | const break_data = zir_datas[@intFromEnum(sema.comptime_break_inst)].@"break"; | 886 | const break_data = zir_datas[@intFromEnum(sema.comptime_break_inst)].@"break"; |
| 908 | const extra = sema.code.extraData(Zir.Inst.Break, break_data.payload_index).data; | 887 | const extra = sema.code.extraData(Zir.Inst.Break, break_data.payload_index).data; |
| 909 | try sema.addRuntimeBreak(block, .{ | 888 | try sema.addRuntimeBreak(block, extra.block_inst, break_data.operand); |
| 910 | .block_inst = extra.block_inst, | | |
| 911 | .operand = break_data.operand, | | |
| 912 | .inst = sema.comptime_break_inst, | | |
| 913 | }); | | |
| 914 | }, | 889 | }, |
| 915 | else => |e| return e, | 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 | sema: *Sema, | 897 | sema: *Sema, |
| 921 | block: *Block, | 898 | block: *Block, |
| 922 | body: []const Zir.Inst.Index, | 899 | body: []const Zir.Inst.Index, |
| 923 | ) !void { | 900 | ) !void { |
| 924 | _ = sema.analyzeBodyInner(block, body) catch |err| switch (err) { | 901 | sema.analyzeBodyInner(block, body) catch |err| switch (err) { |
| 925 | error.ComptimeBreak => unreachable, // unexpected comptime control flow | 902 | error.ComptimeBreak => unreachable, // unexpected comptime control flow |
| 926 | else => |e| return e, | 903 | else => |e| return e, |
| 927 | }; | 904 | }; |
| 928 | } | 905 | } |
| 929 | | 906 | |
| 930 | const BreakData = struct { | 907 | /// Given a ZIR body which can be exited via a `break_inline` instruction, or a non-inline body which |
| 931 | block_inst: Zir.Inst.Index, | 908 | /// we are evaluating at comptime, semantically analyze the body and return the result from it. |
| 932 | operand: Zir.Inst.Ref, | 909 | /// Returns `null` if control flow did not break from this block, but instead terminated with some |
| 933 | inst: Zir.Inst.Index, | 910 | /// other runtime noreturn instruction. Compile-time breaks to blocks further up the stack still |
| 934 | }; | 911 | /// return `error.ComptimeBreak`. If `block.is_comptime`, this function will never return `null`. |
| 935 | | 912 | fn analyzeInlineBody( |
| 936 | pub fn analyzeBodyBreak( | | |
| 937 | sema: *Sema, | 913 | sema: *Sema, |
| 938 | block: *Block, | 914 | block: *Block, |
| 939 | body: []const Zir.Inst.Index, | 915 | body: []const Zir.Inst.Index, |
| 940 | ) CompileError!?BreakData { | 916 | /// The index which a break instruction can target to break from this body. |
| 941 | const break_inst = sema.analyzeBodyInner(block, body) catch |err| switch (err) { | 917 | break_target: Zir.Inst.Index, |
| 942 | error.ComptimeBreak => sema.comptime_break_inst, | 918 | ) CompileError!?Air.Inst.Ref { |
| 943 | else => |e| return e, | 919 | if (sema.analyzeBodyInner(block, body)) |_| { |
| 944 | }; | | |
| 945 | if (block.instructions.items.len != 0 and | | |
| 946 | sema.isNoReturn(block.instructions.items[block.instructions.items.len - 1].toRef())) | | |
| 947 | return null; | 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 | const break_data = sema.code.instructions.items(.data)[@intFromEnum(break_inst)].@"break"; | 926 | const break_data = sema.code.instructions.items(.data)[@intFromEnum(break_inst)].@"break"; |
| 949 | const extra = sema.code.extraData(Zir.Inst.Break, break_data.payload_index).data; | 927 | const extra = sema.code.extraData(Zir.Inst.Break, break_data.payload_index).data; |
| 950 | return BreakData{ | 928 | if (extra.block_inst != break_target) { |
| 951 | .block_inst = extra.block_inst, | 929 | // This control flow goes further up the stack. |
| 952 | .operand = break_data.operand, | 930 | return error.ComptimeBreak; |
| 953 | .inst = break_inst, | 931 | } |
| 954 | }; | 932 | return try sema.resolveInst(break_data.operand); |
| 955 | } | 933 | } |
| 956 | | 934 | |
| 957 | /// ZIR instructions which are always `noreturn` return this. This matches the | 935 | /// Like `analyzeInlineBody`, but if the body does not break with a value, returns |
| 958 | /// return type of `analyzeBody` so that we can tail call them. | 936 | /// `.unreachable_value` instead of `null`. Notably, use this to evaluate an arbitrary |
| 959 | /// Only appropriate to return when the instruction is known to be NoReturn | 937 | /// body at comptime to a single result value. |
| 960 | /// solely based on the ZIR tag. | 938 | pub fn resolveInlineBody( |
| 961 | const always_noreturn: CompileError!Zir.Inst.Index = @as(Zir.Inst.Index, undefined); | 939 | sema: *Sema, |
| 962 | | 940 | block: *Block, |
| 963 | /// This function is the main loop of `Sema` and it can be used in two different ways: | 941 | body: []const Zir.Inst.Index, |
| 964 | /// * The traditional way where there are N breaks out of the block and peer type | 942 | /// The index which a break instruction can target to break from this body. |
| 965 | /// resolution is done on the break operands. In this case, the `Zir.Inst.Index` | 943 | break_target: Zir.Inst.Index, |
| 966 | /// part of the return value will be `undefined`, and callsites should ignore it, | 944 | ) CompileError!Air.Inst.Ref { |
| 967 | /// finding the block result value via the block scope. | 945 | return (try sema.analyzeInlineBody(block, body, break_target)) orelse .unreachable_value; |
| 968 | /// * The "flat" way. There is only 1 break out of the block, and it is with a `break_inline` | 946 | } |
| 969 | /// instruction. In this case, the `Zir.Inst.Index` part of the return value will be | 947 | |
| 970 | /// the break instruction. This communicates both which block the break applies to, as | 948 | /// This function is the main loop of `Sema`. It analyzes a single body of ZIR instructions. |
| 971 | /// well as the operand. No block scope needs to be created for this strategy. | 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 | fn analyzeBodyInner( | 968 | fn analyzeBodyInner( |
| 973 | sema: *Sema, | 969 | sema: *Sema, |
| 974 | block: *Block, | 970 | block: *Block, |
| 975 | body: []const Zir.Inst.Index, | 971 | body: []const Zir.Inst.Index, |
| 976 | ) CompileError!Zir.Inst.Index { | 972 | ) CompileError!void { |
| 977 | // No tracy calls here, to avoid interfering with the tail call mechanism. | 973 | // No tracy calls here, to avoid interfering with the tail call mechanism. |
| 978 | | 974 | |
| 979 | try sema.inst_map.ensureSpaceForInstructions(sema.gpa, body); | 975 | try sema.inst_map.ensureSpaceForInstructions(sema.gpa, body); |
| ... | @@ -997,7 +993,7 @@ fn analyzeBodyInner( | ... | @@ -997,7 +993,7 @@ fn analyzeBodyInner( |
| 997 | // the loop. The only way to break out of the loop is with a `noreturn` | 993 | // the loop. The only way to break out of the loop is with a `noreturn` |
| 998 | // instruction. | 994 | // instruction. |
| 999 | var i: u32 = 0; | 995 | var i: u32 = 0; |
| 1000 | const result = while (true) { | 996 | while (true) { |
| 1001 | crash_info.setBodyIndex(i); | 997 | crash_info.setBodyIndex(i); |
| 1002 | const inst = body[i]; | 998 | const inst = body[i]; |
| 1003 | std.log.scoped(.sema_zir).debug("sema ZIR {s} %{d}", .{ | 999 | std.log.scoped(.sema_zir).debug("sema ZIR {s} %{d}", .{ |
| ... | @@ -1214,14 +1210,14 @@ fn analyzeBodyInner( | ... | @@ -1214,14 +1210,14 @@ fn analyzeBodyInner( |
| 1214 | // Instructions that we know to *always* be noreturn based solely on their tag. | 1210 | // Instructions that we know to *always* be noreturn based solely on their tag. |
| 1215 | // These functions match the return type of analyzeBody so that we can | 1211 | // These functions match the return type of analyzeBody so that we can |
| 1216 | // tail call them here. | 1212 | // tail call them here. |
| 1217 | .compile_error => break sema.zirCompileError(block, inst), | 1213 | .compile_error => break try sema.zirCompileError(block, inst), |
| 1218 | .ret_implicit => break sema.zirRetImplicit(block, inst), | 1214 | .ret_implicit => break try sema.zirRetImplicit(block, inst), |
| 1219 | .ret_node => break sema.zirRetNode(block, inst), | 1215 | .ret_node => break try sema.zirRetNode(block, inst), |
| 1220 | .ret_load => break sema.zirRetLoad(block, inst), | 1216 | .ret_load => break try sema.zirRetLoad(block, inst), |
| 1221 | .ret_err_value => break sema.zirRetErrValue(block, inst), | 1217 | .ret_err_value => break try sema.zirRetErrValue(block, inst), |
| 1222 | .@"unreachable" => break sema.zirUnreachable(block, inst), | 1218 | .@"unreachable" => break try sema.zirUnreachable(block, inst), |
| 1223 | .panic => break sema.zirPanic(block, inst), | 1219 | .panic => break try sema.zirPanic(block, inst), |
| 1224 | .trap => break sema.zirTrap(block, inst), | 1220 | .trap => break try sema.zirTrap(block, inst), |
| 1225 | // zig fmt: on | 1221 | // zig fmt: on |
| 1226 | | 1222 | |
| 1227 | // This instruction never exists in an analyzed body. It exists only in the declaration | 1223 | // This instruction never exists in an analyzed body. It exists only in the declaration |
| ... | @@ -1247,7 +1243,7 @@ fn analyzeBodyInner( | ... | @@ -1247,7 +1243,7 @@ fn analyzeBodyInner( |
| 1247 | .builtin_extern => try sema.zirBuiltinExtern( block, extended), | 1243 | .builtin_extern => try sema.zirBuiltinExtern( block, extended), |
| 1248 | .@"asm" => try sema.zirAsm( block, extended, false), | 1244 | .@"asm" => try sema.zirAsm( block, extended, false), |
| 1249 | .asm_expr => try sema.zirAsm( block, extended, true), | 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 | .compile_log => try sema.zirCompileLog( extended), | 1247 | .compile_log => try sema.zirCompileLog( extended), |
| 1252 | .min_multi => try sema.zirMinMaxMulti( block, extended, .min), | 1248 | .min_multi => try sema.zirMinMaxMulti( block, extended, .min), |
| 1253 | .max_multi => try sema.zirMinMaxMulti( block, extended, .max), | 1249 | .max_multi => try sema.zirMinMaxMulti( block, extended, .max), |
| ... | @@ -1522,18 +1518,16 @@ fn analyzeBodyInner( | ... | @@ -1522,18 +1518,16 @@ fn analyzeBodyInner( |
| 1522 | // Special case instructions to handle comptime control flow. | 1518 | // Special case instructions to handle comptime control flow. |
| 1523 | .@"break" => { | 1519 | .@"break" => { |
| 1524 | if (block.is_comptime) { | 1520 | if (block.is_comptime) { |
| 1525 | break inst; // same as break_inline | 1521 | sema.comptime_break_inst = inst; |
| | 1522 | return error.ComptimeBreak; |
| 1526 | } else { | 1523 | } else { |
| 1527 | break sema.zirBreak(block, inst); | 1524 | try sema.zirBreak(block, inst); |
| | 1525 | break; |
| 1528 | } | 1526 | } |
| 1529 | }, | 1527 | }, |
| 1530 | .break_inline => { | 1528 | .break_inline => { |
| 1531 | if (block.is_comptime) { | 1529 | sema.comptime_break_inst = inst; |
| 1532 | break inst; | 1530 | return error.ComptimeBreak; |
| 1533 | } else { | | |
| 1534 | sema.comptime_break_inst = inst; | | |
| 1535 | return error.ComptimeBreak; | | |
| 1536 | } | | |
| 1537 | }, | 1531 | }, |
| 1538 | .repeat => { | 1532 | .repeat => { |
| 1539 | if (block.is_comptime) { | 1533 | if (block.is_comptime) { |
| ... | @@ -1548,7 +1542,10 @@ fn analyzeBodyInner( | ... | @@ -1548,7 +1542,10 @@ fn analyzeBodyInner( |
| 1548 | i = 0; | 1542 | i = 0; |
| 1549 | continue; | 1543 | continue; |
| 1550 | } else { | 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 | .repeat_inline => { | 1551 | .repeat_inline => { |
| ... | @@ -1584,13 +1581,8 @@ fn analyzeBodyInner( | ... | @@ -1584,13 +1581,8 @@ fn analyzeBodyInner( |
| 1584 | child_block.instructions = block.instructions; | 1581 | child_block.instructions = block.instructions; |
| 1585 | defer block.instructions = child_block.instructions; | 1582 | defer block.instructions = child_block.instructions; |
| 1586 | | 1583 | |
| 1587 | const break_data = (try sema.analyzeBodyBreak(&child_block, inline_body)) orelse | 1584 | const result = try sema.analyzeInlineBody(&child_block, inline_body, inst) orelse break; |
| 1588 | break always_noreturn; | 1585 | break :blk result; |
| 1589 | if (inst == break_data.block_inst) { | | |
| 1590 | break :blk try sema.resolveInst(break_data.operand); | | |
| 1591 | } else { | | |
| 1592 | break break_data.inst; | | |
| 1593 | } | | |
| 1594 | }, | 1586 | }, |
| 1595 | .block, .block_comptime => blk: { | 1587 | .block, .block_comptime => blk: { |
| 1596 | if (!block.is_comptime) { | 1588 | if (!block.is_comptime) { |
| ... | @@ -1615,13 +1607,8 @@ fn analyzeBodyInner( | ... | @@ -1615,13 +1607,8 @@ fn analyzeBodyInner( |
| 1615 | child_block.instructions = block.instructions; | 1607 | child_block.instructions = block.instructions; |
| 1616 | defer block.instructions = child_block.instructions; | 1608 | defer block.instructions = child_block.instructions; |
| 1617 | | 1609 | |
| 1618 | const break_data = (try sema.analyzeBodyBreak(&child_block, inline_body)) orelse | 1610 | const result = try sema.analyzeInlineBody(&child_block, inline_body, inst) orelse break; |
| 1619 | break always_noreturn; | 1611 | break :blk result; |
| 1620 | if (inst == break_data.block_inst) { | | |
| 1621 | break :blk try sema.resolveInst(break_data.operand); | | |
| 1622 | } else { | | |
| 1623 | break break_data.inst; | | |
| 1624 | } | | |
| 1625 | }, | 1612 | }, |
| 1626 | .block_inline => blk: { | 1613 | .block_inline => blk: { |
| 1627 | // Directly analyze the block body without introducing a new block. | 1614 | // Directly analyze the block body without introducing a new block. |
| ... | @@ -1634,7 +1621,12 @@ fn analyzeBodyInner( | ... | @@ -1634,7 +1621,12 @@ fn analyzeBodyInner( |
| 1634 | const inline_body = sema.code.bodySlice(extra.end, extra.data.body_len); | 1621 | const inline_body = sema.code.bodySlice(extra.end, extra.data.body_len); |
| 1635 | const gpa = sema.gpa; | 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 | // Create a temporary child block so that this inline block is properly | 1630 | // Create a temporary child block so that this inline block is properly |
| 1639 | // labeled for any .restore_err_ret_index instructions | 1631 | // labeled for any .restore_err_ret_index instructions |
| 1640 | var child_block = block.makeSubBlock(); | 1632 | var child_block = block.makeSubBlock(); |
| ... | @@ -1660,11 +1652,26 @@ fn analyzeBodyInner( | ... | @@ -1660,11 +1652,26 @@ fn analyzeBodyInner( |
| 1660 | child_block.instructions = block.instructions; | 1652 | child_block.instructions = block.instructions; |
| 1661 | defer block.instructions = child_block.instructions; | 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 | if (need_debug_scope) { | 1670 | if (need_debug_scope) { |
| 1665 | _ = try sema.ensurePostHoc(block, inst); | 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 | // A runtime conditional branch that needs a post-hoc block to be | 1677 | // A runtime conditional branch that needs a post-hoc block to be |
| ... | @@ -1686,13 +1693,13 @@ fn analyzeBodyInner( | ... | @@ -1686,13 +1693,13 @@ fn analyzeBodyInner( |
| 1686 | // It may pass through our currently being analyzed block_inline or it | 1693 | // It may pass through our currently being analyzed block_inline or it |
| 1687 | // may point directly to it. In the latter case, this modifies the | 1694 | // may point directly to it. In the latter case, this modifies the |
| 1688 | // block that we looked up in the post_hoc_blocks map above. | 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 | try labeled_block.block.instructions.appendSlice(gpa, block.instructions.items[block_index..]); | 1699 | try labeled_block.block.instructions.appendSlice(gpa, block.instructions.items[block_index..]); |
| 1693 | block.instructions.items.len = block_index; | 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 | // Destroy the ad-hoc block entry so that it does not interfere with | 1704 | // Destroy the ad-hoc block entry so that it does not interfere with |
| 1698 | // the next iteration of comptime control flow, if any. | 1705 | // the next iteration of comptime control flow, if any. |
| ... | @@ -1703,15 +1710,19 @@ fn analyzeBodyInner( | ... | @@ -1703,15 +1710,19 @@ fn analyzeBodyInner( |
| 1703 | break :blk block_result; | 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 | if (inst == break_data.block_inst) { | 1714 | if (inst == break_data.block_inst) { |
| 1708 | break :blk try sema.resolveInst(break_data.operand); | 1715 | break :blk try sema.resolveInst(break_data.operand); |
| 1709 | } else { | 1716 | } else { |
| 1710 | break break_data.inst; | 1717 | // `comptime_break_inst` preserved from `analyzeBodyInner` above. |
| | 1718 | return error.ComptimeBreak; |
| 1711 | } | 1719 | } |
| 1712 | }, | 1720 | }, |
| 1713 | .condbr => blk: { | 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 | // Same as condbr_inline. TODO https://github.com/ziglang/zig/issues/8220 | 1726 | // Same as condbr_inline. TODO https://github.com/ziglang/zig/issues/8220 |
| 1716 | const inst_data = datas[@intFromEnum(inst)].pl_node; | 1727 | const inst_data = datas[@intFromEnum(inst)].pl_node; |
| 1717 | const cond_src: LazySrcLoc = .{ .node_offset_if_cond = inst_data.src_node }; | 1728 | const cond_src: LazySrcLoc = .{ .node_offset_if_cond = inst_data.src_node }; |
| ... | @@ -1728,13 +1739,9 @@ fn analyzeBodyInner( | ... | @@ -1728,13 +1739,9 @@ fn analyzeBodyInner( |
| 1728 | const inline_body = if (cond.val.toBool()) then_body else else_body; | 1739 | const inline_body = if (cond.val.toBool()) then_body else else_body; |
| 1729 | | 1740 | |
| 1730 | try sema.maybeErrorUnwrapCondbr(block, inline_body, extra.data.condition, cond_src); | 1741 | try sema.maybeErrorUnwrapCondbr(block, inline_body, extra.data.condition, cond_src); |
| 1731 | const break_data = (try sema.analyzeBodyBreak(block, inline_body)) orelse | 1742 | |
| 1732 | break always_noreturn; | 1743 | const result = try sema.analyzeInlineBody(block, inline_body, inst) orelse break; |
| 1733 | if (inst == break_data.block_inst) { | 1744 | break :blk result; |
| 1734 | break :blk try sema.resolveInst(break_data.operand); | | |
| 1735 | } else { | | |
| 1736 | break break_data.inst; | | |
| 1737 | } | | |
| 1738 | }, | 1745 | }, |
| 1739 | .condbr_inline => blk: { | 1746 | .condbr_inline => blk: { |
| 1740 | const inst_data = datas[@intFromEnum(inst)].pl_node; | 1747 | const inst_data = datas[@intFromEnum(inst)].pl_node; |
| ... | @@ -1754,13 +1761,9 @@ fn analyzeBodyInner( | ... | @@ -1754,13 +1761,9 @@ fn analyzeBodyInner( |
| 1754 | try sema.maybeErrorUnwrapCondbr(block, inline_body, extra.data.condition, cond_src); | 1761 | try sema.maybeErrorUnwrapCondbr(block, inline_body, extra.data.condition, cond_src); |
| 1755 | const old_runtime_index = block.runtime_index; | 1762 | const old_runtime_index = block.runtime_index; |
| 1756 | defer block.runtime_index = old_runtime_index; | 1763 | defer block.runtime_index = old_runtime_index; |
| 1757 | const break_data = (try sema.analyzeBodyBreak(block, inline_body)) orelse | 1764 | |
| 1758 | break always_noreturn; | 1765 | const result = try sema.analyzeInlineBody(block, inline_body, inst) orelse break; |
| 1759 | if (inst == break_data.block_inst) { | 1766 | break :blk result; |
| 1760 | break :blk try sema.resolveInst(break_data.operand); | | |
| 1761 | } else { | | |
| 1762 | break break_data.inst; | | |
| 1763 | } | | |
| 1764 | }, | 1767 | }, |
| 1765 | .@"try" => blk: { | 1768 | .@"try" => blk: { |
| 1766 | if (!block.is_comptime) break :blk try sema.zirTry(block, inst); | 1769 | if (!block.is_comptime) break :blk try sema.zirTry(block, inst); |
| ... | @@ -1785,13 +1788,8 @@ fn analyzeBodyInner( | ... | @@ -1785,13 +1788,8 @@ fn analyzeBodyInner( |
| 1785 | if (is_non_err_val.toBool()) { | 1788 | if (is_non_err_val.toBool()) { |
| 1786 | break :blk try sema.analyzeErrUnionPayload(block, src, err_union_ty, err_union, operand_src, false); | 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 | 1791 | const result = try sema.analyzeInlineBody(block, inline_body, inst) orelse break; |
| 1789 | break always_noreturn; | 1792 | break :blk result; |
| 1790 | if (inst == break_data.block_inst) { | | |
| 1791 | break :blk try sema.resolveInst(break_data.operand); | | |
| 1792 | } else { | | |
| 1793 | break break_data.inst; | | |
| 1794 | } | | |
| 1795 | }, | 1793 | }, |
| 1796 | .try_ptr => blk: { | 1794 | .try_ptr => blk: { |
| 1797 | if (!block.is_comptime) break :blk try sema.zirTryPtr(block, inst); | 1795 | if (!block.is_comptime) break :blk try sema.zirTryPtr(block, inst); |
| ... | @@ -1811,22 +1809,22 @@ fn analyzeBodyInner( | ... | @@ -1811,22 +1809,22 @@ fn analyzeBodyInner( |
| 1811 | if (is_non_err_val.toBool()) { | 1809 | if (is_non_err_val.toBool()) { |
| 1812 | break :blk try sema.analyzeErrUnionPayloadPtr(block, src, operand, false, false); | 1810 | break :blk try sema.analyzeErrUnionPayloadPtr(block, src, operand, false, false); |
| 1813 | } | 1811 | } |
| 1814 | const break_data = (try sema.analyzeBodyBreak(block, inline_body)) orelse | 1812 | const result = try sema.analyzeInlineBody(block, inline_body, inst) orelse break; |
| 1815 | break always_noreturn; | 1813 | break :blk result; |
| 1816 | if (inst == break_data.block_inst) { | | |
| 1817 | break :blk try sema.resolveInst(break_data.operand); | | |
| 1818 | } else { | | |
| 1819 | break break_data.inst; | | |
| 1820 | } | | |
| 1821 | }, | 1814 | }, |
| 1822 | .@"defer" => blk: { | 1815 | .@"defer" => blk: { |
| 1823 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].@"defer"; | 1816 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].@"defer"; |
| 1824 | const defer_body = sema.code.bodySlice(inst_data.index, inst_data.len); | 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) { | 1818 | if (sema.analyzeBodyInner(block, defer_body)) |_| { |
| 1826 | error.ComptimeBreak => sema.comptime_break_inst, | 1819 | // The defer terminated noreturn - no more analysis needed. |
| | 1820 | break; |
| | 1821 | } else |err| switch (err) { |
| | 1822 | error.ComptimeBreak => {}, |
| 1827 | else => |e| return e, | 1823 | else => |e| return e, |
| 1828 | }; | 1824 | } |
| 1829 | if (break_inst != defer_body[defer_body.len - 1]) break always_noreturn; | 1825 | if (sema.comptime_break_inst != defer_body[defer_body.len - 1]) { |
| | 1826 | return error.ComptimeBreak; |
| | 1827 | } |
| 1830 | break :blk .void_value; | 1828 | break :blk .void_value; |
| 1831 | }, | 1829 | }, |
| 1832 | .defer_err_code => blk: { | 1830 | .defer_err_code => blk: { |
| ... | @@ -1835,11 +1833,16 @@ fn analyzeBodyInner( | ... | @@ -1835,11 +1833,16 @@ fn analyzeBodyInner( |
| 1835 | const defer_body = sema.code.bodySlice(extra.index, extra.len); | 1833 | const defer_body = sema.code.bodySlice(extra.index, extra.len); |
| 1836 | const err_code = try sema.resolveInst(inst_data.err_code); | 1834 | const err_code = try sema.resolveInst(inst_data.err_code); |
| 1837 | map.putAssumeCapacity(extra.remapped_err_code, err_code); | 1835 | map.putAssumeCapacity(extra.remapped_err_code, err_code); |
| 1838 | const break_inst = sema.analyzeBodyInner(block, defer_body) catch |err| switch (err) { | 1836 | if (sema.analyzeBodyInner(block, defer_body)) |_| { |
| 1839 | error.ComptimeBreak => sema.comptime_break_inst, | 1837 | // The defer terminated noreturn - no more analysis needed. |
| | 1838 | break; |
| | 1839 | } else |err| switch (err) { |
| | 1840 | error.ComptimeBreak => {}, |
| 1840 | else => |e| return e, | 1841 | else => |e| return e, |
| 1841 | }; | 1842 | } |
| 1842 | if (break_inst != defer_body[defer_body.len - 1]) break always_noreturn; | 1843 | if (sema.comptime_break_inst != defer_body[defer_body.len - 1]) { |
| | 1844 | return error.ComptimeBreak; |
| | 1845 | } |
| 1843 | break :blk .void_value; | 1846 | break :blk .void_value; |
| 1844 | }, | 1847 | }, |
| 1845 | }; | 1848 | }; |
| ... | @@ -1847,17 +1850,15 @@ fn analyzeBodyInner( | ... | @@ -1847,17 +1850,15 @@ fn analyzeBodyInner( |
| 1847 | // We're going to assume that the body itself is noreturn, so let's ensure that now | 1850 | // We're going to assume that the body itself is noreturn, so let's ensure that now |
| 1848 | assert(block.instructions.items.len > 0); | 1851 | assert(block.instructions.items.len > 0); |
| 1849 | assert(sema.isNoReturn(block.instructions.items[block.instructions.items.len - 1].toRef())); | 1852 | assert(sema.isNoReturn(block.instructions.items[block.instructions.items.len - 1].toRef())); |
| 1850 | break always_noreturn; | 1853 | break; |
| 1851 | } | 1854 | } |
| 1852 | map.putAssumeCapacity(inst, air_inst); | 1855 | map.putAssumeCapacity(inst, air_inst); |
| 1853 | i += 1; | 1856 | i += 1; |
| 1854 | }; | 1857 | } |
| 1855 | | 1858 | |
| 1856 | // We may have overwritten the capture scope due to a `repeat` instruction where | 1859 | // We may have overwritten the capture scope due to a `repeat` instruction where |
| 1857 | // the body had a capture; restore it now. | 1860 | // the body had a capture; restore it now. |
| 1858 | block.wip_capture_scope = parent_capture_scope; | 1861 | block.wip_capture_scope = parent_capture_scope; |
| 1859 | | | |
| 1860 | return result; | | |
| 1861 | } | 1862 | } |
| 1862 | | 1863 | |
| 1863 | pub fn resolveInstAllowNone(sema: *Sema, zir_ref: Zir.Inst.Ref) !Air.Inst.Ref { | 1864 | pub fn resolveInstAllowNone(sema: *Sema, zir_ref: Zir.Inst.Ref) !Air.Inst.Ref { |
| ... | @@ -1894,7 +1895,7 @@ fn resolveConstBool( | ... | @@ -1894,7 +1895,7 @@ fn resolveConstBool( |
| 1894 | return val.toBool(); | 1895 | return val.toBool(); |
| 1895 | } | 1896 | } |
| 1896 | | 1897 | |
| 1897 | pub fn resolveConstString( | 1898 | fn resolveConstString( |
| 1898 | sema: *Sema, | 1899 | sema: *Sema, |
| 1899 | block: *Block, | 1900 | block: *Block, |
| 1900 | src: LazySrcLoc, | 1901 | src: LazySrcLoc, |
| ... | @@ -1902,6 +1903,16 @@ pub fn resolveConstString( | ... | @@ -1902,6 +1903,16 @@ pub fn resolveConstString( |
| 1902 | reason: NeededComptimeReason, | 1903 | reason: NeededComptimeReason, |
| 1903 | ) ![]u8 { | 1904 | ) ![]u8 { |
| 1904 | const air_inst = try sema.resolveInst(zir_ref); | 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 | const wanted_type = Type.slice_const_u8; | 1916 | const wanted_type = Type.slice_const_u8; |
| 1906 | const coerced_inst = try sema.coerce(block, wanted_type, air_inst, src); | 1917 | const coerced_inst = try sema.coerce(block, wanted_type, air_inst, src); |
| 1907 | const val = try sema.resolveConstDefinedValue(block, src, coerced_inst, reason); | 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,9 +2204,8 @@ fn resolveValueAllowVariables(sema: *Sema, inst: Air.Inst.Ref) CompileError!?Val |
| 2193 | return val; | 2204 | return val; |
| 2194 | } | 2205 | } |
| 2195 | | 2206 | |
| 2196 | /// Returns a compile error if the value has tag `variable`. See `resolveInstValue` for | 2207 | /// Returns a compile error if the value has tag `variable`. |
| 2197 | /// a function that does not. | 2208 | fn resolveInstConst( |
| 2198 | pub fn resolveInstConst( | | |
| 2199 | sema: *Sema, | 2209 | sema: *Sema, |
| 2200 | block: *Block, | 2210 | block: *Block, |
| 2201 | src: LazySrcLoc, | 2211 | src: LazySrcLoc, |
| ... | @@ -2211,15 +2221,13 @@ pub fn resolveInstConst( | ... | @@ -2211,15 +2221,13 @@ pub fn resolveInstConst( |
| 2211 | } | 2221 | } |
| 2212 | | 2222 | |
| 2213 | /// Value Tag may be `undef` or `variable`. | 2223 | /// Value Tag may be `undef` or `variable`. |
| 2214 | /// See `resolveInstConst` for an alternative. | 2224 | pub fn resolveConstValueAllowVariables( |
| 2215 | pub fn resolveInstValueAllowVariables( | | |
| 2216 | sema: *Sema, | 2225 | sema: *Sema, |
| 2217 | block: *Block, | 2226 | block: *Block, |
| 2218 | src: LazySrcLoc, | 2227 | src: LazySrcLoc, |
| 2219 | zir_ref: Zir.Inst.Ref, | 2228 | air_ref: Air.Inst.Ref, |
| 2220 | reason: NeededComptimeReason, | 2229 | reason: NeededComptimeReason, |
| 2221 | ) CompileError!TypedValue { | 2230 | ) CompileError!TypedValue { |
| 2222 | const air_ref = try sema.resolveInst(zir_ref); | | |
| 2223 | const val = try sema.resolveValueAllowVariables(air_ref) orelse { | 2231 | const val = try sema.resolveValueAllowVariables(air_ref) orelse { |
| 2224 | return sema.failWithNeededComptime(block, src, reason); | 2232 | return sema.failWithNeededComptime(block, src, reason); |
| 2225 | }; | 2233 | }; |
| ... | @@ -2616,7 +2624,7 @@ fn reparentOwnedErrorMsg( | ... | @@ -2616,7 +2624,7 @@ fn reparentOwnedErrorMsg( |
| 2616 | | 2624 | |
| 2617 | const align_ty = Type.u29; | 2625 | const align_ty = Type.u29; |
| 2618 | | 2626 | |
| 2619 | fn analyzeAsAlign( | 2627 | pub fn analyzeAsAlign( |
| 2620 | sema: *Sema, | 2628 | sema: *Sema, |
| 2621 | block: *Block, | 2629 | block: *Block, |
| 2622 | src: LazySrcLoc, | 2630 | src: LazySrcLoc, |
| ... | @@ -2654,7 +2662,7 @@ fn validateAlignAllowZero( | ... | @@ -2654,7 +2662,7 @@ fn validateAlignAllowZero( |
| 2654 | return Alignment.fromNonzeroByteUnits(alignment); | 2662 | return Alignment.fromNonzeroByteUnits(alignment); |
| 2655 | } | 2663 | } |
| 2656 | | 2664 | |
| 2657 | pub fn resolveAlign( | 2665 | fn resolveAlign( |
| 2658 | sema: *Sema, | 2666 | sema: *Sema, |
| 2659 | block: *Block, | 2667 | block: *Block, |
| 2660 | src: LazySrcLoc, | 2668 | src: LazySrcLoc, |
| ... | @@ -3054,7 +3062,7 @@ fn zirEnumDecl( | ... | @@ -3054,7 +3062,7 @@ fn zirEnumDecl( |
| 3054 | defer enum_block.instructions.deinit(sema.gpa); | 3062 | defer enum_block.instructions.deinit(sema.gpa); |
| 3055 | | 3063 | |
| 3056 | if (body.len != 0) { | 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 | if (tag_type_ref != .none) { | 3068 | if (tag_type_ref != .none) { |
| ... | @@ -5597,7 +5605,7 @@ fn zirFloat128(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -5597,7 +5605,7 @@ fn zirFloat128(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 5597 | return Air.internedToRef((try sema.mod.floatValue(Type.comptime_float, number)).toIntern()); | 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 | const tracy = trace(@src()); | 5609 | const tracy = trace(@src()); |
| 5602 | defer tracy.end(); | 5610 | defer tracy.end(); |
| 5603 | | 5611 | |
| ... | @@ -5650,7 +5658,7 @@ fn zirCompileLog( | ... | @@ -5650,7 +5658,7 @@ fn zirCompileLog( |
| 5650 | return .void_value; | 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 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; | 5662 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; |
| 5655 | const src = inst_data.src(); | 5663 | const src = inst_data.src(); |
| 5656 | const msg_inst = try sema.resolveInst(inst_data.operand); | 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,16 +5671,14 @@ fn zirPanic(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Zir.I |
| 5663 | return sema.fail(block, src, "encountered @panic at comptime", .{}); | 5671 | return sema.fail(block, src, "encountered @panic at comptime", .{}); |
| 5664 | } | 5672 | } |
| 5665 | try sema.panicWithMsg(block, src, coerced_msg, .@"@panic"); | 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 | const src_node = sema.code.instructions.items(.data)[@intFromEnum(inst)].node; | 5677 | const src_node = sema.code.instructions.items(.data)[@intFromEnum(inst)].node; |
| 5671 | const src = LazySrcLoc.nodeOffset(src_node); | 5678 | const src = LazySrcLoc.nodeOffset(src_node); |
| 5672 | if (block.is_comptime) | 5679 | if (block.is_comptime) |
| 5673 | return sema.fail(block, src, "encountered @trap at comptime", .{}); | 5680 | return sema.fail(block, src, "encountered @trap at comptime", .{}); |
| 5674 | _ = try block.addNoOp(.trap); | 5681 | _ = try block.addNoOp(.trap); |
| 5675 | return always_noreturn; | | |
| 5676 | } | 5682 | } |
| 5677 | | 5683 | |
| 5678 | fn zirLoop(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 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,7 +5732,8 @@ fn zirLoop(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError |
| 5726 | var loop_block = child_block.makeSubBlock(); | 5732 | var loop_block = child_block.makeSubBlock(); |
| 5727 | defer loop_block.instructions.deinit(gpa); | 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 | const loop_block_len = loop_block.instructions.items.len; | 5738 | const loop_block_len = loop_block.instructions.items.len; |
| 5732 | if (loop_block_len > 0 and sema.typeOf(loop_block.instructions.items[loop_block_len - 1].toRef()).isNoReturn(mod)) { | 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,7 +5749,7 @@ fn zirLoop(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError |
| 5742 | ); | 5749 | ); |
| 5743 | sema.air_extra.appendSliceAssumeCapacity(@ptrCast(loop_block.instructions.items)); | 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 | fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 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,8 +5792,7 @@ fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileEr |
| 5785 | }; | 5792 | }; |
| 5786 | defer child_block.instructions.deinit(gpa); | 5793 | defer child_block.instructions.deinit(gpa); |
| 5787 | | 5794 | |
| 5788 | // Ignore the result, all the relevant operations have written to c_import_buf already. | 5795 | _ = try sema.analyzeInlineBody(&child_block, body, inst); |
| 5789 | _ = try sema.analyzeBodyBreak(&child_block, body); | | |
| 5790 | | 5796 | |
| 5791 | var c_import_res = comp.cImport(c_import_buf.items, parent_block.ownerModule()) catch |err| | 5797 | var c_import_res = comp.cImport(c_import_buf.items, parent_block.ownerModule()) catch |err| |
| 5792 | return sema.fail(&child_block, src, "C import failed: {s}", .{@errorName(err)}); | 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,6 +5922,9 @@ fn zirBlock(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index, force_compt |
| 5916 | return sema.resolveBlockBody(parent_block, src, &child_block, body, inst, &label.merges); | 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 | fn resolveBlockBody( | 5928 | fn resolveBlockBody( |
| 5920 | sema: *Sema, | 5929 | sema: *Sema, |
| 5921 | parent_block: *Block, | 5930 | parent_block: *Block, |
| ... | @@ -5928,12 +5937,12 @@ fn resolveBlockBody( | ... | @@ -5928,12 +5937,12 @@ fn resolveBlockBody( |
| 5928 | merges: *Block.Merges, | 5937 | merges: *Block.Merges, |
| 5929 | ) CompileError!Air.Inst.Ref { | 5938 | ) CompileError!Air.Inst.Ref { |
| 5930 | if (child_block.is_comptime) { | 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 | } else { | 5941 | } else { |
| 5933 | var need_debug_scope = false; | 5942 | var need_debug_scope = false; |
| 5934 | child_block.need_debug_scope = &need_debug_scope; | 5943 | child_block.need_debug_scope = &need_debug_scope; |
| 5935 | if (sema.analyzeBodyInner(child_block, body)) |_| { | 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 | } else |err| switch (err) { | 5946 | } else |err| switch (err) { |
| 5938 | error.ComptimeBreak => { | 5947 | error.ComptimeBreak => { |
| 5939 | // Comptime control flow is happening, however child_block may still contain | 5948 | // Comptime control flow is happening, however child_block may still contain |
| ... | @@ -5970,7 +5979,12 @@ fn resolveBlockBody( | ... | @@ -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 | sema: *Sema, | 5988 | sema: *Sema, |
| 5975 | parent_block: *Block, | 5989 | parent_block: *Block, |
| 5976 | src: LazySrcLoc, | 5990 | src: LazySrcLoc, |
| ... | @@ -6360,7 +6374,7 @@ fn zirFence(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) Co | ... | @@ -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 | const tracy = trace(@src()); | 6378 | const tracy = trace(@src()); |
| 6365 | defer tracy.end(); | 6379 | defer tracy.end(); |
| 6366 | | 6380 | |
| ... | @@ -6386,7 +6400,7 @@ fn zirBreak(sema: *Sema, start_block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -6386,7 +6400,7 @@ fn zirBreak(sema: *Sema, start_block: *Block, inst: Zir.Inst.Index) CompileError |
| 6386 | block.runtime_cond = start_block.runtime_cond orelse start_block.runtime_loop; | 6400 | block.runtime_cond = start_block.runtime_cond orelse start_block.runtime_loop; |
| 6387 | block.runtime_loop = start_block.runtime_loop; | 6401 | block.runtime_loop = start_block.runtime_loop; |
| 6388 | } | 6402 | } |
| 6389 | return inst; | 6403 | return; |
| 6390 | } | 6404 | } |
| 6391 | } | 6405 | } |
| 6392 | block = block.parent.?; | 6406 | block = block.parent.?; |
| ... | @@ -7096,7 +7110,7 @@ const CallArgsInfo = union(enum) { | ... | @@ -7096,7 +7110,7 @@ const CallArgsInfo = union(enum) { |
| 7096 | // Give the arg its result type | 7110 | // Give the arg its result type |
| 7097 | sema.inst_map.putAssumeCapacity(zir_call.call_inst, Air.internedToRef(param_ty.toIntern())); | 7111 | sema.inst_map.putAssumeCapacity(zir_call.call_inst, Air.internedToRef(param_ty.toIntern())); |
| 7098 | // Resolve the arg! | 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 | if (sema.typeOf(uncoerced_arg).zigTypeTag(mod) == .NoReturn) { | 7115 | if (sema.typeOf(uncoerced_arg).zigTypeTag(mod) == .NoReturn) { |
| 7102 | // This terminates resolution of arguments. The caller should | 7116 | // This terminates resolution of arguments. The caller should |
| ... | @@ -7539,7 +7553,7 @@ fn analyzeCall( | ... | @@ -7539,7 +7553,7 @@ fn analyzeCall( |
| 7539 | // each of the parameters, resolving the return type and providing it to the child | 7553 | // each of the parameters, resolving the return type and providing it to the child |
| 7540 | // `Sema` so that it can be used for the `ret_ptr` instruction. | 7554 | // `Sema` so that it can be used for the `ret_ptr` instruction. |
| 7541 | const ret_ty_inst = if (fn_info.ret_ty_body.len != 0) | 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 | else | 7557 | else |
| 7544 | try sema.resolveInst(fn_info.ret_ty_ref); | 7558 | try sema.resolveInst(fn_info.ret_ty_ref); |
| 7545 | const ret_ty_src: LazySrcLoc = .{ .node_offset_fn_type_ret_ty = 0 }; | 7559 | const ret_ty_src: LazySrcLoc = .{ .node_offset_fn_type_ret_ty = 0 }; |
| ... | @@ -7608,11 +7622,11 @@ fn analyzeCall( | ... | @@ -7608,11 +7622,11 @@ fn analyzeCall( |
| 7608 | } | 7622 | } |
| 7609 | | 7623 | |
| 7610 | const result = result: { | 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 | error.ComptimeReturn => break :result inlining.comptime_result, | 7626 | error.ComptimeReturn => break :result inlining.comptime_result, |
| 7613 | else => |e| return e, | 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 | if (!is_comptime_call and !block.is_typeof and | 7632 | if (!is_comptime_call and !block.is_typeof and |
| ... | @@ -7791,7 +7805,7 @@ fn analyzeInlineCallArg( | ... | @@ -7791,7 +7805,7 @@ fn analyzeInlineCallArg( |
| 7791 | const param_ty = param_ty: { | 7805 | const param_ty = param_ty: { |
| 7792 | const raw_param_ty = func_ty_info.param_types.get(ip)[arg_i.*]; | 7806 | const raw_param_ty = func_ty_info.param_types.get(ip)[arg_i.*]; |
| 7793 | if (raw_param_ty != .generic_poison_type) break :param_ty raw_param_ty; | 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 | const param_ty = try ics.callee().analyzeAsType(param_block, param_src, param_ty_inst); | 7809 | const param_ty = try ics.callee().analyzeAsType(param_block, param_src, param_ty_inst); |
| 7796 | break :param_ty param_ty.toIntern(); | 7810 | break :param_ty param_ty.toIntern(); |
| 7797 | }; | 7811 | }; |
| ... | @@ -8026,7 +8040,7 @@ fn instantiateGenericCall( | ... | @@ -8026,7 +8040,7 @@ fn instantiateGenericCall( |
| 8026 | child_sema.generic_call_decl = prev_generic_call_decl; | 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 | break :param_ty try child_sema.analyzeAsType(&child_block, param_data.src(), param_ty_inst); | 8044 | break :param_ty try child_sema.analyzeAsType(&child_block, param_data.src(), param_ty_inst); |
| 8031 | }, | 8045 | }, |
| 8032 | else => unreachable, | 8046 | else => unreachable, |
| ... | @@ -8118,7 +8132,7 @@ fn instantiateGenericCall( | ... | @@ -8118,7 +8132,7 @@ fn instantiateGenericCall( |
| 8118 | | 8132 | |
| 8119 | // We've already handled parameters, so don't resolve the whole body. Instead, just | 8133 | // We've already handled parameters, so don't resolve the whole body. Instead, just |
| 8120 | // do the instructions after the params (i.e. the func itself). | 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 | const callee_index = (child_sema.resolveConstDefinedValue(&child_block, .unneeded, new_func_inst, undefined) catch unreachable).toIntern(); | 8136 | const callee_index = (child_sema.resolveConstDefinedValue(&child_block, .unneeded, new_func_inst, undefined) catch unreachable).toIntern(); |
| 8123 | | 8137 | |
| 8124 | const callee = mod.funcInfo(callee_index); | 8138 | const callee = mod.funcInfo(callee_index); |
| ... | @@ -9176,7 +9190,7 @@ fn resolveGenericBody( | ... | @@ -9176,7 +9190,7 @@ fn resolveGenericBody( |
| 9176 | sema.generic_call_decl = prev_generic_call_decl; | 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 | const result = sema.coerce(block, dest_ty, uncasted, src) catch |err| break :err err; | 9194 | const result = sema.coerce(block, dest_ty, uncasted, src) catch |err| break :err err; |
| 9181 | const val = sema.resolveConstDefinedValue(block, src, result, reason) catch |err| break :err err; | 9195 | const val = sema.resolveConstDefinedValue(block, src, result, reason) catch |err| break :err err; |
| 9182 | return val; | 9196 | return val; |
| ... | @@ -9810,7 +9824,7 @@ fn zirParam( | ... | @@ -9810,7 +9824,7 @@ fn zirParam( |
| 9810 | sema.generic_call_decl = prev_generic_call_decl; | 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 | if (sema.analyzeAsType(block, src, param_ty_inst)) |param_ty| { | 9828 | if (sema.analyzeAsType(block, src, param_ty_inst)) |param_ty| { |
| 9815 | break :param_ty param_ty; | 9829 | break :param_ty param_ty; |
| 9816 | } else |err| break :err err; | 9830 | } else |err| break :err err; |
| ... | @@ -11494,6 +11508,7 @@ fn zirSwitchBlockErrUnion(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Comp | ... | @@ -11494,6 +11508,7 @@ fn zirSwitchBlockErrUnion(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Comp |
| 11494 | sub_block.runtime_loop = null; | 11508 | sub_block.runtime_loop = null; |
| 11495 | sub_block.runtime_cond = mod.declPtr(child_block.src_decl).toSrcLoc(main_operand_src, mod); | 11509 | sub_block.runtime_cond = mod.declPtr(child_block.src_decl).toSrcLoc(main_operand_src, mod); |
| 11496 | sub_block.runtime_index.increment(); | 11510 | sub_block.runtime_index.increment(); |
| | 11511 | sub_block.need_debug_scope = null; // this body is emitted regardless |
| 11497 | defer sub_block.instructions.deinit(gpa); | 11512 | defer sub_block.instructions.deinit(gpa); |
| 11498 | | 11513 | |
| 11499 | try sema.analyzeBodyRuntimeBreak(&sub_block, non_error_case.body); | 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,7 +11571,7 @@ fn zirSwitchBlockErrUnion(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Comp |
| 11556 | sema.air_extra.appendSliceAssumeCapacity(@ptrCast(true_instructions)); | 11571 | sema.air_extra.appendSliceAssumeCapacity(@ptrCast(true_instructions)); |
| 11557 | sema.air_extra.appendSliceAssumeCapacity(@ptrCast(sub_block.instructions.items)); | 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 | fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_ref: bool) CompileError!Air.Inst.Ref { | 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,7 +12193,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r |
| 12178 | false, | 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 | const SpecialProng = struct { | 12199 | const SpecialProng = struct { |
| ... | @@ -12229,6 +12244,7 @@ fn analyzeSwitchRuntimeBlock( | ... | @@ -12229,6 +12244,7 @@ fn analyzeSwitchRuntimeBlock( |
| 12229 | case_block.runtime_loop = null; | 12244 | case_block.runtime_loop = null; |
| 12230 | case_block.runtime_cond = mod.declPtr(child_block.src_decl).toSrcLoc(operand_src, mod); | 12245 | case_block.runtime_cond = mod.declPtr(child_block.src_decl).toSrcLoc(operand_src, mod); |
| 12231 | case_block.runtime_index.increment(); | 12246 | case_block.runtime_index.increment(); |
| | 12247 | case_block.need_debug_scope = null; // this body is emitted regardless |
| 12232 | defer case_block.instructions.deinit(gpa); | 12248 | defer case_block.instructions.deinit(gpa); |
| 12233 | | 12249 | |
| 12234 | var extra_index: usize = special.end; | 12250 | var extra_index: usize = special.end; |
| ... | @@ -18602,7 +18618,7 @@ fn zirTypeofBuiltin(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr | ... | @@ -18602,7 +18618,7 @@ fn zirTypeofBuiltin(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr |
| 18602 | }; | 18618 | }; |
| 18603 | defer child_block.instructions.deinit(sema.gpa); | 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 | const operand_ty = sema.typeOf(operand); | 18622 | const operand_ty = sema.typeOf(operand); |
| 18607 | if (operand_ty.isGenericPoison()) return error.GenericPoison; | 18623 | if (operand_ty.isGenericPoison()) return error.GenericPoison; |
| 18608 | return Air.internedToRef(operand_ty.toIntern()); | 18624 | return Air.internedToRef(operand_ty.toIntern()); |
| ... | @@ -18657,6 +18673,7 @@ fn zirTypeofPeer( | ... | @@ -18657,6 +18673,7 @@ fn zirTypeofPeer( |
| 18657 | sema: *Sema, | 18673 | sema: *Sema, |
| 18658 | block: *Block, | 18674 | block: *Block, |
| 18659 | extended: Zir.Inst.Extended.InstData, | 18675 | extended: Zir.Inst.Extended.InstData, |
| | 18676 | inst: Zir.Inst.Index, |
| 18660 | ) CompileError!Air.Inst.Ref { | 18677 | ) CompileError!Air.Inst.Ref { |
| 18661 | const tracy = trace(@src()); | 18678 | const tracy = trace(@src()); |
| 18662 | defer tracy.end(); | 18679 | defer tracy.end(); |
| ... | @@ -18681,7 +18698,7 @@ fn zirTypeofPeer( | ... | @@ -18681,7 +18698,7 @@ fn zirTypeofPeer( |
| 18681 | }; | 18698 | }; |
| 18682 | defer child_block.instructions.deinit(sema.gpa); | 18699 | defer child_block.instructions.deinit(sema.gpa); |
| 18683 | // Ignore the result, we only care about the instructions in `args`. | 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 | const args = sema.code.refSlice(extra.end, extended.small); | 18703 | const args = sema.code.refSlice(extra.end, extended.small); |
| 18687 | | 18704 | |
| ... | @@ -18748,7 +18765,7 @@ fn zirBoolBr( | ... | @@ -18748,7 +18765,7 @@ fn zirBoolBr( |
| 18748 | // comptime-known left-hand side. No need for a block here; the result | 18765 | // comptime-known left-hand side. No need for a block here; the result |
| 18749 | // is simply the rhs expression. Here we rely on there only being 1 | 18766 | // is simply the rhs expression. Here we rely on there only being 1 |
| 18750 | // break instruction (`break_inline`). | 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 | if (sema.typeOf(rhs_result).isNoReturn(mod)) { | 18769 | if (sema.typeOf(rhs_result).isNoReturn(mod)) { |
| 18753 | return rhs_result; | 18770 | return rhs_result; |
| 18754 | } | 18771 | } |
| ... | @@ -18782,7 +18799,7 @@ fn zirBoolBr( | ... | @@ -18782,7 +18799,7 @@ fn zirBoolBr( |
| 18782 | const lhs_result: Air.Inst.Ref = if (is_bool_or) .bool_true else .bool_false; | 18799 | const lhs_result: Air.Inst.Ref = if (is_bool_or) .bool_true else .bool_false; |
| 18783 | _ = try lhs_block.addBr(block_inst, lhs_result); | 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 | const rhs_noret = sema.typeOf(rhs_result).isNoReturn(mod); | 18803 | const rhs_noret = sema.typeOf(rhs_result).isNoReturn(mod); |
| 18787 | const coerced_rhs_result = if (!rhs_noret) rhs: { | 18804 | const coerced_rhs_result = if (!rhs_noret) rhs: { |
| 18788 | const coerced_result = try sema.coerce(rhs_block, Type.bool, rhs_result, rhs_src); | 18805 | const coerced_result = try sema.coerce(rhs_block, Type.bool, rhs_result, rhs_src); |
| ... | @@ -18933,7 +18950,7 @@ fn zirCondbr( | ... | @@ -18933,7 +18950,7 @@ fn zirCondbr( |
| 18933 | sema: *Sema, | 18950 | sema: *Sema, |
| 18934 | parent_block: *Block, | 18951 | parent_block: *Block, |
| 18935 | inst: Zir.Inst.Index, | 18952 | inst: Zir.Inst.Index, |
| 18936 | ) CompileError!Zir.Inst.Index { | 18953 | ) CompileError!void { |
| 18937 | const tracy = trace(@src()); | 18954 | const tracy = trace(@src()); |
| 18938 | defer tracy.end(); | 18955 | defer tracy.end(); |
| 18939 | | 18956 | |
| ... | @@ -18952,8 +18969,7 @@ fn zirCondbr( | ... | @@ -18952,8 +18969,7 @@ fn zirCondbr( |
| 18952 | const body = if (cond_val.toBool()) then_body else else_body; | 18969 | const body = if (cond_val.toBool()) then_body else else_body; |
| 18953 | | 18970 | |
| 18954 | try sema.maybeErrorUnwrapCondbr(parent_block, body, extra.data.condition, cond_src); | 18971 | try sema.maybeErrorUnwrapCondbr(parent_block, body, extra.data.condition, cond_src); |
| 18955 | // We use `analyzeBodyInner` since we want to propagate any possible | 18972 | // We use `analyzeBodyInner` since we want to propagate any comptime control flow to the caller. |
| 18956 | // `error.ComptimeBreak` to the caller. | | |
| 18957 | return sema.analyzeBodyInner(parent_block, body); | 18973 | return sema.analyzeBodyInner(parent_block, body); |
| 18958 | } | 18974 | } |
| 18959 | | 18975 | |
| ... | @@ -18965,6 +18981,7 @@ fn zirCondbr( | ... | @@ -18965,6 +18981,7 @@ fn zirCondbr( |
| 18965 | sub_block.runtime_loop = null; | 18981 | sub_block.runtime_loop = null; |
| 18966 | sub_block.runtime_cond = mod.declPtr(parent_block.src_decl).toSrcLoc(cond_src, mod); | 18982 | sub_block.runtime_cond = mod.declPtr(parent_block.src_decl).toSrcLoc(cond_src, mod); |
| 18967 | sub_block.runtime_index.increment(); | 18983 | sub_block.runtime_index.increment(); |
| | 18984 | sub_block.need_debug_scope = null; // this body is emitted regardless |
| 18968 | defer sub_block.instructions.deinit(gpa); | 18985 | defer sub_block.instructions.deinit(gpa); |
| 18969 | | 18986 | |
| 18970 | try sema.analyzeBodyRuntimeBreak(&sub_block, then_body); | 18987 | try sema.analyzeBodyRuntimeBreak(&sub_block, then_body); |
| ... | @@ -19002,7 +19019,6 @@ fn zirCondbr( | ... | @@ -19002,7 +19019,6 @@ fn zirCondbr( |
| 19002 | }); | 19019 | }); |
| 19003 | sema.air_extra.appendSliceAssumeCapacity(@ptrCast(true_instructions)); | 19020 | sema.air_extra.appendSliceAssumeCapacity(@ptrCast(true_instructions)); |
| 19004 | sema.air_extra.appendSliceAssumeCapacity(@ptrCast(sub_block.instructions.items)); | 19021 | sema.air_extra.appendSliceAssumeCapacity(@ptrCast(sub_block.instructions.items)); |
| 19005 | return always_noreturn; | | |
| 19006 | } | 19022 | } |
| 19007 | | 19023 | |
| 19008 | fn zirTry(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 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,14 +19043,15 @@ fn zirTry(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError! |
| 19027 | } | 19043 | } |
| 19028 | // We can analyze the body directly in the parent block because we know there are | 19044 | // We can analyze the body directly in the parent block because we know there are |
| 19029 | // no breaks from the body possible, and that the body is noreturn. | 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 | var sub_block = parent_block.makeSubBlock(); | 19050 | var sub_block = parent_block.makeSubBlock(); |
| 19034 | defer sub_block.instructions.deinit(sema.gpa); | 19051 | defer sub_block.instructions.deinit(sema.gpa); |
| 19035 | | 19052 | |
| 19036 | // This body is guaranteed to end with noreturn and has no breaks. | 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 | try sema.air_extra.ensureUnusedCapacity(sema.gpa, @typeInfo(Air.Try).Struct.fields.len + | 19056 | try sema.air_extra.ensureUnusedCapacity(sema.gpa, @typeInfo(Air.Try).Struct.fields.len + |
| 19040 | sub_block.instructions.items.len); | 19057 | sub_block.instructions.items.len); |
| ... | @@ -19074,14 +19091,15 @@ fn zirTryPtr(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileErr | ... | @@ -19074,14 +19091,15 @@ fn zirTryPtr(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileErr |
| 19074 | } | 19091 | } |
| 19075 | // We can analyze the body directly in the parent block because we know there are | 19092 | // We can analyze the body directly in the parent block because we know there are |
| 19076 | // no breaks from the body possible, and that the body is noreturn. | 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 | var sub_block = parent_block.makeSubBlock(); | 19098 | var sub_block = parent_block.makeSubBlock(); |
| 19081 | defer sub_block.instructions.deinit(sema.gpa); | 19099 | defer sub_block.instructions.deinit(sema.gpa); |
| 19082 | | 19100 | |
| 19083 | // This body is guaranteed to end with noreturn and has no breaks. | 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 | const operand_ty = sema.typeOf(operand); | 19104 | const operand_ty = sema.typeOf(operand); |
| 19087 | const ptr_info = operand_ty.ptrInfo(mod); | 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,13 +19174,13 @@ fn ensurePostHoc(sema: *Sema, block: *Block, dest_block: Zir.Inst.Index) !*Label |
| 19156 | return labeled_block; | 19174 | return labeled_block; |
| 19157 | } | 19175 | } |
| 19158 | | 19176 | |
| 19159 | // A `break` statement is inside a runtime condition, but trying to | 19177 | /// 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 | 19178 | /// break from an inline loop. In such case we must convert it to |
| 19161 | // a runtime break. | 19179 | /// a runtime break. |
| 19162 | fn addRuntimeBreak(sema: *Sema, child_block: *Block, break_data: BreakData) !void { | 19180 | fn addRuntimeBreak(sema: *Sema, child_block: *Block, block_inst: Zir.Inst.Index, break_operand: Zir.Inst.Ref) !void { |
| 19163 | const labeled_block = try sema.ensurePostHoc(child_block, break_data.block_inst); | 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 | const br_ref = try child_block.addBr(labeled_block.label.merges.block_inst, operand); | 19184 | const br_ref = try child_block.addBr(labeled_block.label.merges.block_inst, operand); |
| 19167 | | 19185 | |
| 19168 | try labeled_block.label.merges.results.append(sema.gpa, operand); | 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,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 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].@"unreachable"; | 19198 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].@"unreachable"; |
| 19181 | const src = inst_data.src(); | 19199 | const src = inst_data.src(); |
| 19182 | | 19200 | |
| ... | @@ -19193,14 +19211,13 @@ fn zirUnreachable(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -19193,14 +19211,13 @@ fn zirUnreachable(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 19193 | }, | 19211 | }, |
| 19194 | else => |e| return e, | 19212 | else => |e| return e, |
| 19195 | }; | 19213 | }; |
| 19196 | return always_noreturn; | | |
| 19197 | } | 19214 | } |
| 19198 | | 19215 | |
| 19199 | fn zirRetErrValue( | 19216 | fn zirRetErrValue( |
| 19200 | sema: *Sema, | 19217 | sema: *Sema, |
| 19201 | block: *Block, | 19218 | block: *Block, |
| 19202 | inst: Zir.Inst.Index, | 19219 | inst: Zir.Inst.Index, |
| 19203 | ) CompileError!Zir.Inst.Index { | 19220 | ) CompileError!void { |
| 19204 | const mod = sema.mod; | 19221 | const mod = sema.mod; |
| 19205 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].str_tok; | 19222 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].str_tok; |
| 19206 | const err_name = try mod.intern_pool.getOrPutString(sema.gpa, inst_data.get(sema.code)); | 19223 | const err_name = try mod.intern_pool.getOrPutString(sema.gpa, inst_data.get(sema.code)); |
| ... | @@ -19219,7 +19236,7 @@ fn zirRetImplicit( | ... | @@ -19219,7 +19236,7 @@ fn zirRetImplicit( |
| 19219 | sema: *Sema, | 19236 | sema: *Sema, |
| 19220 | block: *Block, | 19237 | block: *Block, |
| 19221 | inst: Zir.Inst.Index, | 19238 | inst: Zir.Inst.Index, |
| 19222 | ) CompileError!Zir.Inst.Index { | 19239 | ) CompileError!void { |
| 19223 | const tracy = trace(@src()); | 19240 | const tracy = trace(@src()); |
| 19224 | defer tracy.end(); | 19241 | defer tracy.end(); |
| 19225 | | 19242 | |
| ... | @@ -19234,7 +19251,7 @@ fn zirRetImplicit( | ... | @@ -19234,7 +19251,7 @@ fn zirRetImplicit( |
| 19234 | } else { | 19251 | } else { |
| 19235 | try block.addUnreachable(r_brace_src, false); | 19252 | try block.addUnreachable(r_brace_src, false); |
| 19236 | } | 19253 | } |
| 19237 | return always_noreturn; | 19254 | return; |
| 19238 | } | 19255 | } |
| 19239 | | 19256 | |
| 19240 | const operand = try sema.resolveInst(inst_data.operand); | 19257 | const operand = try sema.resolveInst(inst_data.operand); |
| ... | @@ -19265,7 +19282,7 @@ fn zirRetImplicit( | ... | @@ -19265,7 +19282,7 @@ fn zirRetImplicit( |
| 19265 | return sema.analyzeRet(block, operand, r_brace_src, r_brace_src); | 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 | const tracy = trace(@src()); | 19286 | const tracy = trace(@src()); |
| 19270 | defer tracy.end(); | 19287 | defer tracy.end(); |
| 19271 | | 19288 | |
| ... | @@ -19276,7 +19293,7 @@ fn zirRetNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Zir | ... | @@ -19276,7 +19293,7 @@ fn zirRetNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Zir |
| 19276 | return sema.analyzeRet(block, operand, src, .{ .node_offset_return_operand = inst_data.src_node }); | 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 | const tracy = trace(@src()); | 19297 | const tracy = trace(@src()); |
| 19281 | defer tracy.end(); | 19298 | defer tracy.end(); |
| 19282 | | 19299 | |
| ... | @@ -19295,7 +19312,6 @@ fn zirRetLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Zir | ... | @@ -19295,7 +19312,6 @@ fn zirRetLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Zir |
| 19295 | } | 19312 | } |
| 19296 | | 19313 | |
| 19297 | _ = try block.addUnOp(.ret_load, ret_ptr); | 19314 | _ = try block.addUnOp(.ret_load, ret_ptr); |
| 19298 | return always_noreturn; | | |
| 19299 | } | 19315 | } |
| 19300 | | 19316 | |
| 19301 | fn retWithErrTracing( | 19317 | fn retWithErrTracing( |
| ... | @@ -19305,12 +19321,12 @@ fn retWithErrTracing( | ... | @@ -19305,12 +19321,12 @@ fn retWithErrTracing( |
| 19305 | is_non_err: Air.Inst.Ref, | 19321 | is_non_err: Air.Inst.Ref, |
| 19306 | ret_tag: Air.Inst.Tag, | 19322 | ret_tag: Air.Inst.Tag, |
| 19307 | operand: Air.Inst.Ref, | 19323 | operand: Air.Inst.Ref, |
| 19308 | ) CompileError!Zir.Inst.Index { | 19324 | ) CompileError!void { |
| 19309 | const mod = sema.mod; | 19325 | const mod = sema.mod; |
| 19310 | const need_check = switch (is_non_err) { | 19326 | const need_check = switch (is_non_err) { |
| 19311 | .bool_true => { | 19327 | .bool_true => { |
| 19312 | _ = try block.addUnOp(ret_tag, operand); | 19328 | _ = try block.addUnOp(ret_tag, operand); |
| 19313 | return always_noreturn; | 19329 | return; |
| 19314 | }, | 19330 | }, |
| 19315 | .bool_false => false, | 19331 | .bool_false => false, |
| 19316 | else => true, | 19332 | else => true, |
| ... | @@ -19326,7 +19342,7 @@ fn retWithErrTracing( | ... | @@ -19326,7 +19342,7 @@ fn retWithErrTracing( |
| 19326 | if (!need_check) { | 19342 | if (!need_check) { |
| 19327 | try sema.callBuiltin(block, src, return_err_fn, .never_inline, &args, .@"error return"); | 19343 | try sema.callBuiltin(block, src, return_err_fn, .never_inline, &args, .@"error return"); |
| 19328 | _ = try block.addUnOp(ret_tag, operand); | 19344 | _ = try block.addUnOp(ret_tag, operand); |
| 19329 | return always_noreturn; | 19345 | return; |
| 19330 | } | 19346 | } |
| 19331 | | 19347 | |
| 19332 | var then_block = block.makeSubBlock(); | 19348 | var then_block = block.makeSubBlock(); |
| ... | @@ -19353,8 +19369,6 @@ fn retWithErrTracing( | ... | @@ -19353,8 +19369,6 @@ fn retWithErrTracing( |
| 19353 | .operand = is_non_err, | 19369 | .operand = is_non_err, |
| 19354 | .payload = cond_br_payload, | 19370 | .payload = cond_br_payload, |
| 19355 | } } }); | 19371 | } } }); |
| 19356 | | | |
| 19357 | return always_noreturn; | | |
| 19358 | } | 19372 | } |
| 19359 | | 19373 | |
| 19360 | fn wantErrorReturnTracing(sema: *Sema, fn_ret_ty: Type) bool { | 19374 | fn wantErrorReturnTracing(sema: *Sema, fn_ret_ty: Type) bool { |
| ... | @@ -19481,7 +19495,7 @@ fn analyzeRet( | ... | @@ -19481,7 +19495,7 @@ fn analyzeRet( |
| 19481 | uncasted_operand: Air.Inst.Ref, | 19495 | uncasted_operand: Air.Inst.Ref, |
| 19482 | src: LazySrcLoc, | 19496 | src: LazySrcLoc, |
| 19483 | operand_src: LazySrcLoc, | 19497 | operand_src: LazySrcLoc, |
| 19484 | ) CompileError!Zir.Inst.Index { | 19498 | ) CompileError!void { |
| 19485 | // Special case for returning an error to an inferred error set; we need to | 19499 | // Special case for returning an error to an inferred error set; we need to |
| 19486 | // add the error tag to the inferred error set of the in-scope function, so | 19500 | // add the error tag to the inferred error set of the in-scope function, so |
| 19487 | // that the coercion below works correctly. | 19501 | // that the coercion below works correctly. |
| ... | @@ -19513,7 +19527,7 @@ fn analyzeRet( | ... | @@ -19513,7 +19527,7 @@ fn analyzeRet( |
| 19513 | try inlining.merges.results.append(sema.gpa, operand); | 19527 | try inlining.merges.results.append(sema.gpa, operand); |
| 19514 | try inlining.merges.br_list.append(sema.gpa, br_inst.toIndex().?); | 19528 | try inlining.merges.br_list.append(sema.gpa, br_inst.toIndex().?); |
| 19515 | try inlining.merges.src_locs.append(sema.gpa, operand_src); | 19529 | try inlining.merges.src_locs.append(sema.gpa, operand_src); |
| 19516 | return always_noreturn; | 19530 | return; |
| 19517 | } else if (block.is_comptime) { | 19531 | } else if (block.is_comptime) { |
| 19518 | return sema.fail(block, src, "function called at runtime cannot return value at comptime", .{}); | 19532 | return sema.fail(block, src, "function called at runtime cannot return value at comptime", .{}); |
| 19519 | } else if (sema.func_is_naked) { | 19533 | } else if (sema.func_is_naked) { |
| ... | @@ -19538,8 +19552,6 @@ fn analyzeRet( | ... | @@ -19538,8 +19552,6 @@ fn analyzeRet( |
| 19538 | } | 19552 | } |
| 19539 | | 19553 | |
| 19540 | _ = try block.addUnOp(air_tag, operand); | 19554 | _ = try block.addUnOp(air_tag, operand); |
| 19541 | | | |
| 19542 | return always_noreturn; | | |
| 19543 | } | 19555 | } |
| 19544 | | 19556 | |
| 19545 | fn floatOpAllowed(tag: Zir.Inst.Tag) bool { | 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,7 +19628,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 19616 | const address_space: std.builtin.AddressSpace = if (inst_data.flags.has_addrspace) blk: { | 19628 | const address_space: std.builtin.AddressSpace = if (inst_data.flags.has_addrspace) blk: { |
| 19617 | const ref: Zir.Inst.Ref = @enumFromInt(sema.code.extra[extra_i]); | 19629 | const ref: Zir.Inst.Ref = @enumFromInt(sema.code.extra[extra_i]); |
| 19618 | extra_i += 1; | 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 | } else if (elem_ty.zigTypeTag(mod) == .Fn and target.cpu.arch == .avr) .flash else .generic; | 19632 | } else if (elem_ty.zigTypeTag(mod) == .Fn and target.cpu.arch == .avr) .flash else .generic; |
| 19621 | | 19633 | |
| 19622 | const bit_offset: u16 = if (inst_data.flags.has_bit_range) blk: { | 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,7 +35749,7 @@ fn semaBackingIntType(mod: *Module, struct_type: InternPool.Key.StructType) Comp |
| 35737 | break :blk try sema.resolveType(&block, backing_int_src, backing_int_ref); | 35749 | break :blk try sema.resolveType(&block, backing_int_src, backing_int_ref); |
| 35738 | } else { | 35750 | } else { |
| 35739 | const body = zir.bodySlice(extra_index, backing_int_body_len); | 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 | break :blk try sema.analyzeAsType(&block, backing_int_src, ty_ref); | 35753 | break :blk try sema.analyzeAsType(&block, backing_int_src, ty_ref); |
| 35742 | } | 35754 | } |
| 35743 | }; | 35755 | }; |
| ... | @@ -36618,7 +36630,7 @@ fn semaStructFields( | ... | @@ -36618,7 +36630,7 @@ fn semaStructFields( |
| 36618 | assert(zir_field.type_body_len != 0); | 36630 | assert(zir_field.type_body_len != 0); |
| 36619 | const body = zir.bodySlice(extra_index, zir_field.type_body_len); | 36631 | const body = zir.bodySlice(extra_index, zir_field.type_body_len); |
| 36620 | extra_index += body.len; | 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 | break :ty sema.analyzeAsType(&block_scope, .unneeded, ty_ref) catch |err| switch (err) { | 36634 | break :ty sema.analyzeAsType(&block_scope, .unneeded, ty_ref) catch |err| switch (err) { |
| 36623 | error.NeededSourceLocation => { | 36635 | error.NeededSourceLocation => { |
| 36624 | const ty_src = mod.fieldSrcLoc(decl_index, .{ | 36636 | const ty_src = mod.fieldSrcLoc(decl_index, .{ |
| ... | @@ -36704,7 +36716,7 @@ fn semaStructFields( | ... | @@ -36704,7 +36716,7 @@ fn semaStructFields( |
| 36704 | if (zir_field.align_body_len > 0) { | 36716 | if (zir_field.align_body_len > 0) { |
| 36705 | const body = zir.bodySlice(extra_index, zir_field.align_body_len); | 36717 | const body = zir.bodySlice(extra_index, zir_field.align_body_len); |
| 36706 | extra_index += body.len; | 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 | const field_align = sema.analyzeAsAlign(&block_scope, .unneeded, align_ref) catch |err| switch (err) { | 36720 | const field_align = sema.analyzeAsAlign(&block_scope, .unneeded, align_ref) catch |err| switch (err) { |
| 36709 | error.NeededSourceLocation => { | 36721 | error.NeededSourceLocation => { |
| 36710 | const align_src = mod.fieldSrcLoc(decl_index, .{ | 36722 | const align_src = mod.fieldSrcLoc(decl_index, .{ |
| ... | @@ -36854,7 +36866,7 @@ fn semaStructFieldInits( | ... | @@ -36854,7 +36866,7 @@ fn semaStructFieldInits( |
| 36854 | try sema.inst_map.ensureSpaceForInstructions(sema.gpa, &.{zir_index}); | 36866 | try sema.inst_map.ensureSpaceForInstructions(sema.gpa, &.{zir_index}); |
| 36855 | sema.inst_map.putAssumeCapacity(zir_index, type_ref); | 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 | const coerced = sema.coerce(&block_scope, field_ty, init, .unneeded) catch |err| switch (err) { | 36870 | const coerced = sema.coerce(&block_scope, field_ty, init, .unneeded) catch |err| switch (err) { |
| 36859 | error.NeededSourceLocation => { | 36871 | error.NeededSourceLocation => { |
| 36860 | const init_src = mod.fieldSrcLoc(decl_index, .{ | 36872 | const init_src = mod.fieldSrcLoc(decl_index, .{ |
| ... | @@ -36971,7 +36983,7 @@ fn semaUnionFields(mod: *Module, arena: Allocator, union_type: InternPool.Key.Un | ... | @@ -36971,7 +36983,7 @@ fn semaUnionFields(mod: *Module, arena: Allocator, union_type: InternPool.Key.Un |
| 36971 | defer assert(block_scope.instructions.items.len == 0); | 36983 | defer assert(block_scope.instructions.items.len == 0); |
| 36972 | | 36984 | |
| 36973 | if (body.len != 0) { | 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 | for (comptime_mutable_decls.items) |ct_decl_index| { | 36989 | for (comptime_mutable_decls.items) |ct_decl_index| { |
| ... | @@ -37914,15 +37926,25 @@ pub const AddressSpaceContext = enum { | ... | @@ -37914,15 +37926,25 @@ pub const AddressSpaceContext = enum { |
| 37914 | pointer, | 37926 | pointer, |
| 37915 | }; | 37927 | }; |
| 37916 | | 37928 | |
| 37917 | pub fn analyzeAddressSpace( | 37929 | fn resolveAddressSpace( |
| 37918 | sema: *Sema, | 37930 | sema: *Sema, |
| 37919 | block: *Block, | 37931 | block: *Block, |
| 37920 | src: LazySrcLoc, | 37932 | src: LazySrcLoc, |
| 37921 | zir_ref: Zir.Inst.Ref, | 37933 | zir_ref: Zir.Inst.Ref, |
| 37922 | ctx: AddressSpaceContext, | 37934 | ctx: AddressSpaceContext, |
| 37923 | ) !std.builtin.AddressSpace { | 37935 | ) !std.builtin.AddressSpace { |
| 37924 | const mod = sema.mod; | | |
| 37925 | const air_ref = try sema.resolveInst(zir_ref); | 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 | const coerced = try sema.coerce(block, Type.fromInterned(.address_space_type), air_ref, src); | 37948 | const coerced = try sema.coerce(block, Type.fromInterned(.address_space_type), air_ref, src); |
| 37927 | const addrspace_val = try sema.resolveConstDefinedValue(block, src, coerced, .{ | 37949 | const addrspace_val = try sema.resolveConstDefinedValue(block, src, coerced, .{ |
| 37928 | .needed_comptime_reason = "address space must be comptime-known", | 37950 | .needed_comptime_reason = "address space must be comptime-known", |