| author | |
| committer | |
| log | ccf670c2b04ebeb9db43eb9f5c47c6cf03e4b1d0 |
| tree | 3f7899bf6231500782af185ffe701ee66793e226 |
| parent | 602029bb2fb78048e46136784e717b57b8de8f2c |
Resolves: #705618 files changed, 234 insertions(+), 304 deletions(-)
lib/std/Build/Cache.zig+2-2| ... | ... | @@ -374,7 +374,7 @@ pub const Manifest = struct { |
| 374 | 374 | self.failed_file_index = null; |
| 375 | 375 | |
| 376 | 376 | const ext = ".txt"; |
| 377 | var manifest_file_path: [self.hex_digest.len + ext.len]u8 = undefined; | |
| 377 | var manifest_file_path: [hex_digest_len + ext.len]u8 = undefined; | |
| 378 | 378 | |
| 379 | 379 | var bin_digest: BinDigest = undefined; |
| 380 | 380 | self.hash.hasher.final(&bin_digest); |
| ... | ... | @@ -389,7 +389,7 @@ pub const Manifest = struct { |
| 389 | 389 | self.hash.hasher.update(&bin_digest); |
| 390 | 390 | |
| 391 | 391 | mem.copy(u8, &manifest_file_path, &self.hex_digest); |
| 392 | manifest_file_path[self.hex_digest.len..][0..ext.len].* = ext.*; | |
| 392 | manifest_file_path[hex_digest_len..][0..ext.len].* = ext.*; | |
| 393 | 393 | |
| 394 | 394 | if (self.files.items.len == 0) { |
| 395 | 395 | // If there are no file inputs, we check if the manifest file exists instead of |
lib/std/crypto/25519/ed25519.zig+1-1| ... | ... | @@ -622,7 +622,7 @@ test "ed25519 test vectors" { |
| 622 | 622 | }, |
| 623 | 623 | }; |
| 624 | 624 | for (entries) |entry| { |
| 625 | var msg: [entry.msg_hex.len / 2]u8 = undefined; | |
| 625 | var msg: [64 / 2]u8 = undefined; | |
| 626 | 626 | _ = try fmt.hexToBytes(&msg, entry.msg_hex); |
| 627 | 627 | var public_key_bytes: [32]u8 = undefined; |
| 628 | 628 | _ = try fmt.hexToBytes(&public_key_bytes, entry.public_key_hex); |
lib/std/enums.zig+4-4| ... | ... | @@ -177,9 +177,9 @@ test "std.enums.directEnumArrayDefault slice" { |
| 177 | 177 | /// Cast an enum literal, value, or string to the enum value of type E |
| 178 | 178 | /// with the same name. |
| 179 | 179 | pub fn nameCast(comptime E: type, comptime value: anytype) E { |
| 180 | comptime { | |
| 180 | return comptime blk: { | |
| 181 | 181 | const V = @TypeOf(value); |
| 182 | if (V == E) return value; | |
| 182 | if (V == E) break :blk value; | |
| 183 | 183 | var name: ?[]const u8 = switch (@typeInfo(V)) { |
| 184 | 184 | .EnumLiteral, .Enum => @tagName(value), |
| 185 | 185 | .Pointer => if (std.meta.trait.isZigString(V)) value else null, |
| ... | ... | @@ -187,12 +187,12 @@ pub fn nameCast(comptime E: type, comptime value: anytype) E { |
| 187 | 187 | }; |
| 188 | 188 | if (name) |n| { |
| 189 | 189 | if (@hasField(E, n)) { |
| 190 | return @field(E, n); | |
| 190 | break :blk @field(E, n); | |
| 191 | 191 | } |
| 192 | 192 | @compileError("Enum " ++ @typeName(E) ++ " has no field named " ++ n); |
| 193 | 193 | } |
| 194 | 194 | @compileError("Cannot cast from " ++ @typeName(@TypeOf(value)) ++ " to " ++ @typeName(E)); |
| 195 | } | |
| 195 | }; | |
| 196 | 196 | } |
| 197 | 197 | |
| 198 | 198 | test "std.enums.nameCast" { |
lib/std/math.zig+1-1| ... | ... | @@ -877,7 +877,7 @@ fn testDivFloor() !void { |
| 877 | 877 | /// zero. |
| 878 | 878 | pub fn divCeil(comptime T: type, numerator: T, denominator: T) !T { |
| 879 | 879 | @setRuntimeSafety(false); |
| 880 | if (comptime std.meta.trait.isNumber(T) and denominator == 0) return error.DivisionByZero; | |
| 880 | if ((comptime std.meta.trait.isNumber(T)) and denominator == 0) return error.DivisionByZero; | |
| 881 | 881 | const info = @typeInfo(T); |
| 882 | 882 | switch (info) { |
| 883 | 883 | .ComptimeFloat, .Float => return @ceil(numerator / denominator), |
lib/std/meta.zig+6-6| ... | ... | @@ -549,14 +549,14 @@ test "std.meta.FieldType" { |
| 549 | 549 | } |
| 550 | 550 | |
| 551 | 551 | pub fn fieldNames(comptime T: type) *const [fields(T).len][]const u8 { |
| 552 | comptime { | |
| 552 | return comptime blk: { | |
| 553 | 553 | const fieldInfos = fields(T); |
| 554 | 554 | var names: [fieldInfos.len][]const u8 = undefined; |
| 555 | 555 | for (fieldInfos, 0..) |field, i| { |
| 556 | 556 | names[i] = field.name; |
| 557 | 557 | } |
| 558 | return &names; | |
| 559 | } | |
| 558 | break :blk &names; | |
| 559 | }; | |
| 560 | 560 | } |
| 561 | 561 | |
| 562 | 562 | test "std.meta.fieldNames" { |
| ... | ... | @@ -590,14 +590,14 @@ test "std.meta.fieldNames" { |
| 590 | 590 | /// Given an enum or error set type, returns a pointer to an array containing all tags for that |
| 591 | 591 | /// enum or error set. |
| 592 | 592 | pub fn tags(comptime T: type) *const [fields(T).len]T { |
| 593 | comptime { | |
| 593 | return comptime blk: { | |
| 594 | 594 | const fieldInfos = fields(T); |
| 595 | 595 | var res: [fieldInfos.len]T = undefined; |
| 596 | 596 | for (fieldInfos, 0..) |field, i| { |
| 597 | 597 | res[i] = @field(T, field.name); |
| 598 | 598 | } |
| 599 | return &res; | |
| 600 | } | |
| 599 | break :blk &res; | |
| 600 | }; | |
| 601 | 601 | } |
| 602 | 602 | |
| 603 | 603 | test "std.meta.tags" { |
lib/std/meta/trait.zig+7-7| ... | ... | @@ -400,18 +400,18 @@ test "isTuple" { |
| 400 | 400 | /// *const u8, ?[]const u8, ?*const [N]u8. |
| 401 | 401 | /// ``` |
| 402 | 402 | pub fn isZigString(comptime T: type) bool { |
| 403 | comptime { | |
| 403 | return comptime blk: { | |
| 404 | 404 | // Only pointer types can be strings, no optionals |
| 405 | 405 | const info = @typeInfo(T); |
| 406 | if (info != .Pointer) return false; | |
| 406 | if (info != .Pointer) break :blk false; | |
| 407 | 407 | |
| 408 | 408 | const ptr = &info.Pointer; |
| 409 | 409 | // Check for CV qualifiers that would prevent coerction to []const u8 |
| 410 | if (ptr.is_volatile or ptr.is_allowzero) return false; | |
| 410 | if (ptr.is_volatile or ptr.is_allowzero) break :blk false; | |
| 411 | 411 | |
| 412 | 412 | // If it's already a slice, simple check. |
| 413 | 413 | if (ptr.size == .Slice) { |
| 414 | return ptr.child == u8; | |
| 414 | break :blk ptr.child == u8; | |
| 415 | 415 | } |
| 416 | 416 | |
| 417 | 417 | // Otherwise check if it's an array type that coerces to slice. |
| ... | ... | @@ -419,12 +419,12 @@ pub fn isZigString(comptime T: type) bool { |
| 419 | 419 | const child = @typeInfo(ptr.child); |
| 420 | 420 | if (child == .Array) { |
| 421 | 421 | const arr = &child.Array; |
| 422 | return arr.child == u8; | |
| 422 | break :blk arr.child == u8; | |
| 423 | 423 | } |
| 424 | 424 | } |
| 425 | 425 | |
| 426 | return false; | |
| 427 | } | |
| 426 | break :blk false; | |
| 427 | }; | |
| 428 | 428 | } |
| 429 | 429 | |
| 430 | 430 | test "isZigString" { |
lib/std/net/test.zig+1-1| ... | ... | @@ -99,7 +99,7 @@ test "parse and render UNIX addresses" { |
| 99 | 99 | const fmt_addr = std.fmt.bufPrint(buffer[0..], "{}", .{addr}) catch unreachable; |
| 100 | 100 | try std.testing.expectEqualSlices(u8, "/tmp/testpath", fmt_addr); |
| 101 | 101 | |
| 102 | const too_long = [_]u8{'a'} ** (addr.un.path.len + 1); | |
| 102 | const too_long = [_]u8{'a'} ** 200; | |
| 103 | 103 | try testing.expectError(error.NameTooLong, net.Address.initUnix(too_long[0..])); |
| 104 | 104 | } |
| 105 | 105 |
lib/std/unicode.zig+3-3| ... | ... | @@ -774,13 +774,13 @@ test "utf8ToUtf16LeWithNull" { |
| 774 | 774 | |
| 775 | 775 | /// Converts a UTF-8 string literal into a UTF-16LE string literal. |
| 776 | 776 | pub fn utf8ToUtf16LeStringLiteral(comptime utf8: []const u8) *const [calcUtf16LeLen(utf8) catch unreachable:0]u16 { |
| 777 | comptime { | |
| 777 | return comptime blk: { | |
| 778 | 778 | const len: usize = calcUtf16LeLen(utf8) catch |err| @compileError(err); |
| 779 | 779 | var utf16le: [len:0]u16 = [_:0]u16{0} ** len; |
| 780 | 780 | const utf16le_len = utf8ToUtf16Le(&utf16le, utf8[0..]) catch |err| @compileError(err); |
| 781 | 781 | assert(len == utf16le_len); |
| 782 | return &utf16le; | |
| 783 | } | |
| 782 | break :blk &utf16le; | |
| 783 | }; | |
| 784 | 784 | } |
| 785 | 785 | |
| 786 | 786 | const CalcUtf16LeLenError = Utf8DecodeError || error{Utf8InvalidStartByte}; |
lib/std/zig/system/linux.zig+5-3| ... | ... | @@ -147,7 +147,9 @@ test "cpuinfo: PowerPC" { |
| 147 | 147 | } |
| 148 | 148 | |
| 149 | 149 | const ArmCpuinfoImpl = struct { |
| 150 | cores: [4]CoreInfo = undefined, | |
| 150 | const num_cores = 4; | |
| 151 | ||
| 152 | cores: [num_cores]CoreInfo = undefined, | |
| 151 | 153 | core_no: usize = 0, |
| 152 | 154 | have_fields: usize = 0, |
| 153 | 155 | |
| ... | ... | @@ -162,7 +164,7 @@ const ArmCpuinfoImpl = struct { |
| 162 | 164 | const cpu_models = @import("arm.zig").cpu_models; |
| 163 | 165 | |
| 164 | 166 | fn addOne(self: *ArmCpuinfoImpl) void { |
| 165 | if (self.have_fields == 4 and self.core_no < self.cores.len) { | |
| 167 | if (self.have_fields == 4 and self.core_no < num_cores) { | |
| 166 | 168 | if (self.core_no > 0) { |
| 167 | 169 | // Deduplicate the core info. |
| 168 | 170 | for (self.cores[0..self.core_no]) |it| { |
| ... | ... | @@ -222,7 +224,7 @@ const ArmCpuinfoImpl = struct { |
| 222 | 224 | else => false, |
| 223 | 225 | }; |
| 224 | 226 | |
| 225 | var known_models: [self.cores.len]?*const Target.Cpu.Model = undefined; | |
| 227 | var known_models: [num_cores]?*const Target.Cpu.Model = undefined; | |
| 226 | 228 | for (self.cores[0..self.core_no], 0..) |core, i| { |
| 227 | 229 | known_models[i] = cpu_models.isKnown(.{ |
| 228 | 230 | .architecture = core.architecture, |
src/AstGen.zig+157-119| ... | ... | @@ -137,7 +137,7 @@ pub fn generate(gpa: Allocator, tree: Ast) Allocator.Error!Zir { |
| 137 | 137 | |
| 138 | 138 | var gz_instructions: std.ArrayListUnmanaged(Zir.Inst.Index) = .{}; |
| 139 | 139 | var gen_scope: GenZir = .{ |
| 140 | .force_comptime = true, | |
| 140 | .is_comptime = true, | |
| 141 | 141 | .parent = &top_scope.base, |
| 142 | 142 | .anon_name_strategy = .parent, |
| 143 | 143 | .decl_node_index = 0, |
| ... | ... | @@ -362,11 +362,7 @@ const type_ri: ResultInfo = .{ .rl = .{ .ty = .type_type } }; |
| 362 | 362 | const coerced_type_ri: ResultInfo = .{ .rl = .{ .coerced_ty = .type_type } }; |
| 363 | 363 | |
| 364 | 364 | fn typeExpr(gz: *GenZir, scope: *Scope, type_node: Ast.Node.Index) InnerError!Zir.Inst.Ref { |
| 365 | const prev_force_comptime = gz.force_comptime; | |
| 366 | gz.force_comptime = true; | |
| 367 | defer gz.force_comptime = prev_force_comptime; | |
| 368 | ||
| 369 | return expr(gz, scope, coerced_type_ri, type_node); | |
| 365 | return comptimeExpr(gz, scope, coerced_type_ri, type_node); | |
| 370 | 366 | } |
| 371 | 367 | |
| 372 | 368 | fn reachableTypeExpr( |
| ... | ... | @@ -375,11 +371,7 @@ fn reachableTypeExpr( |
| 375 | 371 | type_node: Ast.Node.Index, |
| 376 | 372 | reachable_node: Ast.Node.Index, |
| 377 | 373 | ) InnerError!Zir.Inst.Ref { |
| 378 | const prev_force_comptime = gz.force_comptime; | |
| 379 | gz.force_comptime = true; | |
| 380 | defer gz.force_comptime = prev_force_comptime; | |
| 381 | ||
| 382 | return reachableExpr(gz, scope, coerced_type_ri, type_node, reachable_node); | |
| 374 | return reachableExprComptime(gz, scope, coerced_type_ri, type_node, reachable_node, true); | |
| 383 | 375 | } |
| 384 | 376 | |
| 385 | 377 | /// Same as `expr` but fails with a compile error if the result type is `noreturn`. |
| ... | ... | @@ -401,11 +393,11 @@ fn reachableExprComptime( |
| 401 | 393 | reachable_node: Ast.Node.Index, |
| 402 | 394 | force_comptime: bool, |
| 403 | 395 | ) InnerError!Zir.Inst.Ref { |
| 404 | const prev_force_comptime = gz.force_comptime; | |
| 405 | gz.force_comptime = prev_force_comptime or force_comptime; | |
| 406 | defer gz.force_comptime = prev_force_comptime; | |
| 396 | const result_inst = if (force_comptime) | |
| 397 | try comptimeExpr(gz, scope, ri, node) | |
| 398 | else | |
| 399 | try expr(gz, scope, ri, node); | |
| 407 | 400 | |
| 408 | const result_inst = try expr(gz, scope, ri, node); | |
| 409 | 401 | if (gz.refIsNoReturn(result_inst)) { |
| 410 | 402 | try gz.astgen.appendErrorNodeNotes(reachable_node, "unreachable code", .{}, &[_]u32{ |
| 411 | 403 | try gz.astgen.errNoteNode(node, "control flow is diverted here", .{}), |
| ... | ... | @@ -825,7 +817,6 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE |
| 825 | 817 | _ = try gz.addAsIndex(.{ |
| 826 | 818 | .tag = .@"unreachable", |
| 827 | 819 | .data = .{ .@"unreachable" = .{ |
| 828 | .force_comptime = gz.force_comptime, | |
| 829 | 820 | .src_node = gz.nodeIndexToRelative(node), |
| 830 | 821 | } }, |
| 831 | 822 | }); |
| ... | ... | @@ -1578,12 +1569,7 @@ fn arrayInitExprRlPtrInner( |
| 1578 | 1569 | _ = try expr(gz, scope, .{ .rl = .{ .ptr = .{ .inst = elem_ptr } } }, elem_init); |
| 1579 | 1570 | } |
| 1580 | 1571 | |
| 1581 | const tag: Zir.Inst.Tag = if (gz.force_comptime) | |
| 1582 | .validate_array_init_comptime | |
| 1583 | else | |
| 1584 | .validate_array_init; | |
| 1585 | ||
| 1586 | _ = try gz.addPlNodePayloadIndex(tag, node, payload_index); | |
| 1572 | _ = try gz.addPlNodePayloadIndex(.validate_array_init, node, payload_index); | |
| 1587 | 1573 | return .void_value; |
| 1588 | 1574 | } |
| 1589 | 1575 | |
| ... | ... | @@ -1800,12 +1786,7 @@ fn structInitExprRlPtrInner( |
| 1800 | 1786 | _ = try expr(gz, scope, .{ .rl = .{ .ptr = .{ .inst = field_ptr } } }, field_init); |
| 1801 | 1787 | } |
| 1802 | 1788 | |
| 1803 | const tag: Zir.Inst.Tag = if (gz.force_comptime) | |
| 1804 | .validate_struct_init_comptime | |
| 1805 | else | |
| 1806 | .validate_struct_init; | |
| 1807 | ||
| 1808 | _ = try gz.addPlNodePayloadIndex(tag, node, payload_index); | |
| 1789 | _ = try gz.addPlNodePayloadIndex(.validate_struct_init, node, payload_index); | |
| 1809 | 1790 | return Zir.Inst.Ref.void_value; |
| 1810 | 1791 | } |
| 1811 | 1792 | |
| ... | ... | @@ -1843,23 +1824,105 @@ fn structInitExprRlTy( |
| 1843 | 1824 | return try gz.addPlNodePayloadIndex(tag, node, payload_index); |
| 1844 | 1825 | } |
| 1845 | 1826 | |
| 1846 | /// This calls expr in a comptime scope, and is intended to be called as a helper function. | |
| 1847 | /// The one that corresponds to `comptime` expression syntax is `comptimeExprAst`. | |
| 1827 | /// This explicitly calls expr in a comptime scope by wrapping it in a `block_comptime` if | |
| 1828 | /// necessary. It should be used whenever we need to force compile-time evaluation of something, | |
| 1829 | /// such as a type. | |
| 1830 | /// The function corresponding to `comptime` expression syntax is `comptimeExprAst`. | |
| 1848 | 1831 | fn comptimeExpr( |
| 1849 | 1832 | gz: *GenZir, |
| 1850 | 1833 | scope: *Scope, |
| 1851 | 1834 | ri: ResultInfo, |
| 1852 | 1835 | node: Ast.Node.Index, |
| 1853 | 1836 | ) InnerError!Zir.Inst.Ref { |
| 1854 | const prev_force_comptime = gz.force_comptime; | |
| 1855 | gz.force_comptime = true; | |
| 1856 | defer gz.force_comptime = prev_force_comptime; | |
| 1837 | if (gz.is_comptime) { | |
| 1838 | // No need to change anything! | |
| 1839 | return expr(gz, scope, ri, node); | |
| 1840 | } | |
| 1857 | 1841 | |
| 1858 | return expr(gz, scope, ri, node); | |
| 1842 | // There's an optimization here: if the body will be evaluated at comptime regardless, there's | |
| 1843 | // no need to wrap it in a block. This is hard to determine in general, but we can identify a | |
| 1844 | // common subset of trivially comptime expressions to take down the size of the ZIR a bit. | |
| 1845 | const tree = gz.astgen.tree; | |
| 1846 | const main_tokens = tree.nodes.items(.main_token); | |
| 1847 | const node_tags = tree.nodes.items(.tag); | |
| 1848 | switch (node_tags[node]) { | |
| 1849 | // Any identifier in `primitive_instrs` is trivially comptime. In particular, this includes | |
| 1850 | // some common types, so we can elide `block_comptime` for a few common type annotations. | |
| 1851 | .identifier => { | |
| 1852 | const ident_token = main_tokens[node]; | |
| 1853 | const ident_name_raw = tree.tokenSlice(ident_token); | |
| 1854 | if (primitive_instrs.get(ident_name_raw)) |zir_const_ref| { | |
| 1855 | // No need to worry about result location here, we're not creating a comptime block! | |
| 1856 | return rvalue(gz, ri, zir_const_ref, node); | |
| 1857 | } | |
| 1858 | }, | |
| 1859 | ||
| 1860 | // We can also avoid the block for a few trivial AST tags which are always comptime-known. | |
| 1861 | .number_literal, .string_literal, .multiline_string_literal, .enum_literal, .error_value => { | |
| 1862 | // No need to worry about result location here, we're not creating a comptime block! | |
| 1863 | return expr(gz, scope, ri, node); | |
| 1864 | }, | |
| 1865 | ||
| 1866 | // Lastly, for labelled blocks, avoid emitting a labelled block directly inside this | |
| 1867 | // comptime block, because that would be silly! Note that we don't bother doing this for | |
| 1868 | // unlabelled blocks, since they don't generate blocks at comptime anyway (see `blockExpr`). | |
| 1869 | .block_two, .block_two_semicolon, .block, .block_semicolon => { | |
| 1870 | const token_tags = tree.tokens.items(.tag); | |
| 1871 | const lbrace = main_tokens[node]; | |
| 1872 | if (token_tags[lbrace - 1] == .colon and | |
| 1873 | token_tags[lbrace - 2] == .identifier) | |
| 1874 | { | |
| 1875 | const node_datas = tree.nodes.items(.data); | |
| 1876 | switch (node_tags[node]) { | |
| 1877 | .block_two, .block_two_semicolon => { | |
| 1878 | const stmts: [2]Ast.Node.Index = .{ node_datas[node].lhs, node_datas[node].rhs }; | |
| 1879 | const stmt_slice = if (stmts[0] == 0) | |
| 1880 | stmts[0..0] | |
| 1881 | else if (stmts[1] == 0) | |
| 1882 | stmts[0..1] | |
| 1883 | else | |
| 1884 | stmts[0..2]; | |
| 1885 | ||
| 1886 | // Careful! We can't pass in the real result location here, since it may | |
| 1887 | // refer to runtime memory. A runtime-to-comptime boundary has to remove | |
| 1888 | // result location information, compute the result, and copy it to the true | |
| 1889 | // result location at runtime. We do this below as well. | |
| 1890 | const block_ref = try labeledBlockExpr(gz, scope, .{ .rl = .none }, node, stmt_slice, true); | |
| 1891 | return rvalue(gz, ri, block_ref, node); | |
| 1892 | }, | |
| 1893 | .block, .block_semicolon => { | |
| 1894 | const stmts = tree.extra_data[node_datas[node].lhs..node_datas[node].rhs]; | |
| 1895 | // Replace result location and copy back later - see above. | |
| 1896 | const block_ref = try labeledBlockExpr(gz, scope, .{ .rl = .none }, node, stmts, true); | |
| 1897 | return rvalue(gz, ri, block_ref, node); | |
| 1898 | }, | |
| 1899 | else => unreachable, | |
| 1900 | } | |
| 1901 | } | |
| 1902 | }, | |
| 1903 | ||
| 1904 | // In other cases, we don't optimize anything - we need a wrapper comptime block. | |
| 1905 | else => {}, | |
| 1906 | } | |
| 1907 | ||
| 1908 | var block_scope = gz.makeSubBlock(scope); | |
| 1909 | block_scope.is_comptime = true; | |
| 1910 | defer block_scope.unstack(); | |
| 1911 | ||
| 1912 | const block_inst = try gz.makeBlockInst(.block_comptime, node); | |
| 1913 | // Replace result location and copy back later - see above. | |
| 1914 | const block_result = try expr(&block_scope, scope, .{ .rl = .none }, node); | |
| 1915 | if (!gz.refIsNoReturn(block_result)) { | |
| 1916 | _ = try block_scope.addBreak(.@"break", block_inst, block_result); | |
| 1917 | } | |
| 1918 | try block_scope.setBlockBody(block_inst); | |
| 1919 | try gz.instructions.append(gz.astgen.gpa, block_inst); | |
| 1920 | ||
| 1921 | return rvalue(gz, ri, indexToRef(block_inst), node); | |
| 1859 | 1922 | } |
| 1860 | 1923 | |
| 1861 | 1924 | /// This one is for an actual `comptime` syntax, and will emit a compile error if |
| 1862 | /// the scope already has `force_comptime=true`. | |
| 1925 | /// the scope is already known to be comptime-evaluated. | |
| 1863 | 1926 | /// See `comptimeExpr` for the helper function for calling expr in a comptime scope. |
| 1864 | 1927 | fn comptimeExprAst( |
| 1865 | 1928 | gz: *GenZir, |
| ... | ... | @@ -1868,16 +1931,13 @@ fn comptimeExprAst( |
| 1868 | 1931 | node: Ast.Node.Index, |
| 1869 | 1932 | ) InnerError!Zir.Inst.Ref { |
| 1870 | 1933 | const astgen = gz.astgen; |
| 1871 | if (gz.force_comptime) { | |
| 1934 | if (gz.is_comptime) { | |
| 1872 | 1935 | return astgen.failNode(node, "redundant comptime keyword in already comptime scope", .{}); |
| 1873 | 1936 | } |
| 1874 | 1937 | const tree = astgen.tree; |
| 1875 | 1938 | const node_datas = tree.nodes.items(.data); |
| 1876 | 1939 | const body_node = node_datas[node].lhs; |
| 1877 | gz.force_comptime = true; | |
| 1878 | const result = try expr(gz, scope, ri, body_node); | |
| 1879 | gz.force_comptime = false; | |
| 1880 | return result; | |
| 1940 | return comptimeExpr(gz, scope, ri, body_node); | |
| 1881 | 1941 | } |
| 1882 | 1942 | |
| 1883 | 1943 | /// Restore the error return trace index. Performs the restore only if the result is a non-error or |
| ... | ... | @@ -1961,7 +2021,7 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) Inn |
| 1961 | 2021 | }; |
| 1962 | 2022 | // If we made it here, this block is the target of the break expr |
| 1963 | 2023 | |
| 1964 | const break_tag: Zir.Inst.Tag = if (block_gz.is_inline or block_gz.force_comptime) | |
| 2024 | const break_tag: Zir.Inst.Tag = if (block_gz.is_inline) | |
| 1965 | 2025 | .break_inline |
| 1966 | 2026 | else |
| 1967 | 2027 | .@"break"; |
| ... | ... | @@ -1973,7 +2033,7 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) Inn |
| 1973 | 2033 | try genDefers(parent_gz, scope, parent_scope, .normal_only); |
| 1974 | 2034 | |
| 1975 | 2035 | // As our last action before the break, "pop" the error trace if needed |
| 1976 | if (!block_gz.force_comptime) | |
| 2036 | if (!block_gz.is_comptime) | |
| 1977 | 2037 | _ = try parent_gz.addRestoreErrRetIndex(.{ .block = block_inst }, .always); |
| 1978 | 2038 | |
| 1979 | 2039 | _ = try parent_gz.addBreak(break_tag, block_inst, .void_value); |
| ... | ... | @@ -1986,7 +2046,7 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) Inn |
| 1986 | 2046 | try genDefers(parent_gz, scope, parent_scope, .normal_only); |
| 1987 | 2047 | |
| 1988 | 2048 | // As our last action before the break, "pop" the error trace if needed |
| 1989 | if (!block_gz.force_comptime) | |
| 2049 | if (!block_gz.is_comptime) | |
| 1990 | 2050 | try restoreErrRetIndex(parent_gz, .{ .block = block_inst }, block_gz.break_result_info, rhs, operand); |
| 1991 | 2051 | |
| 1992 | 2052 | switch (block_gz.break_result_info.rl) { |
| ... | ... | @@ -2062,7 +2122,7 @@ fn continueExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) |
| 2062 | 2122 | continue; |
| 2063 | 2123 | } |
| 2064 | 2124 | |
| 2065 | const break_tag: Zir.Inst.Tag = if (gen_zir.is_inline or gen_zir.force_comptime) | |
| 2125 | const break_tag: Zir.Inst.Tag = if (gen_zir.is_inline) | |
| 2066 | 2126 | .break_inline |
| 2067 | 2127 | else |
| 2068 | 2128 | .@"break"; |
| ... | ... | @@ -2071,7 +2131,7 @@ fn continueExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) |
| 2071 | 2131 | } |
| 2072 | 2132 | |
| 2073 | 2133 | // As our last action before the continue, "pop" the error trace if needed |
| 2074 | if (!gen_zir.force_comptime) | |
| 2134 | if (!gen_zir.is_comptime) | |
| 2075 | 2135 | _ = try parent_gz.addRestoreErrRetIndex(.{ .block = continue_block }, .always); |
| 2076 | 2136 | |
| 2077 | 2137 | _ = try parent_gz.addBreak(break_tag, continue_block, .void_value); |
| ... | ... | @@ -2116,10 +2176,10 @@ fn blockExpr( |
| 2116 | 2176 | if (token_tags[lbrace - 1] == .colon and |
| 2117 | 2177 | token_tags[lbrace - 2] == .identifier) |
| 2118 | 2178 | { |
| 2119 | return labeledBlockExpr(gz, scope, ri, block_node, statements); | |
| 2179 | return labeledBlockExpr(gz, scope, ri, block_node, statements, false); | |
| 2120 | 2180 | } |
| 2121 | 2181 | |
| 2122 | if (!gz.force_comptime) { | |
| 2182 | if (!gz.is_comptime) { | |
| 2123 | 2183 | // Since this block is unlabeled, its control flow is effectively linear and we |
| 2124 | 2184 | // can *almost* get away with inlining the block here. However, we actually need |
| 2125 | 2185 | // to preserve the .block for Sema, to properly pop the error return trace. |
| ... | ... | @@ -2136,9 +2196,7 @@ fn blockExpr( |
| 2136 | 2196 | if (!block_scope.endsWithNoReturn()) { |
| 2137 | 2197 | // As our last action before the break, "pop" the error trace if needed |
| 2138 | 2198 | _ = try gz.addRestoreErrRetIndex(.{ .block = block_inst }, .always); |
| 2139 | ||
| 2140 | const break_tag: Zir.Inst.Tag = if (block_scope.force_comptime) .break_inline else .@"break"; | |
| 2141 | _ = try block_scope.addBreak(break_tag, block_inst, .void_value); | |
| 2199 | _ = try block_scope.addBreak(.@"break", block_inst, .void_value); | |
| 2142 | 2200 | } |
| 2143 | 2201 | |
| 2144 | 2202 | try block_scope.setBlockBody(block_inst); |
| ... | ... | @@ -2188,6 +2246,7 @@ fn labeledBlockExpr( |
| 2188 | 2246 | ri: ResultInfo, |
| 2189 | 2247 | block_node: Ast.Node.Index, |
| 2190 | 2248 | statements: []const Ast.Node.Index, |
| 2249 | force_comptime: bool, | |
| 2191 | 2250 | ) InnerError!Zir.Inst.Ref { |
| 2192 | 2251 | const tracy = trace(@src()); |
| 2193 | 2252 | defer tracy.end(); |
| ... | ... | @@ -2205,16 +2264,16 @@ fn labeledBlockExpr( |
| 2205 | 2264 | |
| 2206 | 2265 | // Reserve the Block ZIR instruction index so that we can put it into the GenZir struct |
| 2207 | 2266 | // so that break statements can reference it. |
| 2208 | const block_tag: Zir.Inst.Tag = if (gz.force_comptime) .block_inline else .block; | |
| 2267 | const block_tag: Zir.Inst.Tag = if (force_comptime) .block_comptime else .block; | |
| 2209 | 2268 | const block_inst = try gz.makeBlockInst(block_tag, block_node); |
| 2210 | 2269 | try gz.instructions.append(astgen.gpa, block_inst); |
| 2211 | ||
| 2212 | 2270 | var block_scope = gz.makeSubBlock(parent_scope); |
| 2213 | 2271 | block_scope.label = GenZir.Label{ |
| 2214 | 2272 | .token = label_token, |
| 2215 | 2273 | .block_inst = block_inst, |
| 2216 | 2274 | }; |
| 2217 | 2275 | block_scope.setBreakResultInfo(ri); |
| 2276 | if (force_comptime) block_scope.is_comptime = true; | |
| 2218 | 2277 | defer block_scope.unstack(); |
| 2219 | 2278 | defer block_scope.labeled_breaks.deinit(astgen.gpa); |
| 2220 | 2279 | |
| ... | ... | @@ -2222,9 +2281,7 @@ fn labeledBlockExpr( |
| 2222 | 2281 | if (!block_scope.endsWithNoReturn()) { |
| 2223 | 2282 | // As our last action before the return, "pop" the error trace if needed |
| 2224 | 2283 | _ = try gz.addRestoreErrRetIndex(.{ .block = block_inst }, .always); |
| 2225 | ||
| 2226 | const break_tag: Zir.Inst.Tag = if (block_scope.force_comptime) .break_inline else .@"break"; | |
| 2227 | _ = try block_scope.addBreak(break_tag, block_inst, .void_value); | |
| 2284 | _ = try block_scope.addBreak(.@"break", block_inst, .void_value); | |
| 2228 | 2285 | } |
| 2229 | 2286 | |
| 2230 | 2287 | if (!block_scope.label.?.used) { |
| ... | ... | @@ -2436,6 +2493,7 @@ fn addEnsureResult(gz: *GenZir, maybe_unused_result: Zir.Inst.Ref, statement: As |
| 2436 | 2493 | .bitcast, |
| 2437 | 2494 | .bit_or, |
| 2438 | 2495 | .block, |
| 2496 | .block_comptime, | |
| 2439 | 2497 | .block_inline, |
| 2440 | 2498 | .suspend_block, |
| 2441 | 2499 | .loop, |
| ... | ... | @@ -2610,8 +2668,6 @@ fn addEnsureResult(gz: *GenZir, maybe_unused_result: Zir.Inst.Ref, statement: As |
| 2610 | 2668 | .for_len, |
| 2611 | 2669 | .@"try", |
| 2612 | 2670 | .try_ptr, |
| 2613 | //.try_inline, | |
| 2614 | //.try_ptr_inline, | |
| 2615 | 2671 | => break :b false, |
| 2616 | 2672 | |
| 2617 | 2673 | .extended => switch (gz.astgen.instructions.items(.data)[inst].extended.opcode) { |
| ... | ... | @@ -2638,7 +2694,6 @@ fn addEnsureResult(gz: *GenZir, maybe_unused_result: Zir.Inst.Ref, statement: As |
| 2638 | 2694 | .repeat, |
| 2639 | 2695 | .repeat_inline, |
| 2640 | 2696 | .panic, |
| 2641 | .panic_comptime, | |
| 2642 | 2697 | .trap, |
| 2643 | 2698 | .check_comptime_control_flow, |
| 2644 | 2699 | => { |
| ... | ... | @@ -2665,9 +2720,7 @@ fn addEnsureResult(gz: *GenZir, maybe_unused_result: Zir.Inst.Ref, statement: As |
| 2665 | 2720 | .store_to_inferred_ptr, |
| 2666 | 2721 | .resolve_inferred_alloc, |
| 2667 | 2722 | .validate_struct_init, |
| 2668 | .validate_struct_init_comptime, | |
| 2669 | 2723 | .validate_array_init, |
| 2670 | .validate_array_init_comptime, | |
| 2671 | 2724 | .set_runtime_safety, |
| 2672 | 2725 | .closure_capture, |
| 2673 | 2726 | .memcpy, |
| ... | ... | @@ -2988,7 +3041,7 @@ fn varDecl( |
| 2988 | 3041 | return &sub_scope.base; |
| 2989 | 3042 | } |
| 2990 | 3043 | |
| 2991 | const is_comptime = gz.force_comptime or | |
| 3044 | const is_comptime = gz.is_comptime or | |
| 2992 | 3045 | tree.nodes.items(.tag)[var_decl.ast.init_node] == .@"comptime"; |
| 2993 | 3046 | |
| 2994 | 3047 | // Detect whether the initialization expression actually uses the |
| ... | ... | @@ -3133,7 +3186,7 @@ fn varDecl( |
| 3133 | 3186 | const old_rl_ty_inst = gz.rl_ty_inst; |
| 3134 | 3187 | defer gz.rl_ty_inst = old_rl_ty_inst; |
| 3135 | 3188 | |
| 3136 | const is_comptime = var_decl.comptime_token != null or gz.force_comptime; | |
| 3189 | const is_comptime = var_decl.comptime_token != null or gz.is_comptime; | |
| 3137 | 3190 | var resolve_inferred_alloc: Zir.Inst.Ref = .none; |
| 3138 | 3191 | const var_data: struct { |
| 3139 | 3192 | result_info: ResultInfo, |
| ... | ... | @@ -3211,7 +3264,7 @@ fn emitDbgNode(gz: *GenZir, node: Ast.Node.Index) !void { |
| 3211 | 3264 | // The instruction emitted here is for debugging runtime code. |
| 3212 | 3265 | // If the current block will be evaluated only during semantic analysis |
| 3213 | 3266 | // then no dbg_stmt ZIR instruction is needed. |
| 3214 | if (gz.force_comptime) return; | |
| 3267 | if (gz.is_comptime) return; | |
| 3215 | 3268 | |
| 3216 | 3269 | const astgen = gz.astgen; |
| 3217 | 3270 | astgen.advanceSourceCursorToNode(node); |
| ... | ... | @@ -3631,7 +3684,7 @@ fn fnDecl( |
| 3631 | 3684 | astgen.advanceSourceCursorToNode(decl_node); |
| 3632 | 3685 | |
| 3633 | 3686 | var decl_gz: GenZir = .{ |
| 3634 | .force_comptime = true, | |
| 3687 | .is_comptime = true, | |
| 3635 | 3688 | .decl_node_index = fn_proto.ast.proto_node, |
| 3636 | 3689 | .decl_line = astgen.source_line, |
| 3637 | 3690 | .parent = scope, |
| ... | ... | @@ -3642,7 +3695,7 @@ fn fnDecl( |
| 3642 | 3695 | defer decl_gz.unstack(); |
| 3643 | 3696 | |
| 3644 | 3697 | var fn_gz: GenZir = .{ |
| 3645 | .force_comptime = false, | |
| 3698 | .is_comptime = false, | |
| 3646 | 3699 | .decl_node_index = fn_proto.ast.proto_node, |
| 3647 | 3700 | .decl_line = decl_gz.decl_line, |
| 3648 | 3701 | .parent = &decl_gz.base, |
| ... | ... | @@ -4005,7 +4058,7 @@ fn globalVarDecl( |
| 4005 | 4058 | .decl_node_index = node, |
| 4006 | 4059 | .decl_line = astgen.source_line, |
| 4007 | 4060 | .astgen = astgen, |
| 4008 | .force_comptime = true, | |
| 4061 | .is_comptime = true, | |
| 4009 | 4062 | .anon_name_strategy = .parent, |
| 4010 | 4063 | .instructions = gz.instructions, |
| 4011 | 4064 | .instructions_top = gz.instructions.items.len, |
| ... | ... | @@ -4156,7 +4209,7 @@ fn comptimeDecl( |
| 4156 | 4209 | astgen.advanceSourceCursorToNode(node); |
| 4157 | 4210 | |
| 4158 | 4211 | var decl_block: GenZir = .{ |
| 4159 | .force_comptime = true, | |
| 4212 | .is_comptime = true, | |
| 4160 | 4213 | .decl_node_index = node, |
| 4161 | 4214 | .decl_line = astgen.source_line, |
| 4162 | 4215 | .parent = scope, |
| ... | ... | @@ -4210,7 +4263,7 @@ fn usingnamespaceDecl( |
| 4210 | 4263 | astgen.advanceSourceCursorToNode(node); |
| 4211 | 4264 | |
| 4212 | 4265 | var decl_block: GenZir = .{ |
| 4213 | .force_comptime = true, | |
| 4266 | .is_comptime = true, | |
| 4214 | 4267 | .decl_node_index = node, |
| 4215 | 4268 | .decl_line = astgen.source_line, |
| 4216 | 4269 | .parent = scope, |
| ... | ... | @@ -4257,7 +4310,7 @@ fn testDecl( |
| 4257 | 4310 | astgen.advanceSourceCursorToNode(node); |
| 4258 | 4311 | |
| 4259 | 4312 | var decl_block: GenZir = .{ |
| 4260 | .force_comptime = true, | |
| 4313 | .is_comptime = true, | |
| 4261 | 4314 | .decl_node_index = node, |
| 4262 | 4315 | .decl_line = astgen.source_line, |
| 4263 | 4316 | .parent = scope, |
| ... | ... | @@ -4353,7 +4406,7 @@ fn testDecl( |
| 4353 | 4406 | }; |
| 4354 | 4407 | |
| 4355 | 4408 | var fn_block: GenZir = .{ |
| 4356 | .force_comptime = false, | |
| 4409 | .is_comptime = false, | |
| 4357 | 4410 | .decl_node_index = node, |
| 4358 | 4411 | .decl_line = decl_block.decl_line, |
| 4359 | 4412 | .parent = &decl_block.base, |
| ... | ... | @@ -4477,7 +4530,7 @@ fn structDeclInner( |
| 4477 | 4530 | .decl_node_index = node, |
| 4478 | 4531 | .decl_line = gz.decl_line, |
| 4479 | 4532 | .astgen = astgen, |
| 4480 | .force_comptime = true, | |
| 4533 | .is_comptime = true, | |
| 4481 | 4534 | .instructions = gz.instructions, |
| 4482 | 4535 | .instructions_top = gz.instructions.items.len, |
| 4483 | 4536 | }; |
| ... | ... | @@ -4720,7 +4773,7 @@ fn unionDeclInner( |
| 4720 | 4773 | .decl_node_index = node, |
| 4721 | 4774 | .decl_line = gz.decl_line, |
| 4722 | 4775 | .astgen = astgen, |
| 4723 | .force_comptime = true, | |
| 4776 | .is_comptime = true, | |
| 4724 | 4777 | .instructions = gz.instructions, |
| 4725 | 4778 | .instructions_top = gz.instructions.items.len, |
| 4726 | 4779 | }; |
| ... | ... | @@ -5006,7 +5059,7 @@ fn containerDecl( |
| 5006 | 5059 | .decl_node_index = node, |
| 5007 | 5060 | .decl_line = gz.decl_line, |
| 5008 | 5061 | .astgen = astgen, |
| 5009 | .force_comptime = true, | |
| 5062 | .is_comptime = true, | |
| 5010 | 5063 | .instructions = gz.instructions, |
| 5011 | 5064 | .instructions_top = gz.instructions.items.len, |
| 5012 | 5065 | }; |
| ... | ... | @@ -5115,7 +5168,7 @@ fn containerDecl( |
| 5115 | 5168 | .decl_node_index = node, |
| 5116 | 5169 | .decl_line = gz.decl_line, |
| 5117 | 5170 | .astgen = astgen, |
| 5118 | .force_comptime = true, | |
| 5171 | .is_comptime = true, | |
| 5119 | 5172 | .instructions = gz.instructions, |
| 5120 | 5173 | .instructions_top = gz.instructions.items.len, |
| 5121 | 5174 | }; |
| ... | ... | @@ -5304,7 +5357,7 @@ fn tryExpr( |
| 5304 | 5357 | // Then we will save the line/column so that we can emit another one that goes |
| 5305 | 5358 | // "backwards" because we want to evaluate the operand, but then put the debug |
| 5306 | 5359 | // info back at the try keyword for error return tracing. |
| 5307 | if (!parent_gz.force_comptime) { | |
| 5360 | if (!parent_gz.is_comptime) { | |
| 5308 | 5361 | try emitDbgNode(parent_gz, node); |
| 5309 | 5362 | } |
| 5310 | 5363 | const try_line = astgen.source_line - parent_gz.decl_line; |
| ... | ... | @@ -5316,17 +5369,7 @@ fn tryExpr( |
| 5316 | 5369 | }; |
| 5317 | 5370 | // This could be a pointer or value depending on the `ri` parameter. |
| 5318 | 5371 | const operand = try reachableExpr(parent_gz, scope, operand_ri, operand_node, node); |
| 5319 | const is_inline = parent_gz.force_comptime; | |
| 5320 | const is_inline_bit = @as(u2, @boolToInt(is_inline)); | |
| 5321 | const is_ptr_bit = @as(u2, @boolToInt(operand_ri.rl == .ref)) << 1; | |
| 5322 | const block_tag: Zir.Inst.Tag = switch (is_inline_bit | is_ptr_bit) { | |
| 5323 | 0b00 => .@"try", | |
| 5324 | 0b01 => .@"try", | |
| 5325 | //0b01 => .try_inline, | |
| 5326 | 0b10 => .try_ptr, | |
| 5327 | 0b11 => .try_ptr, | |
| 5328 | //0b11 => .try_ptr_inline, | |
| 5329 | }; | |
| 5372 | const block_tag: Zir.Inst.Tag = if (operand_ri.rl == .ref) .try_ptr else .@"try"; | |
| 5330 | 5373 | const try_inst = try parent_gz.makeBlockInst(block_tag, node); |
| 5331 | 5374 | try parent_gz.instructions.append(astgen.gpa, try_inst); |
| 5332 | 5375 | |
| ... | ... | @@ -5382,11 +5425,9 @@ fn orelseCatchExpr( |
| 5382 | 5425 | // up for this fact by calling rvalue on the else branch. |
| 5383 | 5426 | const operand = try reachableExpr(&block_scope, &block_scope.base, operand_ri, lhs, rhs); |
| 5384 | 5427 | const cond = try block_scope.addUnNode(cond_op, operand, node); |
| 5385 | const condbr_tag: Zir.Inst.Tag = if (parent_gz.force_comptime) .condbr_inline else .condbr; | |
| 5386 | const condbr = try block_scope.addCondBr(condbr_tag, node); | |
| 5428 | const condbr = try block_scope.addCondBr(.condbr, node); | |
| 5387 | 5429 | |
| 5388 | const block_tag: Zir.Inst.Tag = if (parent_gz.force_comptime) .block_inline else .block; | |
| 5389 | const block = try parent_gz.makeBlockInst(block_tag, node); | |
| 5430 | const block = try parent_gz.makeBlockInst(.block, node); | |
| 5390 | 5431 | try block_scope.setBlockBody(block); |
| 5391 | 5432 | // block_scope unstacked now, can add new instructions to parent_gz |
| 5392 | 5433 | try parent_gz.instructions.append(astgen.gpa, block); |
| ... | ... | @@ -5445,7 +5486,6 @@ fn orelseCatchExpr( |
| 5445 | 5486 | // instructions into place until we know whether to keep store_to_block_ptr |
| 5446 | 5487 | // instructions or not. |
| 5447 | 5488 | |
| 5448 | const break_tag: Zir.Inst.Tag = if (parent_gz.force_comptime) .break_inline else .@"break"; | |
| 5449 | 5489 | const result = try finishThenElseBlock( |
| 5450 | 5490 | parent_gz, |
| 5451 | 5491 | ri, |
| ... | ... | @@ -5461,7 +5501,7 @@ fn orelseCatchExpr( |
| 5461 | 5501 | rhs, |
| 5462 | 5502 | block, |
| 5463 | 5503 | block, |
| 5464 | break_tag, | |
| 5504 | .@"break", | |
| 5465 | 5505 | ); |
| 5466 | 5506 | return result; |
| 5467 | 5507 | } |
| ... | ... | @@ -5747,11 +5787,9 @@ fn ifExpr( |
| 5747 | 5787 | } |
| 5748 | 5788 | }; |
| 5749 | 5789 | |
| 5750 | const condbr_tag: Zir.Inst.Tag = if (parent_gz.force_comptime) .condbr_inline else .condbr; | |
| 5751 | const condbr = try block_scope.addCondBr(condbr_tag, node); | |
| 5790 | const condbr = try block_scope.addCondBr(.condbr, node); | |
| 5752 | 5791 | |
| 5753 | const block_tag: Zir.Inst.Tag = if (parent_gz.force_comptime) .block_inline else .block; | |
| 5754 | const block = try parent_gz.makeBlockInst(block_tag, node); | |
| 5792 | const block = try parent_gz.makeBlockInst(.block, node); | |
| 5755 | 5793 | try block_scope.setBlockBody(block); |
| 5756 | 5794 | // block_scope unstacked now, can add new instructions to parent_gz |
| 5757 | 5795 | try parent_gz.instructions.append(astgen.gpa, block); |
| ... | ... | @@ -5891,7 +5929,6 @@ fn ifExpr( |
| 5891 | 5929 | }, |
| 5892 | 5930 | }; |
| 5893 | 5931 | |
| 5894 | const break_tag: Zir.Inst.Tag = if (parent_gz.force_comptime) .break_inline else .@"break"; | |
| 5895 | 5932 | const result = try finishThenElseBlock( |
| 5896 | 5933 | parent_gz, |
| 5897 | 5934 | ri, |
| ... | ... | @@ -5907,7 +5944,7 @@ fn ifExpr( |
| 5907 | 5944 | else_info.src, |
| 5908 | 5945 | block, |
| 5909 | 5946 | block, |
| 5910 | break_tag, | |
| 5947 | .@"break", | |
| 5911 | 5948 | ); |
| 5912 | 5949 | return result; |
| 5913 | 5950 | } |
| ... | ... | @@ -6043,7 +6080,7 @@ fn whileExpr( |
| 6043 | 6080 | try astgen.checkLabelRedefinition(scope, label_token); |
| 6044 | 6081 | } |
| 6045 | 6082 | |
| 6046 | const is_inline = parent_gz.force_comptime or while_full.inline_token != null; | |
| 6083 | const is_inline = while_full.inline_token != null; | |
| 6047 | 6084 | const loop_tag: Zir.Inst.Tag = if (is_inline) .block_inline else .loop; |
| 6048 | 6085 | const loop_block = try parent_gz.makeBlockInst(loop_tag, node); |
| 6049 | 6086 | try parent_gz.instructions.append(astgen.gpa, loop_block); |
| ... | ... | @@ -6315,7 +6352,7 @@ fn forExpr( |
| 6315 | 6352 | try astgen.checkLabelRedefinition(scope, label_token); |
| 6316 | 6353 | } |
| 6317 | 6354 | |
| 6318 | const is_inline = parent_gz.force_comptime or for_full.inline_token != null; | |
| 6355 | const is_inline = for_full.inline_token != null; | |
| 6319 | 6356 | const tree = astgen.tree; |
| 6320 | 6357 | const token_tags = tree.tokens.items(.tag); |
| 6321 | 6358 | const node_tags = tree.nodes.items(.tag); |
| ... | ... | @@ -7114,7 +7151,7 @@ fn ret(gz: *GenZir, scope: *Scope, node: Ast.Node.Index) InnerError!Zir.Inst.Ref |
| 7114 | 7151 | // Then we will save the line/column so that we can emit another one that goes |
| 7115 | 7152 | // "backwards" because we want to evaluate the operand, but then put the debug |
| 7116 | 7153 | // info back at the return keyword for error return tracing. |
| 7117 | if (!gz.force_comptime) { | |
| 7154 | if (!gz.is_comptime) { | |
| 7118 | 7155 | try emitDbgNode(gz, node); |
| 7119 | 7156 | } |
| 7120 | 7157 | const ret_line = astgen.source_line - gz.decl_line; |
| ... | ... | @@ -7859,7 +7896,7 @@ fn typeOf( |
| 7859 | 7896 | const typeof_inst = try gz.makeBlockInst(.typeof_builtin, node); |
| 7860 | 7897 | |
| 7861 | 7898 | var typeof_scope = gz.makeSubBlock(scope); |
| 7862 | typeof_scope.force_comptime = false; | |
| 7899 | typeof_scope.is_comptime = false; | |
| 7863 | 7900 | typeof_scope.c_import = false; |
| 7864 | 7901 | defer typeof_scope.unstack(); |
| 7865 | 7902 | |
| ... | ... | @@ -7880,7 +7917,7 @@ fn typeOf( |
| 7880 | 7917 | const typeof_inst = try gz.addExtendedMultiOpPayloadIndex(.typeof_peer, payload_index, args.len); |
| 7881 | 7918 | |
| 7882 | 7919 | var typeof_scope = gz.makeSubBlock(scope); |
| 7883 | typeof_scope.force_comptime = false; | |
| 7920 | typeof_scope.is_comptime = false; | |
| 7884 | 7921 | |
| 7885 | 7922 | for (args, 0..) |arg, i| { |
| 7886 | 7923 | const param_ref = try reachableExpr(&typeof_scope, &typeof_scope.base, .{ .rl = .none }, arg, node); |
| ... | ... | @@ -8207,7 +8244,7 @@ fn builtinCall( |
| 8207 | 8244 | }, |
| 8208 | 8245 | .panic => { |
| 8209 | 8246 | try emitDbgNode(gz, node); |
| 8210 | return simpleUnOp(gz, scope, ri, node, .{ .rl = .{ .ty = .const_slice_u8_type } }, params[0], if (gz.force_comptime) .panic_comptime else .panic); | |
| 8247 | return simpleUnOp(gz, scope, ri, node, .{ .rl = .{ .ty = .const_slice_u8_type } }, params[0], .panic); | |
| 8211 | 8248 | }, |
| 8212 | 8249 | .trap => { |
| 8213 | 8250 | try emitDbgNode(gz, node); |
| ... | ... | @@ -8431,7 +8468,6 @@ fn builtinCall( |
| 8431 | 8468 | .args = args, |
| 8432 | 8469 | .flags = .{ |
| 8433 | 8470 | .is_nosuspend = gz.nosuspend_node != 0, |
| 8434 | .is_comptime = gz.force_comptime, | |
| 8435 | 8471 | .ensure_result_used = false, |
| 8436 | 8472 | }, |
| 8437 | 8473 | }); |
| ... | ... | @@ -8644,15 +8680,14 @@ fn simpleUnOp( |
| 8644 | 8680 | operand_node: Ast.Node.Index, |
| 8645 | 8681 | tag: Zir.Inst.Tag, |
| 8646 | 8682 | ) InnerError!Zir.Inst.Ref { |
| 8647 | const prev_force_comptime = gz.force_comptime; | |
| 8648 | defer gz.force_comptime = prev_force_comptime; | |
| 8649 | ||
| 8650 | 8683 | switch (tag) { |
| 8651 | 8684 | .tag_name, .error_name, .ptr_to_int => try emitDbgNode(gz, node), |
| 8652 | .compile_error => gz.force_comptime = true, | |
| 8653 | 8685 | else => {}, |
| 8654 | 8686 | } |
| 8655 | const operand = try expr(gz, scope, operand_ri, operand_node); | |
| 8687 | const operand = if (tag == .compile_error) | |
| 8688 | try comptimeExpr(gz, scope, operand_ri, operand_node) | |
| 8689 | else | |
| 8690 | try expr(gz, scope, operand_ri, operand_node); | |
| 8656 | 8691 | const result = try gz.addUnNode(tag, operand, node); |
| 8657 | 8692 | return rvalue(gz, ri, result, node); |
| 8658 | 8693 | } |
| ... | ... | @@ -8814,7 +8849,7 @@ fn cImport( |
| 8814 | 8849 | if (gz.c_import) return gz.astgen.failNode(node, "cannot nest @cImport", .{}); |
| 8815 | 8850 | |
| 8816 | 8851 | var block_scope = gz.makeSubBlock(scope); |
| 8817 | block_scope.force_comptime = true; | |
| 8852 | block_scope.is_comptime = true; | |
| 8818 | 8853 | block_scope.c_import = true; |
| 8819 | 8854 | defer block_scope.unstack(); |
| 8820 | 8855 | |
| ... | ... | @@ -8860,7 +8895,7 @@ fn callExpr( |
| 8860 | 8895 | |
| 8861 | 8896 | const callee = try calleeExpr(gz, scope, call.ast.fn_expr); |
| 8862 | 8897 | const modifier: std.builtin.CallModifier = blk: { |
| 8863 | if (gz.force_comptime) { | |
| 8898 | if (gz.is_comptime) { | |
| 8864 | 8899 | break :blk .compile_time; |
| 8865 | 8900 | } |
| 8866 | 8901 | if (call.async_token != null) { |
| ... | ... | @@ -10875,7 +10910,10 @@ const Scope = struct { |
| 10875 | 10910 | const GenZir = struct { |
| 10876 | 10911 | const base_tag: Scope.Tag = .gen_zir; |
| 10877 | 10912 | base: Scope = Scope{ .tag = base_tag }, |
| 10878 | force_comptime: bool, | |
| 10913 | /// Whether we're already in a scope known to be comptime. This is set | |
| 10914 | /// whenever we know Sema will analyze the current block with `is_comptime`, | |
| 10915 | /// for instance when we're within a `struct_decl` or a `block_comptime`. | |
| 10916 | is_comptime: bool, | |
| 10879 | 10917 | /// This is set to true for inline loops; false otherwise. |
| 10880 | 10918 | is_inline: bool = false, |
| 10881 | 10919 | c_import: bool = false, |
| ... | ... | @@ -10962,7 +11000,7 @@ const GenZir = struct { |
| 10962 | 11000 | |
| 10963 | 11001 | fn makeSubBlock(gz: *GenZir, scope: *Scope) GenZir { |
| 10964 | 11002 | return .{ |
| 10965 | .force_comptime = gz.force_comptime, | |
| 11003 | .is_comptime = gz.is_comptime, | |
| 10966 | 11004 | .c_import = gz.c_import, |
| 10967 | 11005 | .decl_node_index = gz.decl_node_index, |
| 10968 | 11006 | .decl_line = gz.decl_line, |
| ... | ... | @@ -12405,7 +12443,7 @@ const GenZir = struct { |
| 12405 | 12443 | } |
| 12406 | 12444 | |
| 12407 | 12445 | fn addDbgVar(gz: *GenZir, tag: Zir.Inst.Tag, name: u32, inst: Zir.Inst.Ref) !void { |
| 12408 | if (gz.force_comptime) return; | |
| 12446 | if (gz.is_comptime) return; | |
| 12409 | 12447 | |
| 12410 | 12448 | _ = try gz.add(.{ .tag = tag, .data = .{ |
| 12411 | 12449 | .str_op = .{ |
| ... | ... | @@ -12416,13 +12454,13 @@ const GenZir = struct { |
| 12416 | 12454 | } |
| 12417 | 12455 | |
| 12418 | 12456 | fn addDbgBlockBegin(gz: *GenZir) !void { |
| 12419 | if (gz.force_comptime) return; | |
| 12457 | if (gz.is_comptime) return; | |
| 12420 | 12458 | |
| 12421 | 12459 | _ = try gz.add(.{ .tag = .dbg_block_begin, .data = undefined }); |
| 12422 | 12460 | } |
| 12423 | 12461 | |
| 12424 | 12462 | fn addDbgBlockEnd(gz: *GenZir) !void { |
| 12425 | if (gz.force_comptime) return; | |
| 12463 | if (gz.is_comptime) return; | |
| 12426 | 12464 | const gpa = gz.astgen.gpa; |
| 12427 | 12465 | |
| 12428 | 12466 | const tags = gz.astgen.instructions.items(.tag); |
| ... | ... | @@ -12554,7 +12592,7 @@ fn detectLocalShadowing( |
| 12554 | 12592 | /// Advances the source cursor to the main token of `node` if not in comptime scope. |
| 12555 | 12593 | /// Usually paired with `emitDbgStmt`. |
| 12556 | 12594 | fn maybeAdvanceSourceCursorToMainToken(gz: *GenZir, node: Ast.Node.Index) void { |
| 12557 | if (gz.force_comptime) return; | |
| 12595 | if (gz.is_comptime) return; | |
| 12558 | 12596 | |
| 12559 | 12597 | const tree = gz.astgen.tree; |
| 12560 | 12598 | const token_starts = tree.tokens.items(.start); |
| ... | ... | @@ -12765,7 +12803,7 @@ fn countBodyLenAfterFixups(astgen: *AstGen, body: []const Zir.Inst.Index) u32 { |
| 12765 | 12803 | } |
| 12766 | 12804 | |
| 12767 | 12805 | fn emitDbgStmt(gz: *GenZir, line: u32, column: u32) !void { |
| 12768 | if (gz.force_comptime) return; | |
| 12806 | if (gz.is_comptime) return; | |
| 12769 | 12807 | |
| 12770 | 12808 | _ = try gz.add(.{ .tag = .dbg_stmt, .data = .{ |
| 12771 | 12809 | .dbg_stmt = .{ |
src/Sema.zig+23-89| ... | ... | @@ -1112,8 +1112,7 @@ fn analyzeBodyInner( |
| 1112 | 1112 | .ret_load => break sema.zirRetLoad(block, inst), |
| 1113 | 1113 | .ret_err_value => break sema.zirRetErrValue(block, inst), |
| 1114 | 1114 | .@"unreachable" => break sema.zirUnreachable(block, inst), |
| 1115 | .panic => break sema.zirPanic(block, inst, false), | |
| 1116 | .panic_comptime => break sema.zirPanic(block, inst, true), | |
| 1115 | .panic => break sema.zirPanic(block, inst), | |
| 1117 | 1116 | .trap => break sema.zirTrap(block, inst), |
| 1118 | 1117 | // zig fmt: on |
| 1119 | 1118 | |
| ... | ... | @@ -1292,22 +1291,12 @@ fn analyzeBodyInner( |
| 1292 | 1291 | continue; |
| 1293 | 1292 | }, |
| 1294 | 1293 | .validate_struct_init => { |
| 1295 | try sema.zirValidateStructInit(block, inst, false); | |
| 1296 | i += 1; | |
| 1297 | continue; | |
| 1298 | }, | |
| 1299 | .validate_struct_init_comptime => { | |
| 1300 | try sema.zirValidateStructInit(block, inst, true); | |
| 1294 | try sema.zirValidateStructInit(block, inst); | |
| 1301 | 1295 | i += 1; |
| 1302 | 1296 | continue; |
| 1303 | 1297 | }, |
| 1304 | 1298 | .validate_array_init => { |
| 1305 | try sema.zirValidateArrayInit(block, inst, false); | |
| 1306 | i += 1; | |
| 1307 | continue; | |
| 1308 | }, | |
| 1309 | .validate_array_init_comptime => { | |
| 1310 | try sema.zirValidateArrayInit(block, inst, true); | |
| 1299 | try sema.zirValidateArrayInit(block, inst); | |
| 1311 | 1300 | i += 1; |
| 1312 | 1301 | continue; |
| 1313 | 1302 | }, |
| ... | ... | @@ -1464,8 +1453,10 @@ fn analyzeBodyInner( |
| 1464 | 1453 | break break_data.inst; |
| 1465 | 1454 | } |
| 1466 | 1455 | }, |
| 1467 | .block => blk: { | |
| 1468 | if (!block.is_comptime) break :blk try sema.zirBlock(block, inst); | |
| 1456 | .block, .block_comptime => blk: { | |
| 1457 | if (!block.is_comptime) { | |
| 1458 | break :blk try sema.zirBlock(block, inst, tags[inst] == .block_comptime); | |
| 1459 | } | |
| 1469 | 1460 | // Same as `block_inline`. TODO https://github.com/ziglang/zig/issues/8220 |
| 1470 | 1461 | const inst_data = datas[inst].pl_node; |
| 1471 | 1462 | const extra = sema.code.extraData(Zir.Inst.Block, inst_data.payload_index); |
| ... | ... | @@ -1649,38 +1640,6 @@ fn analyzeBodyInner( |
| 1649 | 1640 | break break_data.inst; |
| 1650 | 1641 | } |
| 1651 | 1642 | }, |
| 1652 | //.try_inline => blk: { | |
| 1653 | // const inst_data = sema.code.instructions.items(.data)[inst].pl_node; | |
| 1654 | // const src = inst_data.src(); | |
| 1655 | // const operand_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node }; | |
| 1656 | // const extra = sema.code.extraData(Zir.Inst.Try, inst_data.payload_index); | |
| 1657 | // const inline_body = sema.code.extra[extra.end..][0..extra.data.body_len]; | |
| 1658 | // const operand = try sema.resolveInst(extra.data.operand); | |
| 1659 | // const operand_ty = sema.typeOf(operand); | |
| 1660 | // const is_ptr = operand_ty.zigTypeTag() == .Pointer; | |
| 1661 | // const err_union = if (is_ptr) | |
| 1662 | // try sema.analyzeLoad(block, src, operand, operand_src) | |
| 1663 | // else | |
| 1664 | // operand; | |
| 1665 | // const is_non_err = try sema.analyzeIsNonErrComptimeOnly(block, operand_src, err_union); | |
| 1666 | // assert(is_non_err != .none); | |
| 1667 | // const is_non_err_tv = try sema.resolveInstConst(block, operand_src, is_non_err); | |
| 1668 | // if (is_non_err_tv.val.toBool()) { | |
| 1669 | // if (is_ptr) { | |
| 1670 | // break :blk try sema.analyzeErrUnionPayloadPtr(block, src, operand, false, false); | |
| 1671 | // } else { | |
| 1672 | // const err_union_ty = sema.typeOf(err_union); | |
| 1673 | // break :blk try sema.analyzeErrUnionPayload(block, src, err_union_ty, operand, operand_src, false); | |
| 1674 | // } | |
| 1675 | // } | |
| 1676 | // const break_data = (try sema.analyzeBodyBreak(block, inline_body)) orelse | |
| 1677 | // break always_noreturn; | |
| 1678 | // if (inst == break_data.block_inst) { | |
| 1679 | // break :blk try sema.resolveInst(break_data.operand); | |
| 1680 | // } else { | |
| 1681 | // break break_data.inst; | |
| 1682 | // } | |
| 1683 | //}, | |
| 1684 | 1643 | .try_ptr => blk: { |
| 1685 | 1644 | if (!block.is_comptime) break :blk try sema.zirTryPtr(block, inst); |
| 1686 | 1645 | const inst_data = sema.code.instructions.items(.data)[inst].pl_node; |
| ... | ... | @@ -1707,28 +1666,6 @@ fn analyzeBodyInner( |
| 1707 | 1666 | break break_data.inst; |
| 1708 | 1667 | } |
| 1709 | 1668 | }, |
| 1710 | //.try_ptr_inline => blk: { | |
| 1711 | // const inst_data = sema.code.instructions.items(.data)[inst].pl_node; | |
| 1712 | // const src = inst_data.src(); | |
| 1713 | // const operand_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node }; | |
| 1714 | // const extra = sema.code.extraData(Zir.Inst.Try, inst_data.payload_index); | |
| 1715 | // const inline_body = sema.code.extra[extra.end..][0..extra.data.body_len]; | |
| 1716 | // const operand = try sema.resolveInst(extra.data.operand); | |
| 1717 | // const err_union = try sema.analyzeLoad(block, src, operand, operand_src); | |
| 1718 | // const is_non_err = try sema.analyzeIsNonErrComptimeOnly(block, operand_src, err_union); | |
| 1719 | // assert(is_non_err != .none); | |
| 1720 | // const is_non_err_tv = try sema.resolveInstConst(block, operand_src, is_non_err); | |
| 1721 | // if (is_non_err_tv.val.toBool()) { | |
| 1722 | // break :blk try sema.analyzeErrUnionPayloadPtr(block, src, operand, false, false); | |
| 1723 | // } | |
| 1724 | // const break_data = (try sema.analyzeBodyBreak(block, inline_body)) orelse | |
| 1725 | // break always_noreturn; | |
| 1726 | // if (inst == break_data.block_inst) { | |
| 1727 | // break :blk try sema.resolveInst(break_data.operand); | |
| 1728 | // } else { | |
| 1729 | // break break_data.inst; | |
| 1730 | // } | |
| 1731 | //}, | |
| 1732 | 1669 | .@"defer" => blk: { |
| 1733 | 1670 | const inst_data = sema.code.instructions.items(.data)[inst].@"defer"; |
| 1734 | 1671 | const defer_body = sema.code.extra[inst_data.index..][0..inst_data.len]; |
| ... | ... | @@ -4175,7 +4112,6 @@ fn zirValidateStructInit( |
| 4175 | 4112 | sema: *Sema, |
| 4176 | 4113 | block: *Block, |
| 4177 | 4114 | inst: Zir.Inst.Index, |
| 4178 | is_comptime: bool, | |
| 4179 | 4115 | ) CompileError!void { |
| 4180 | 4116 | const tracy = trace(@src()); |
| 4181 | 4117 | defer tracy.end(); |
| ... | ... | @@ -4194,7 +4130,6 @@ fn zirValidateStructInit( |
| 4194 | 4130 | agg_ty, |
| 4195 | 4131 | init_src, |
| 4196 | 4132 | instrs, |
| 4197 | is_comptime, | |
| 4198 | 4133 | ), |
| 4199 | 4134 | .Union => return sema.validateUnionInit( |
| 4200 | 4135 | block, |
| ... | ... | @@ -4202,7 +4137,6 @@ fn zirValidateStructInit( |
| 4202 | 4137 | init_src, |
| 4203 | 4138 | instrs, |
| 4204 | 4139 | object_ptr, |
| 4205 | is_comptime, | |
| 4206 | 4140 | ), |
| 4207 | 4141 | else => unreachable, |
| 4208 | 4142 | } |
| ... | ... | @@ -4215,7 +4149,6 @@ fn validateUnionInit( |
| 4215 | 4149 | init_src: LazySrcLoc, |
| 4216 | 4150 | instrs: []const Zir.Inst.Index, |
| 4217 | 4151 | union_ptr: Air.Inst.Ref, |
| 4218 | is_comptime: bool, | |
| 4219 | 4152 | ) CompileError!void { |
| 4220 | 4153 | if (instrs.len != 1) { |
| 4221 | 4154 | const msg = msg: { |
| ... | ... | @@ -4238,7 +4171,7 @@ fn validateUnionInit( |
| 4238 | 4171 | return sema.failWithOwnedErrorMsg(msg); |
| 4239 | 4172 | } |
| 4240 | 4173 | |
| 4241 | if ((is_comptime or block.is_comptime) and | |
| 4174 | if (block.is_comptime and | |
| 4242 | 4175 | (try sema.resolveDefinedValue(block, init_src, union_ptr)) != null) |
| 4243 | 4176 | { |
| 4244 | 4177 | // In this case, comptime machinery already did everything. No work to do here. |
| ... | ... | @@ -4342,7 +4275,6 @@ fn validateStructInit( |
| 4342 | 4275 | struct_ty: Type, |
| 4343 | 4276 | init_src: LazySrcLoc, |
| 4344 | 4277 | instrs: []const Zir.Inst.Index, |
| 4345 | is_comptime: bool, | |
| 4346 | 4278 | ) CompileError!void { |
| 4347 | 4279 | const gpa = sema.gpa; |
| 4348 | 4280 | |
| ... | ... | @@ -4382,7 +4314,7 @@ fn validateStructInit( |
| 4382 | 4314 | errdefer if (root_msg) |msg| msg.destroy(sema.gpa); |
| 4383 | 4315 | |
| 4384 | 4316 | const struct_ptr = try sema.resolveInst(struct_ptr_zir_ref); |
| 4385 | if ((is_comptime or block.is_comptime) and | |
| 4317 | if (block.is_comptime and | |
| 4386 | 4318 | (try sema.resolveDefinedValue(block, init_src, struct_ptr)) != null) |
| 4387 | 4319 | { |
| 4388 | 4320 | try sema.resolveStructLayout(struct_ty); |
| ... | ... | @@ -4606,7 +4538,6 @@ fn zirValidateArrayInit( |
| 4606 | 4538 | sema: *Sema, |
| 4607 | 4539 | block: *Block, |
| 4608 | 4540 | inst: Zir.Inst.Index, |
| 4609 | is_comptime: bool, | |
| 4610 | 4541 | ) CompileError!void { |
| 4611 | 4542 | const validate_inst = sema.code.instructions.items(.data)[inst].pl_node; |
| 4612 | 4543 | const init_src = validate_inst.src(); |
| ... | ... | @@ -4654,7 +4585,7 @@ fn zirValidateArrayInit( |
| 4654 | 4585 | else => unreachable, |
| 4655 | 4586 | }; |
| 4656 | 4587 | |
| 4657 | if ((is_comptime or block.is_comptime) and | |
| 4588 | if (block.is_comptime and | |
| 4658 | 4589 | (try sema.resolveDefinedValue(block, init_src, array_ptr)) != null) |
| 4659 | 4590 | { |
| 4660 | 4591 | // In this case the comptime machinery will have evaluated the store instructions |
| ... | ... | @@ -5222,12 +5153,12 @@ fn zirCompileLog( |
| 5222 | 5153 | return Air.Inst.Ref.void_value; |
| 5223 | 5154 | } |
| 5224 | 5155 | |
| 5225 | fn zirPanic(sema: *Sema, block: *Block, inst: Zir.Inst.Index, force_comptime: bool) CompileError!Zir.Inst.Index { | |
| 5156 | fn zirPanic(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Zir.Inst.Index { | |
| 5226 | 5157 | const inst_data = sema.code.instructions.items(.data)[inst].un_node; |
| 5227 | 5158 | const src = inst_data.src(); |
| 5228 | 5159 | const msg_inst = try sema.resolveInst(inst_data.operand); |
| 5229 | 5160 | |
| 5230 | if (block.is_comptime or force_comptime) { | |
| 5161 | if (block.is_comptime) { | |
| 5231 | 5162 | return sema.fail(block, src, "encountered @panic at comptime", .{}); |
| 5232 | 5163 | } |
| 5233 | 5164 | try sema.panicWithMsg(block, src, msg_inst); |
| ... | ... | @@ -5441,7 +5372,7 @@ fn zirSuspendBlock(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) Comp |
| 5441 | 5372 | return sema.failWithUseOfAsync(parent_block, src); |
| 5442 | 5373 | } |
| 5443 | 5374 | |
| 5444 | fn zirBlock(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | |
| 5375 | fn zirBlock(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index, force_comptime: bool) CompileError!Air.Inst.Ref { | |
| 5445 | 5376 | const tracy = trace(@src()); |
| 5446 | 5377 | defer tracy.end(); |
| 5447 | 5378 | |
| ... | ... | @@ -5479,7 +5410,7 @@ fn zirBlock(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileErro |
| 5479 | 5410 | .instructions = .{}, |
| 5480 | 5411 | .label = &label, |
| 5481 | 5412 | .inlining = parent_block.inlining, |
| 5482 | .is_comptime = parent_block.is_comptime, | |
| 5413 | .is_comptime = parent_block.is_comptime or force_comptime, | |
| 5483 | 5414 | .comptime_reason = parent_block.comptime_reason, |
| 5484 | 5415 | .is_typeof = parent_block.is_typeof, |
| 5485 | 5416 | .want_safety = parent_block.want_safety, |
| ... | ... | @@ -17140,7 +17071,7 @@ fn zirUnreachable(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 17140 | 17071 | const inst_data = sema.code.instructions.items(.data)[inst].@"unreachable"; |
| 17141 | 17072 | const src = inst_data.src(); |
| 17142 | 17073 | |
| 17143 | if (block.is_comptime or inst_data.force_comptime) { | |
| 17074 | if (block.is_comptime) { | |
| 17144 | 17075 | return sema.fail(block, src, "reached unreachable code", .{}); |
| 17145 | 17076 | } |
| 17146 | 17077 | // TODO Add compile error for @optimizeFor occurring too late in a scope. |
| ... | ... | @@ -17410,6 +17341,8 @@ fn analyzeRet( |
| 17410 | 17341 | try inlining.merges.results.append(sema.gpa, operand); |
| 17411 | 17342 | _ = try block.addBr(inlining.merges.block_inst, operand); |
| 17412 | 17343 | return always_noreturn; |
| 17344 | } else if (block.is_comptime) { | |
| 17345 | return sema.fail(block, src, "function called at runtime cannot return value at comptime", .{}); | |
| 17413 | 17346 | } |
| 17414 | 17347 | |
| 17415 | 17348 | try sema.resolveTypeLayout(sema.fn_ret_ty); |
| ... | ... | @@ -17422,6 +17355,7 @@ fn analyzeRet( |
| 17422 | 17355 | } |
| 17423 | 17356 | |
| 17424 | 17357 | _ = try block.addUnOp(.ret, operand); |
| 17358 | ||
| 17425 | 17359 | return always_noreturn; |
| 17426 | 17360 | } |
| 17427 | 17361 | |
| ... | ... | @@ -21560,7 +21494,7 @@ fn zirBuiltinCall(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 21560 | 21494 | switch (modifier) { |
| 21561 | 21495 | // These can be upgraded to comptime or nosuspend calls. |
| 21562 | 21496 | .auto, .never_tail, .no_async => { |
| 21563 | if (extra.flags.is_comptime) { | |
| 21497 | if (block.is_comptime) { | |
| 21564 | 21498 | if (modifier == .never_tail) { |
| 21565 | 21499 | return sema.fail(block, modifier_src, "unable to perform 'never_tail' call at compile-time", .{}); |
| 21566 | 21500 | } |
| ... | ... | @@ -21575,12 +21509,12 @@ fn zirBuiltinCall(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 21575 | 21509 | return sema.fail(block, func_src, "modifier '{s}' requires a comptime-known function", .{@tagName(modifier)}); |
| 21576 | 21510 | }; |
| 21577 | 21511 | |
| 21578 | if (extra.flags.is_comptime) { | |
| 21512 | if (block.is_comptime) { | |
| 21579 | 21513 | modifier = .compile_time; |
| 21580 | 21514 | } |
| 21581 | 21515 | }, |
| 21582 | 21516 | .always_tail => { |
| 21583 | if (extra.flags.is_comptime) { | |
| 21517 | if (block.is_comptime) { | |
| 21584 | 21518 | modifier = .compile_time; |
| 21585 | 21519 | } |
| 21586 | 21520 | }, |
| ... | ... | @@ -21588,12 +21522,12 @@ fn zirBuiltinCall(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 21588 | 21522 | if (extra.flags.is_nosuspend) { |
| 21589 | 21523 | return sema.fail(block, modifier_src, "modifier 'async_kw' cannot be used inside nosuspend block", .{}); |
| 21590 | 21524 | } |
| 21591 | if (extra.flags.is_comptime) { | |
| 21525 | if (block.is_comptime) { | |
| 21592 | 21526 | return sema.fail(block, modifier_src, "modifier 'async_kw' cannot be used in combination with comptime function call", .{}); |
| 21593 | 21527 | } |
| 21594 | 21528 | }, |
| 21595 | 21529 | .never_inline => { |
| 21596 | if (extra.flags.is_comptime) { | |
| 21530 | if (block.is_comptime) { | |
| 21597 | 21531 | return sema.fail(block, modifier_src, "unable to perform 'never_inline' call at compile-time", .{}); |
| 21598 | 21532 | } |
| 21599 | 21533 | }, |
src/Zir.zig+11-34| ... | ... | @@ -258,6 +258,9 @@ pub const Inst = struct { |
| 258 | 258 | /// A labeled block of code, which can return a value. |
| 259 | 259 | /// Uses the `pl_node` union field. Payload is `Block`. |
| 260 | 260 | block, |
| 261 | /// Like `block`, but forces full evaluation of its contents at compile-time. | |
| 262 | /// Uses the `pl_node` union field. Payload is `Block`. | |
| 263 | block_comptime, | |
| 261 | 264 | /// A list of instructions which are analyzed in the parent context, without |
| 262 | 265 | /// generating a runtime block. Must terminate with an "inline" variant of |
| 263 | 266 | /// a noreturn instruction. |
| ... | ... | @@ -338,14 +341,8 @@ pub const Inst = struct { |
| 338 | 341 | /// payload value, as if `err_union_payload_unsafe` was executed on the operand. |
| 339 | 342 | /// Uses the `pl_node` union field. Payload is `Try`. |
| 340 | 343 | @"try", |
| 341 | ///// Same as `try` except the operand is coerced to a comptime value, and | |
| 342 | ///// only the taken branch is analyzed. The block must terminate with an "inline" | |
| 343 | ///// variant of a noreturn instruction. | |
| 344 | //try_inline, | |
| 345 | 344 | /// Same as `try` except the operand is a pointer and the result is a pointer. |
| 346 | 345 | try_ptr, |
| 347 | ///// Same as `try_inline` except the operand is a pointer and the result is a pointer. | |
| 348 | //try_ptr_inline, | |
| 349 | 346 | /// An error set type definition. Contains a list of field names. |
| 350 | 347 | /// Uses the `pl_node` union field. Payload is `ErrorSetDecl`. |
| 351 | 348 | error_set_decl, |
| ... | ... | @@ -723,9 +720,6 @@ pub const Inst = struct { |
| 723 | 720 | /// because it must use one of them to find out the struct type. |
| 724 | 721 | /// Uses the `pl_node` field. Payload is `Block`. |
| 725 | 722 | validate_struct_init, |
| 726 | /// Same as `validate_struct_init` but additionally communicates that the | |
| 727 | /// resulting struct initialization value is within a comptime scope. | |
| 728 | validate_struct_init_comptime, | |
| 729 | 723 | /// Given a set of `elem_ptr_imm` instructions, assumes they are all part of an |
| 730 | 724 | /// array initialization expression, and emits a compile error if the number of |
| 731 | 725 | /// elements does not match the array type. |
| ... | ... | @@ -733,9 +727,6 @@ pub const Inst = struct { |
| 733 | 727 | /// because it must use one of them to find out the array type. |
| 734 | 728 | /// Uses the `pl_node` field. Payload is `Block`. |
| 735 | 729 | validate_array_init, |
| 736 | /// Same as `validate_array_init` but additionally communicates that the | |
| 737 | /// resulting array initialization value is within a comptime scope. | |
| 738 | validate_array_init_comptime, | |
| 739 | 730 | /// Check that operand type supports the dereference operand (.*). |
| 740 | 731 | /// Uses the `un_node` field. |
| 741 | 732 | validate_deref, |
| ... | ... | @@ -806,8 +797,6 @@ pub const Inst = struct { |
| 806 | 797 | error_name, |
| 807 | 798 | /// Implement builtin `@panic`. Uses `un_node`. |
| 808 | 799 | panic, |
| 809 | /// Same as `panic` but forces comptime. | |
| 810 | panic_comptime, | |
| 811 | 800 | /// Implements `@trap`. |
| 812 | 801 | /// Uses the `node` field. |
| 813 | 802 | trap, |
| ... | ... | @@ -1050,6 +1039,7 @@ pub const Inst = struct { |
| 1050 | 1039 | .bitcast, |
| 1051 | 1040 | .bit_or, |
| 1052 | 1041 | .block, |
| 1042 | .block_comptime, | |
| 1053 | 1043 | .block_inline, |
| 1054 | 1044 | .suspend_block, |
| 1055 | 1045 | .loop, |
| ... | ... | @@ -1162,9 +1152,7 @@ pub const Inst = struct { |
| 1162 | 1152 | .validate_array_init_ty, |
| 1163 | 1153 | .validate_struct_init_ty, |
| 1164 | 1154 | .validate_struct_init, |
| 1165 | .validate_struct_init_comptime, | |
| 1166 | 1155 | .validate_array_init, |
| 1167 | .validate_array_init_comptime, | |
| 1168 | 1156 | .validate_deref, |
| 1169 | 1157 | .struct_init_empty, |
| 1170 | 1158 | .struct_init, |
| ... | ... | @@ -1254,8 +1242,6 @@ pub const Inst = struct { |
| 1254 | 1242 | .ret_type, |
| 1255 | 1243 | .@"try", |
| 1256 | 1244 | .try_ptr, |
| 1257 | //.try_inline, | |
| 1258 | //.try_ptr_inline, | |
| 1259 | 1245 | .@"defer", |
| 1260 | 1246 | .defer_err_code, |
| 1261 | 1247 | .save_err_ret_index, |
| ... | ... | @@ -1276,7 +1262,6 @@ pub const Inst = struct { |
| 1276 | 1262 | .repeat, |
| 1277 | 1263 | .repeat_inline, |
| 1278 | 1264 | .panic, |
| 1279 | .panic_comptime, | |
| 1280 | 1265 | .trap, |
| 1281 | 1266 | .check_comptime_control_flow, |
| 1282 | 1267 | => true, |
| ... | ... | @@ -1318,9 +1303,7 @@ pub const Inst = struct { |
| 1318 | 1303 | .validate_array_init_ty, |
| 1319 | 1304 | .validate_struct_init_ty, |
| 1320 | 1305 | .validate_struct_init, |
| 1321 | .validate_struct_init_comptime, | |
| 1322 | 1306 | .validate_array_init, |
| 1323 | .validate_array_init_comptime, | |
| 1324 | 1307 | .validate_deref, |
| 1325 | 1308 | .@"export", |
| 1326 | 1309 | .export_value, |
| ... | ... | @@ -1365,6 +1348,7 @@ pub const Inst = struct { |
| 1365 | 1348 | .bitcast, |
| 1366 | 1349 | .bit_or, |
| 1367 | 1350 | .block, |
| 1351 | .block_comptime, | |
| 1368 | 1352 | .block_inline, |
| 1369 | 1353 | .suspend_block, |
| 1370 | 1354 | .loop, |
| ... | ... | @@ -1552,13 +1536,10 @@ pub const Inst = struct { |
| 1552 | 1536 | .repeat, |
| 1553 | 1537 | .repeat_inline, |
| 1554 | 1538 | .panic, |
| 1555 | .panic_comptime, | |
| 1556 | 1539 | .trap, |
| 1557 | 1540 | .for_len, |
| 1558 | 1541 | .@"try", |
| 1559 | 1542 | .try_ptr, |
| 1560 | //.try_inline, | |
| 1561 | //.try_ptr_inline, | |
| 1562 | 1543 | => false, |
| 1563 | 1544 | |
| 1564 | 1545 | .extended => switch (data.extended.opcode) { |
| ... | ... | @@ -1603,6 +1584,7 @@ pub const Inst = struct { |
| 1603 | 1584 | .bit_not = .un_node, |
| 1604 | 1585 | .bit_or = .pl_node, |
| 1605 | 1586 | .block = .pl_node, |
| 1587 | .block_comptime = .pl_node, | |
| 1606 | 1588 | .block_inline = .pl_node, |
| 1607 | 1589 | .suspend_block = .pl_node, |
| 1608 | 1590 | .bool_not = .un_node, |
| ... | ... | @@ -1624,8 +1606,6 @@ pub const Inst = struct { |
| 1624 | 1606 | .condbr_inline = .pl_node, |
| 1625 | 1607 | .@"try" = .pl_node, |
| 1626 | 1608 | .try_ptr = .pl_node, |
| 1627 | //.try_inline = .pl_node, | |
| 1628 | //.try_ptr_inline = .pl_node, | |
| 1629 | 1609 | .error_set_decl = .pl_node, |
| 1630 | 1610 | .error_set_decl_anon = .pl_node, |
| 1631 | 1611 | .error_set_decl_func = .pl_node, |
| ... | ... | @@ -1721,9 +1701,7 @@ pub const Inst = struct { |
| 1721 | 1701 | .validate_array_init_ty = .pl_node, |
| 1722 | 1702 | .validate_struct_init_ty = .un_node, |
| 1723 | 1703 | .validate_struct_init = .pl_node, |
| 1724 | .validate_struct_init_comptime = .pl_node, | |
| 1725 | 1704 | .validate_array_init = .pl_node, |
| 1726 | .validate_array_init_comptime = .pl_node, | |
| 1727 | 1705 | .validate_deref = .un_node, |
| 1728 | 1706 | .struct_init_empty = .un_node, |
| 1729 | 1707 | .field_type = .pl_node, |
| ... | ... | @@ -1750,7 +1728,6 @@ pub const Inst = struct { |
| 1750 | 1728 | .embed_file = .un_node, |
| 1751 | 1729 | .error_name = .un_node, |
| 1752 | 1730 | .panic = .un_node, |
| 1753 | .panic_comptime = .un_node, | |
| 1754 | 1731 | .trap = .node, |
| 1755 | 1732 | .set_runtime_safety = .un_node, |
| 1756 | 1733 | .sqrt = .un_node, |
| ... | ... | @@ -2605,7 +2582,6 @@ pub const Inst = struct { |
| 2605 | 2582 | /// Offset from Decl AST node index. |
| 2606 | 2583 | /// `Tag` determines which kind of AST node this points to. |
| 2607 | 2584 | src_node: i32, |
| 2608 | force_comptime: bool, | |
| 2609 | 2585 | |
| 2610 | 2586 | pub fn src(self: @This()) LazySrcLoc { |
| 2611 | 2587 | return LazySrcLoc.nodeOffset(self.src_node); |
| ... | ... | @@ -2920,9 +2896,8 @@ pub const Inst = struct { |
| 2920 | 2896 | |
| 2921 | 2897 | pub const Flags = packed struct { |
| 2922 | 2898 | is_nosuspend: bool, |
| 2923 | is_comptime: bool, | |
| 2924 | 2899 | ensure_result_used: bool, |
| 2925 | _: u29 = undefined, | |
| 2900 | _: u30 = undefined, | |
| 2926 | 2901 | |
| 2927 | 2902 | comptime { |
| 2928 | 2903 | if (@sizeOf(Flags) != 4 or @bitSizeOf(Flags) != 32) |
| ... | ... | @@ -3912,7 +3887,7 @@ fn findDeclsInner( |
| 3912 | 3887 | |
| 3913 | 3888 | // Block instructions, recurse over the bodies. |
| 3914 | 3889 | |
| 3915 | .block, .block_inline => { | |
| 3890 | .block, .block_comptime, .block_inline => { | |
| 3916 | 3891 | const inst_data = datas[inst].pl_node; |
| 3917 | 3892 | const extra = zir.extraData(Inst.Block, inst_data.payload_index); |
| 3918 | 3893 | const body = zir.extra[extra.end..][0..extra.data.body_len]; |
| ... | ... | @@ -4139,7 +4114,9 @@ pub fn getFnInfo(zir: Zir, fn_inst: Inst.Index) FnInfo { |
| 4139 | 4114 | }, |
| 4140 | 4115 | else => unreachable, |
| 4141 | 4116 | }; |
| 4142 | assert(tags[info.param_block] == .block or tags[info.param_block] == .block_inline); | |
| 4117 | assert(tags[info.param_block] == .block or | |
| 4118 | tags[info.param_block] == .block_comptime or | |
| 4119 | tags[info.param_block] == .block_inline); | |
| 4143 | 4120 | const param_block = zir.extraData(Inst.Block, datas[info.param_block].pl_node.payload_index); |
| 4144 | 4121 | const param_body = zir.extra[param_block.end..][0..param_block.data.body_len]; |
| 4145 | 4122 | var total_params_len: u32 = 0; |
src/print_zir.zig+1-4| ... | ... | @@ -195,7 +195,6 @@ const Writer = struct { |
| 195 | 195 | .embed_file, |
| 196 | 196 | .error_name, |
| 197 | 197 | .panic, |
| 198 | .panic_comptime, | |
| 199 | 198 | .set_runtime_safety, |
| 200 | 199 | .sqrt, |
| 201 | 200 | .sin, |
| ... | ... | @@ -365,13 +364,12 @@ const Writer = struct { |
| 365 | 364 | .call => try self.writeCall(stream, inst), |
| 366 | 365 | |
| 367 | 366 | .block, |
| 367 | .block_comptime, | |
| 368 | 368 | .block_inline, |
| 369 | 369 | .suspend_block, |
| 370 | 370 | .loop, |
| 371 | 371 | .validate_struct_init, |
| 372 | .validate_struct_init_comptime, | |
| 373 | 372 | .validate_array_init, |
| 374 | .validate_array_init_comptime, | |
| 375 | 373 | .c_import, |
| 376 | 374 | .typeof_builtin, |
| 377 | 375 | => try self.writeBlock(stream, inst), |
| ... | ... | @@ -811,7 +809,6 @@ const Writer = struct { |
| 811 | 809 | |
| 812 | 810 | try self.writeFlag(stream, "nodiscard ", extra.flags.ensure_result_used); |
| 813 | 811 | try self.writeFlag(stream, "nosuspend ", extra.flags.is_nosuspend); |
| 814 | try self.writeFlag(stream, "comptime ", extra.flags.is_comptime); | |
| 815 | 812 | |
| 816 | 813 | try self.writeInstRef(stream, extra.modifier); |
| 817 | 814 | try stream.writeAll(", "); |
test/behavior/cast.zig+1-10| ... | ... | @@ -1455,7 +1455,7 @@ test "floatToInt to zero-bit int" { |
| 1455 | 1455 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1456 | 1456 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1457 | 1457 | |
| 1458 | var a: f32 = 0.0; | |
| 1458 | const a: f32 = 0.0; | |
| 1459 | 1459 | comptime try std.testing.expect(@floatToInt(u0, a) == 0); |
| 1460 | 1460 | } |
| 1461 | 1461 | |
| ... | ... | @@ -1507,15 +1507,6 @@ test "optional pointer coerced to optional allowzero pointer" { |
| 1507 | 1507 | try expect(@ptrToInt(q.?) == 4); |
| 1508 | 1508 | } |
| 1509 | 1509 | |
| 1510 | test "ptrToInt on const inside comptime block" { | |
| 1511 | var a = comptime blk: { | |
| 1512 | const b: u8 = 1; | |
| 1513 | const c = @ptrToInt(&b); | |
| 1514 | break :blk c; | |
| 1515 | }; | |
| 1516 | try expect(@intToPtr(*const u8, a).* == 1); | |
| 1517 | } | |
| 1518 | ||
| 1519 | 1510 | test "single item pointer to pointer to array to slice" { |
| 1520 | 1511 | var x: i32 = 1234; |
| 1521 | 1512 | try expect(@as([]const i32, @as(*[1]i32, &x))[0] == 1234); |
test/behavior/eval.zig+1-3| ... | ... | @@ -181,9 +181,7 @@ fn testTryToTrickEvalWithRuntimeIf(b: bool) usize { |
| 181 | 181 | const result = if (b) false else true; |
| 182 | 182 | _ = result; |
| 183 | 183 | } |
| 184 | comptime { | |
| 185 | return i; | |
| 186 | } | |
| 184 | return comptime i; | |
| 187 | 185 | } |
| 188 | 186 | |
| 189 | 187 | test "@setEvalBranchQuota" { |
test/cases/compile_errors/branch_in_comptime_only_scope_uses_condbr_inline.zig+3-4| ... | ... | @@ -16,7 +16,6 @@ pub export fn entry2() void { |
| 16 | 16 | // backend=stage2 |
| 17 | 17 | // target=native |
| 18 | 18 | // |
| 19 | // :4:15: error: unable to resolve comptime value | |
| 20 | // :4:15: note: condition in comptime branch must be comptime-known | |
| 21 | // :11:11: error: unable to resolve comptime value | |
| 22 | // :11:11: note: condition in comptime branch must be comptime-known | |
| 19 | // :4:15: error: unable to evaluate comptime expression | |
| 20 | // :4:13: note: operation is runtime due to this operand | |
| 21 | // :11:11: error: unable to evaluate comptime expression |
test/cases/compile_errors/ignored_comptime_value.zig+4-10| ... | ... | @@ -5,13 +5,7 @@ export fn b() void { |
| 5 | 5 | comptime bar(); |
| 6 | 6 | } |
| 7 | 7 | fn bar() u8 { |
| 8 | const u32_max = @import("std").math.maxInt(u32); | |
| 9 | ||
| 10 | @setEvalBranchQuota(u32_max); | |
| 11 | var x: u32 = 0; | |
| 12 | while (x != u32_max) : (x +%= 1) {} | |
| 13 | ||
| 14 | return 0; | |
| 8 | return 2; | |
| 15 | 9 | } |
| 16 | 10 | |
| 17 | 11 | // error |
| ... | ... | @@ -21,6 +15,6 @@ fn bar() u8 { |
| 21 | 15 | // :2:5: error: value of type 'comptime_int' ignored |
| 22 | 16 | // :2:5: note: all non-void values must be used |
| 23 | 17 | // :2:5: note: this error can be suppressed by assigning the value to '_' |
| 24 | // :5:17: error: value of type 'u8' ignored | |
| 25 | // :5:17: note: all non-void values must be used | |
| 26 | // :5:17: note: this error can be suppressed by assigning the value to '_' | |
| 18 | // :5:5: error: value of type 'u8' ignored | |
| 19 | // :5:5: note: all non-void values must be used | |
| 20 | // :5:5: note: this error can be suppressed by assigning the value to '_' |
test/src/Cases.zig+3-3| ... | ... | @@ -718,7 +718,7 @@ const TestManifestConfigDefaults = struct { |
| 718 | 718 | if (@"type" == .@"error") { |
| 719 | 719 | return "native"; |
| 720 | 720 | } |
| 721 | comptime { | |
| 721 | return comptime blk: { | |
| 722 | 722 | var defaults: []const u8 = ""; |
| 723 | 723 | // TODO should we only return "mainstream" targets by default here? |
| 724 | 724 | // TODO we should also specify ABIs explicitly as the backends are |
| ... | ... | @@ -735,8 +735,8 @@ const TestManifestConfigDefaults = struct { |
| 735 | 735 | defaults = defaults ++ "x86_64-windows" ++ ","; |
| 736 | 736 | // Wasm |
| 737 | 737 | defaults = defaults ++ "wasm32-wasi"; |
| 738 | return defaults; | |
| 739 | } | |
| 738 | break :blk defaults; | |
| 739 | }; | |
| 740 | 740 | } else if (std.mem.eql(u8, key, "output_mode")) { |
| 741 | 741 | return switch (@"type") { |
| 742 | 742 | .@"error" => "Obj", |