authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2023-03-05 12:39:32+00:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-04-12 12:06:19-04:00
logccf670c2b04ebeb9db43eb9f5c47c6cf03e4b1d0
tree3f7899bf6231500782af185ffe701ee66793e226
parent602029bb2fb78048e46136784e717b57b8de8f2c

Zir: implement explicit block_comptime instruction

Resolves: #7056

18 files changed, 234 insertions(+), 304 deletions(-)

lib/std/Build/Cache.zig+2-2
...@@ -374,7 +374,7 @@ pub const Manifest = struct {...@@ -374,7 +374,7 @@ pub const Manifest = struct {
374 self.failed_file_index = null;374 self.failed_file_index = null;
375375
376 const ext = ".txt";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;
378378
379 var bin_digest: BinDigest = undefined;379 var bin_digest: BinDigest = undefined;
380 self.hash.hasher.final(&bin_digest);380 self.hash.hasher.final(&bin_digest);
...@@ -389,7 +389,7 @@ pub const Manifest = struct {...@@ -389,7 +389,7 @@ pub const Manifest = struct {
389 self.hash.hasher.update(&bin_digest);389 self.hash.hasher.update(&bin_digest);
390390
391 mem.copy(u8, &manifest_file_path, &self.hex_digest);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.*;
393393
394 if (self.files.items.len == 0) {394 if (self.files.items.len == 0) {
395 // If there are no file inputs, we check if the manifest file exists instead of395 // 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,7 +622,7 @@ test "ed25519 test vectors" {
622 },622 },
623 };623 };
624 for (entries) |entry| {624 for (entries) |entry| {
625 var msg: [entry.msg_hex.len / 2]u8 = undefined;625 var msg: [64 / 2]u8 = undefined;
626 _ = try fmt.hexToBytes(&msg, entry.msg_hex);626 _ = try fmt.hexToBytes(&msg, entry.msg_hex);
627 var public_key_bytes: [32]u8 = undefined;627 var public_key_bytes: [32]u8 = undefined;
628 _ = try fmt.hexToBytes(&public_key_bytes, entry.public_key_hex);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,9 +177,9 @@ test "std.enums.directEnumArrayDefault slice" {
177/// Cast an enum literal, value, or string to the enum value of type E177/// Cast an enum literal, value, or string to the enum value of type E
178/// with the same name.178/// with the same name.
179pub fn nameCast(comptime E: type, comptime value: anytype) E {179pub fn nameCast(comptime E: type, comptime value: anytype) E {
180 comptime {180 return comptime blk: {
181 const V = @TypeOf(value);181 const V = @TypeOf(value);
182 if (V == E) return value;182 if (V == E) break :blk value;
183 var name: ?[]const u8 = switch (@typeInfo(V)) {183 var name: ?[]const u8 = switch (@typeInfo(V)) {
184 .EnumLiteral, .Enum => @tagName(value),184 .EnumLiteral, .Enum => @tagName(value),
185 .Pointer => if (std.meta.trait.isZigString(V)) value else null,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,12 +187,12 @@ pub fn nameCast(comptime E: type, comptime value: anytype) E {
187 };187 };
188 if (name) |n| {188 if (name) |n| {
189 if (@hasField(E, n)) {189 if (@hasField(E, n)) {
190 return @field(E, n);190 break :blk @field(E, n);
191 }191 }
192 @compileError("Enum " ++ @typeName(E) ++ " has no field named " ++ n);192 @compileError("Enum " ++ @typeName(E) ++ " has no field named " ++ n);
193 }193 }
194 @compileError("Cannot cast from " ++ @typeName(@TypeOf(value)) ++ " to " ++ @typeName(E));194 @compileError("Cannot cast from " ++ @typeName(@TypeOf(value)) ++ " to " ++ @typeName(E));
195 }195 };
196}196}
197197
198test "std.enums.nameCast" {198test "std.enums.nameCast" {
lib/std/math.zig+1-1
...@@ -877,7 +877,7 @@ fn testDivFloor() !void {...@@ -877,7 +877,7 @@ fn testDivFloor() !void {
877/// zero.877/// zero.
878pub fn divCeil(comptime T: type, numerator: T, denominator: T) !T {878pub fn divCeil(comptime T: type, numerator: T, denominator: T) !T {
879 @setRuntimeSafety(false);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 const info = @typeInfo(T);881 const info = @typeInfo(T);
882 switch (info) {882 switch (info) {
883 .ComptimeFloat, .Float => return @ceil(numerator / denominator),883 .ComptimeFloat, .Float => return @ceil(numerator / denominator),
lib/std/meta.zig+6-6
...@@ -549,14 +549,14 @@ test "std.meta.FieldType" {...@@ -549,14 +549,14 @@ test "std.meta.FieldType" {
549}549}
550550
551pub fn fieldNames(comptime T: type) *const [fields(T).len][]const u8 {551pub fn fieldNames(comptime T: type) *const [fields(T).len][]const u8 {
552 comptime {552 return comptime blk: {
553 const fieldInfos = fields(T);553 const fieldInfos = fields(T);
554 var names: [fieldInfos.len][]const u8 = undefined;554 var names: [fieldInfos.len][]const u8 = undefined;
555 for (fieldInfos, 0..) |field, i| {555 for (fieldInfos, 0..) |field, i| {
556 names[i] = field.name;556 names[i] = field.name;
557 }557 }
558 return &names;558 break :blk &names;
559 }559 };
560}560}
561561
562test "std.meta.fieldNames" {562test "std.meta.fieldNames" {
...@@ -590,14 +590,14 @@ test "std.meta.fieldNames" {...@@ -590,14 +590,14 @@ test "std.meta.fieldNames" {
590/// Given an enum or error set type, returns a pointer to an array containing all tags for that590/// Given an enum or error set type, returns a pointer to an array containing all tags for that
591/// enum or error set.591/// enum or error set.
592pub fn tags(comptime T: type) *const [fields(T).len]T {592pub fn tags(comptime T: type) *const [fields(T).len]T {
593 comptime {593 return comptime blk: {
594 const fieldInfos = fields(T);594 const fieldInfos = fields(T);
595 var res: [fieldInfos.len]T = undefined;595 var res: [fieldInfos.len]T = undefined;
596 for (fieldInfos, 0..) |field, i| {596 for (fieldInfos, 0..) |field, i| {
597 res[i] = @field(T, field.name);597 res[i] = @field(T, field.name);
598 }598 }
599 return &res;599 break :blk &res;
600 }600 };
601}601}
602602
603test "std.meta.tags" {603test "std.meta.tags" {
lib/std/meta/trait.zig+7-7
...@@ -400,18 +400,18 @@ test "isTuple" {...@@ -400,18 +400,18 @@ test "isTuple" {
400/// *const u8, ?[]const u8, ?*const [N]u8.400/// *const u8, ?[]const u8, ?*const [N]u8.
401/// ```401/// ```
402pub fn isZigString(comptime T: type) bool {402pub fn isZigString(comptime T: type) bool {
403 comptime {403 return comptime blk: {
404 // Only pointer types can be strings, no optionals404 // Only pointer types can be strings, no optionals
405 const info = @typeInfo(T);405 const info = @typeInfo(T);
406 if (info != .Pointer) return false;406 if (info != .Pointer) break :blk false;
407407
408 const ptr = &info.Pointer;408 const ptr = &info.Pointer;
409 // Check for CV qualifiers that would prevent coerction to []const u8409 // 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;
411411
412 // If it's already a slice, simple check.412 // If it's already a slice, simple check.
413 if (ptr.size == .Slice) {413 if (ptr.size == .Slice) {
414 return ptr.child == u8;414 break :blk ptr.child == u8;
415 }415 }
416416
417 // Otherwise check if it's an array type that coerces to slice.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,12 +419,12 @@ pub fn isZigString(comptime T: type) bool {
419 const child = @typeInfo(ptr.child);419 const child = @typeInfo(ptr.child);
420 if (child == .Array) {420 if (child == .Array) {
421 const arr = &child.Array;421 const arr = &child.Array;
422 return arr.child == u8;422 break :blk arr.child == u8;
423 }423 }
424 }424 }
425425
426 return false;426 break :blk false;
427 }427 };
428}428}
429429
430test "isZigString" {430test "isZigString" {
lib/std/net/test.zig+1-1
...@@ -99,7 +99,7 @@ test "parse and render UNIX addresses" {...@@ -99,7 +99,7 @@ test "parse and render UNIX addresses" {
99 const fmt_addr = std.fmt.bufPrint(buffer[0..], "{}", .{addr}) catch unreachable;99 const fmt_addr = std.fmt.bufPrint(buffer[0..], "{}", .{addr}) catch unreachable;
100 try std.testing.expectEqualSlices(u8, "/tmp/testpath", fmt_addr);100 try std.testing.expectEqualSlices(u8, "/tmp/testpath", fmt_addr);
101101
102 const too_long = [_]u8{'a'} ** (addr.un.path.len + 1);102 const too_long = [_]u8{'a'} ** 200;
103 try testing.expectError(error.NameTooLong, net.Address.initUnix(too_long[0..]));103 try testing.expectError(error.NameTooLong, net.Address.initUnix(too_long[0..]));
104}104}
105105
lib/std/unicode.zig+3-3
...@@ -774,13 +774,13 @@ test "utf8ToUtf16LeWithNull" {...@@ -774,13 +774,13 @@ test "utf8ToUtf16LeWithNull" {
774774
775/// Converts a UTF-8 string literal into a UTF-16LE string literal.775/// Converts a UTF-8 string literal into a UTF-16LE string literal.
776pub fn utf8ToUtf16LeStringLiteral(comptime utf8: []const u8) *const [calcUtf16LeLen(utf8) catch unreachable:0]u16 {776pub fn utf8ToUtf16LeStringLiteral(comptime utf8: []const u8) *const [calcUtf16LeLen(utf8) catch unreachable:0]u16 {
777 comptime {777 return comptime blk: {
778 const len: usize = calcUtf16LeLen(utf8) catch |err| @compileError(err);778 const len: usize = calcUtf16LeLen(utf8) catch |err| @compileError(err);
779 var utf16le: [len:0]u16 = [_:0]u16{0} ** len;779 var utf16le: [len:0]u16 = [_:0]u16{0} ** len;
780 const utf16le_len = utf8ToUtf16Le(&utf16le, utf8[0..]) catch |err| @compileError(err);780 const utf16le_len = utf8ToUtf16Le(&utf16le, utf8[0..]) catch |err| @compileError(err);
781 assert(len == utf16le_len);781 assert(len == utf16le_len);
782 return &utf16le;782 break :blk &utf16le;
783 }783 };
784}784}
785785
786const CalcUtf16LeLenError = Utf8DecodeError || error{Utf8InvalidStartByte};786const CalcUtf16LeLenError = Utf8DecodeError || error{Utf8InvalidStartByte};
lib/std/zig/system/linux.zig+5-3
...@@ -147,7 +147,9 @@ test "cpuinfo: PowerPC" {...@@ -147,7 +147,9 @@ test "cpuinfo: PowerPC" {
147}147}
148148
149const ArmCpuinfoImpl = struct {149const ArmCpuinfoImpl = struct {
150 cores: [4]CoreInfo = undefined,150 const num_cores = 4;
151
152 cores: [num_cores]CoreInfo = undefined,
151 core_no: usize = 0,153 core_no: usize = 0,
152 have_fields: usize = 0,154 have_fields: usize = 0,
153155
...@@ -162,7 +164,7 @@ const ArmCpuinfoImpl = struct {...@@ -162,7 +164,7 @@ const ArmCpuinfoImpl = struct {
162 const cpu_models = @import("arm.zig").cpu_models;164 const cpu_models = @import("arm.zig").cpu_models;
163165
164 fn addOne(self: *ArmCpuinfoImpl) void {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 if (self.core_no > 0) {168 if (self.core_no > 0) {
167 // Deduplicate the core info.169 // Deduplicate the core info.
168 for (self.cores[0..self.core_no]) |it| {170 for (self.cores[0..self.core_no]) |it| {
...@@ -222,7 +224,7 @@ const ArmCpuinfoImpl = struct {...@@ -222,7 +224,7 @@ const ArmCpuinfoImpl = struct {
222 else => false,224 else => false,
223 };225 };
224226
225 var known_models: [self.cores.len]?*const Target.Cpu.Model = undefined;227 var known_models: [num_cores]?*const Target.Cpu.Model = undefined;
226 for (self.cores[0..self.core_no], 0..) |core, i| {228 for (self.cores[0..self.core_no], 0..) |core, i| {
227 known_models[i] = cpu_models.isKnown(.{229 known_models[i] = cpu_models.isKnown(.{
228 .architecture = core.architecture,230 .architecture = core.architecture,
src/AstGen.zig+157-119
...@@ -137,7 +137,7 @@ pub fn generate(gpa: Allocator, tree: Ast) Allocator.Error!Zir {...@@ -137,7 +137,7 @@ pub fn generate(gpa: Allocator, tree: Ast) Allocator.Error!Zir {
137137
138 var gz_instructions: std.ArrayListUnmanaged(Zir.Inst.Index) = .{};138 var gz_instructions: std.ArrayListUnmanaged(Zir.Inst.Index) = .{};
139 var gen_scope: GenZir = .{139 var gen_scope: GenZir = .{
140 .force_comptime = true,140 .is_comptime = true,
141 .parent = &top_scope.base,141 .parent = &top_scope.base,
142 .anon_name_strategy = .parent,142 .anon_name_strategy = .parent,
143 .decl_node_index = 0,143 .decl_node_index = 0,
...@@ -362,11 +362,7 @@ const type_ri: ResultInfo = .{ .rl = .{ .ty = .type_type } };...@@ -362,11 +362,7 @@ const type_ri: ResultInfo = .{ .rl = .{ .ty = .type_type } };
362const coerced_type_ri: ResultInfo = .{ .rl = .{ .coerced_ty = .type_type } };362const coerced_type_ri: ResultInfo = .{ .rl = .{ .coerced_ty = .type_type } };
363363
364fn typeExpr(gz: *GenZir, scope: *Scope, type_node: Ast.Node.Index) InnerError!Zir.Inst.Ref {364fn typeExpr(gz: *GenZir, scope: *Scope, type_node: Ast.Node.Index) InnerError!Zir.Inst.Ref {
365 const prev_force_comptime = gz.force_comptime;365 return comptimeExpr(gz, scope, coerced_type_ri, type_node);
366 gz.force_comptime = true;
367 defer gz.force_comptime = prev_force_comptime;
368
369 return expr(gz, scope, coerced_type_ri, type_node);
370}366}
371367
372fn reachableTypeExpr(368fn reachableTypeExpr(
...@@ -375,11 +371,7 @@ fn reachableTypeExpr(...@@ -375,11 +371,7 @@ fn reachableTypeExpr(
375 type_node: Ast.Node.Index,371 type_node: Ast.Node.Index,
376 reachable_node: Ast.Node.Index,372 reachable_node: Ast.Node.Index,
377) InnerError!Zir.Inst.Ref {373) InnerError!Zir.Inst.Ref {
378 const prev_force_comptime = gz.force_comptime;374 return reachableExprComptime(gz, scope, coerced_type_ri, type_node, reachable_node, true);
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);
383}375}
384376
385/// Same as `expr` but fails with a compile error if the result type is `noreturn`.377/// Same as `expr` but fails with a compile error if the result type is `noreturn`.
...@@ -401,11 +393,11 @@ fn reachableExprComptime(...@@ -401,11 +393,11 @@ fn reachableExprComptime(
401 reachable_node: Ast.Node.Index,393 reachable_node: Ast.Node.Index,
402 force_comptime: bool,394 force_comptime: bool,
403) InnerError!Zir.Inst.Ref {395) InnerError!Zir.Inst.Ref {
404 const prev_force_comptime = gz.force_comptime;396 const result_inst = if (force_comptime)
405 gz.force_comptime = prev_force_comptime or force_comptime;397 try comptimeExpr(gz, scope, ri, node)
406 defer gz.force_comptime = prev_force_comptime;398 else
399 try expr(gz, scope, ri, node);
407400
408 const result_inst = try expr(gz, scope, ri, node);
409 if (gz.refIsNoReturn(result_inst)) {401 if (gz.refIsNoReturn(result_inst)) {
410 try gz.astgen.appendErrorNodeNotes(reachable_node, "unreachable code", .{}, &[_]u32{402 try gz.astgen.appendErrorNodeNotes(reachable_node, "unreachable code", .{}, &[_]u32{
411 try gz.astgen.errNoteNode(node, "control flow is diverted here", .{}),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,7 +817,6 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE
825 _ = try gz.addAsIndex(.{817 _ = try gz.addAsIndex(.{
826 .tag = .@"unreachable",818 .tag = .@"unreachable",
827 .data = .{ .@"unreachable" = .{819 .data = .{ .@"unreachable" = .{
828 .force_comptime = gz.force_comptime,
829 .src_node = gz.nodeIndexToRelative(node),820 .src_node = gz.nodeIndexToRelative(node),
830 } },821 } },
831 });822 });
...@@ -1578,12 +1569,7 @@ fn arrayInitExprRlPtrInner(...@@ -1578,12 +1569,7 @@ fn arrayInitExprRlPtrInner(
1578 _ = try expr(gz, scope, .{ .rl = .{ .ptr = .{ .inst = elem_ptr } } }, elem_init);1569 _ = try expr(gz, scope, .{ .rl = .{ .ptr = .{ .inst = elem_ptr } } }, elem_init);
1579 }1570 }
15801571
1581 const tag: Zir.Inst.Tag = if (gz.force_comptime)1572 _ = try gz.addPlNodePayloadIndex(.validate_array_init, node, payload_index);
1582 .validate_array_init_comptime
1583 else
1584 .validate_array_init;
1585
1586 _ = try gz.addPlNodePayloadIndex(tag, node, payload_index);
1587 return .void_value;1573 return .void_value;
1588}1574}
15891575
...@@ -1800,12 +1786,7 @@ fn structInitExprRlPtrInner(...@@ -1800,12 +1786,7 @@ fn structInitExprRlPtrInner(
1800 _ = try expr(gz, scope, .{ .rl = .{ .ptr = .{ .inst = field_ptr } } }, field_init);1786 _ = try expr(gz, scope, .{ .rl = .{ .ptr = .{ .inst = field_ptr } } }, field_init);
1801 }1787 }
18021788
1803 const tag: Zir.Inst.Tag = if (gz.force_comptime)1789 _ = try gz.addPlNodePayloadIndex(.validate_struct_init, node, payload_index);
1804 .validate_struct_init_comptime
1805 else
1806 .validate_struct_init;
1807
1808 _ = try gz.addPlNodePayloadIndex(tag, node, payload_index);
1809 return Zir.Inst.Ref.void_value;1790 return Zir.Inst.Ref.void_value;
1810}1791}
18111792
...@@ -1843,23 +1824,105 @@ fn structInitExprRlTy(...@@ -1843,23 +1824,105 @@ fn structInitExprRlTy(
1843 return try gz.addPlNodePayloadIndex(tag, node, payload_index);1824 return try gz.addPlNodePayloadIndex(tag, node, payload_index);
1844}1825}
18451826
1846/// This calls expr in a comptime scope, and is intended to be called as a helper function.1827/// This explicitly calls expr in a comptime scope by wrapping it in a `block_comptime` if
1847/// The one that corresponds to `comptime` expression syntax is `comptimeExprAst`.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`.
1848fn comptimeExpr(1831fn comptimeExpr(
1849 gz: *GenZir,1832 gz: *GenZir,
1850 scope: *Scope,1833 scope: *Scope,
1851 ri: ResultInfo,1834 ri: ResultInfo,
1852 node: Ast.Node.Index,1835 node: Ast.Node.Index,
1853) InnerError!Zir.Inst.Ref {1836) InnerError!Zir.Inst.Ref {
1854 const prev_force_comptime = gz.force_comptime;1837 if (gz.is_comptime) {
1855 gz.force_comptime = true;1838 // No need to change anything!
1856 defer gz.force_comptime = prev_force_comptime;1839 return expr(gz, scope, ri, node);
1840 }
18571841
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}
18601923
1861/// This one is for an actual `comptime` syntax, and will emit a compile error if1924/// 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/// See `comptimeExpr` for the helper function for calling expr in a comptime scope.1926/// See `comptimeExpr` for the helper function for calling expr in a comptime scope.
1864fn comptimeExprAst(1927fn comptimeExprAst(
1865 gz: *GenZir,1928 gz: *GenZir,
...@@ -1868,16 +1931,13 @@ fn comptimeExprAst(...@@ -1868,16 +1931,13 @@ fn comptimeExprAst(
1868 node: Ast.Node.Index,1931 node: Ast.Node.Index,
1869) InnerError!Zir.Inst.Ref {1932) InnerError!Zir.Inst.Ref {
1870 const astgen = gz.astgen;1933 const astgen = gz.astgen;
1871 if (gz.force_comptime) {1934 if (gz.is_comptime) {
1872 return astgen.failNode(node, "redundant comptime keyword in already comptime scope", .{});1935 return astgen.failNode(node, "redundant comptime keyword in already comptime scope", .{});
1873 }1936 }
1874 const tree = astgen.tree;1937 const tree = astgen.tree;
1875 const node_datas = tree.nodes.items(.data);1938 const node_datas = tree.nodes.items(.data);
1876 const body_node = node_datas[node].lhs;1939 const body_node = node_datas[node].lhs;
1877 gz.force_comptime = true;1940 return comptimeExpr(gz, scope, ri, body_node);
1878 const result = try expr(gz, scope, ri, body_node);
1879 gz.force_comptime = false;
1880 return result;
1881}1941}
18821942
1883/// Restore the error return trace index. Performs the restore only if the result is a non-error or1943/// 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,7 +2021,7 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) Inn
1961 };2021 };
1962 // If we made it here, this block is the target of the break expr2022 // If we made it here, this block is the target of the break expr
19632023
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 .break_inline2025 .break_inline
1966 else2026 else
1967 .@"break";2027 .@"break";
...@@ -1973,7 +2033,7 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) Inn...@@ -1973,7 +2033,7 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) Inn
1973 try genDefers(parent_gz, scope, parent_scope, .normal_only);2033 try genDefers(parent_gz, scope, parent_scope, .normal_only);
19742034
1975 // As our last action before the break, "pop" the error trace if needed2035 // 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 _ = try parent_gz.addRestoreErrRetIndex(.{ .block = block_inst }, .always);2037 _ = try parent_gz.addRestoreErrRetIndex(.{ .block = block_inst }, .always);
19782038
1979 _ = try parent_gz.addBreak(break_tag, block_inst, .void_value);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,7 +2046,7 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) Inn
1986 try genDefers(parent_gz, scope, parent_scope, .normal_only);2046 try genDefers(parent_gz, scope, parent_scope, .normal_only);
19872047
1988 // As our last action before the break, "pop" the error trace if needed2048 // 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 try restoreErrRetIndex(parent_gz, .{ .block = block_inst }, block_gz.break_result_info, rhs, operand);2050 try restoreErrRetIndex(parent_gz, .{ .block = block_inst }, block_gz.break_result_info, rhs, operand);
19912051
1992 switch (block_gz.break_result_info.rl) {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,7 +2122,7 @@ fn continueExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index)
2062 continue;2122 continue;
2063 }2123 }
20642124
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 .break_inline2126 .break_inline
2067 else2127 else
2068 .@"break";2128 .@"break";
...@@ -2071,7 +2131,7 @@ fn continueExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index)...@@ -2071,7 +2131,7 @@ fn continueExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index)
2071 }2131 }
20722132
2073 // As our last action before the continue, "pop" the error trace if needed2133 // 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 _ = try parent_gz.addRestoreErrRetIndex(.{ .block = continue_block }, .always);2135 _ = try parent_gz.addRestoreErrRetIndex(.{ .block = continue_block }, .always);
20762136
2077 _ = try parent_gz.addBreak(break_tag, continue_block, .void_value);2137 _ = try parent_gz.addBreak(break_tag, continue_block, .void_value);
...@@ -2116,10 +2176,10 @@ fn blockExpr(...@@ -2116,10 +2176,10 @@ fn blockExpr(
2116 if (token_tags[lbrace - 1] == .colon and2176 if (token_tags[lbrace - 1] == .colon and
2117 token_tags[lbrace - 2] == .identifier)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 }
21212181
2122 if (!gz.force_comptime) {2182 if (!gz.is_comptime) {
2123 // Since this block is unlabeled, its control flow is effectively linear and we2183 // Since this block is unlabeled, its control flow is effectively linear and we
2124 // can *almost* get away with inlining the block here. However, we actually need2184 // can *almost* get away with inlining the block here. However, we actually need
2125 // to preserve the .block for Sema, to properly pop the error return trace.2185 // to preserve the .block for Sema, to properly pop the error return trace.
...@@ -2136,9 +2196,7 @@ fn blockExpr(...@@ -2136,9 +2196,7 @@ fn blockExpr(
2136 if (!block_scope.endsWithNoReturn()) {2196 if (!block_scope.endsWithNoReturn()) {
2137 // As our last action before the break, "pop" the error trace if needed2197 // As our last action before the break, "pop" the error trace if needed
2138 _ = try gz.addRestoreErrRetIndex(.{ .block = block_inst }, .always);2198 _ = try gz.addRestoreErrRetIndex(.{ .block = block_inst }, .always);
21392199 _ = try block_scope.addBreak(.@"break", block_inst, .void_value);
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);
2142 }2200 }
21432201
2144 try block_scope.setBlockBody(block_inst);2202 try block_scope.setBlockBody(block_inst);
...@@ -2188,6 +2246,7 @@ fn labeledBlockExpr(...@@ -2188,6 +2246,7 @@ fn labeledBlockExpr(
2188 ri: ResultInfo,2246 ri: ResultInfo,
2189 block_node: Ast.Node.Index,2247 block_node: Ast.Node.Index,
2190 statements: []const Ast.Node.Index,2248 statements: []const Ast.Node.Index,
2249 force_comptime: bool,
2191) InnerError!Zir.Inst.Ref {2250) InnerError!Zir.Inst.Ref {
2192 const tracy = trace(@src());2251 const tracy = trace(@src());
2193 defer tracy.end();2252 defer tracy.end();
...@@ -2205,16 +2264,16 @@ fn labeledBlockExpr(...@@ -2205,16 +2264,16 @@ fn labeledBlockExpr(
22052264
2206 // Reserve the Block ZIR instruction index so that we can put it into the GenZir struct2265 // Reserve the Block ZIR instruction index so that we can put it into the GenZir struct
2207 // so that break statements can reference it.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 const block_inst = try gz.makeBlockInst(block_tag, block_node);2268 const block_inst = try gz.makeBlockInst(block_tag, block_node);
2210 try gz.instructions.append(astgen.gpa, block_inst);2269 try gz.instructions.append(astgen.gpa, block_inst);
2211
2212 var block_scope = gz.makeSubBlock(parent_scope);2270 var block_scope = gz.makeSubBlock(parent_scope);
2213 block_scope.label = GenZir.Label{2271 block_scope.label = GenZir.Label{
2214 .token = label_token,2272 .token = label_token,
2215 .block_inst = block_inst,2273 .block_inst = block_inst,
2216 };2274 };
2217 block_scope.setBreakResultInfo(ri);2275 block_scope.setBreakResultInfo(ri);
2276 if (force_comptime) block_scope.is_comptime = true;
2218 defer block_scope.unstack();2277 defer block_scope.unstack();
2219 defer block_scope.labeled_breaks.deinit(astgen.gpa);2278 defer block_scope.labeled_breaks.deinit(astgen.gpa);
22202279
...@@ -2222,9 +2281,7 @@ fn labeledBlockExpr(...@@ -2222,9 +2281,7 @@ fn labeledBlockExpr(
2222 if (!block_scope.endsWithNoReturn()) {2281 if (!block_scope.endsWithNoReturn()) {
2223 // As our last action before the return, "pop" the error trace if needed2282 // As our last action before the return, "pop" the error trace if needed
2224 _ = try gz.addRestoreErrRetIndex(.{ .block = block_inst }, .always);2283 _ = try gz.addRestoreErrRetIndex(.{ .block = block_inst }, .always);
22252284 _ = try block_scope.addBreak(.@"break", block_inst, .void_value);
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);
2228 }2285 }
22292286
2230 if (!block_scope.label.?.used) {2287 if (!block_scope.label.?.used) {
...@@ -2436,6 +2493,7 @@ fn addEnsureResult(gz: *GenZir, maybe_unused_result: Zir.Inst.Ref, statement: As...@@ -2436,6 +2493,7 @@ fn addEnsureResult(gz: *GenZir, maybe_unused_result: Zir.Inst.Ref, statement: As
2436 .bitcast,2493 .bitcast,
2437 .bit_or,2494 .bit_or,
2438 .block,2495 .block,
2496 .block_comptime,
2439 .block_inline,2497 .block_inline,
2440 .suspend_block,2498 .suspend_block,
2441 .loop,2499 .loop,
...@@ -2610,8 +2668,6 @@ fn addEnsureResult(gz: *GenZir, maybe_unused_result: Zir.Inst.Ref, statement: As...@@ -2610,8 +2668,6 @@ fn addEnsureResult(gz: *GenZir, maybe_unused_result: Zir.Inst.Ref, statement: As
2610 .for_len,2668 .for_len,
2611 .@"try",2669 .@"try",
2612 .try_ptr,2670 .try_ptr,
2613 //.try_inline,
2614 //.try_ptr_inline,
2615 => break :b false,2671 => break :b false,
26162672
2617 .extended => switch (gz.astgen.instructions.items(.data)[inst].extended.opcode) {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,7 +2694,6 @@ fn addEnsureResult(gz: *GenZir, maybe_unused_result: Zir.Inst.Ref, statement: As
2638 .repeat,2694 .repeat,
2639 .repeat_inline,2695 .repeat_inline,
2640 .panic,2696 .panic,
2641 .panic_comptime,
2642 .trap,2697 .trap,
2643 .check_comptime_control_flow,2698 .check_comptime_control_flow,
2644 => {2699 => {
...@@ -2665,9 +2720,7 @@ fn addEnsureResult(gz: *GenZir, maybe_unused_result: Zir.Inst.Ref, statement: As...@@ -2665,9 +2720,7 @@ fn addEnsureResult(gz: *GenZir, maybe_unused_result: Zir.Inst.Ref, statement: As
2665 .store_to_inferred_ptr,2720 .store_to_inferred_ptr,
2666 .resolve_inferred_alloc,2721 .resolve_inferred_alloc,
2667 .validate_struct_init,2722 .validate_struct_init,
2668 .validate_struct_init_comptime,
2669 .validate_array_init,2723 .validate_array_init,
2670 .validate_array_init_comptime,
2671 .set_runtime_safety,2724 .set_runtime_safety,
2672 .closure_capture,2725 .closure_capture,
2673 .memcpy,2726 .memcpy,
...@@ -2988,7 +3041,7 @@ fn varDecl(...@@ -2988,7 +3041,7 @@ fn varDecl(
2988 return &sub_scope.base;3041 return &sub_scope.base;
2989 }3042 }
29903043
2991 const is_comptime = gz.force_comptime or3044 const is_comptime = gz.is_comptime or
2992 tree.nodes.items(.tag)[var_decl.ast.init_node] == .@"comptime";3045 tree.nodes.items(.tag)[var_decl.ast.init_node] == .@"comptime";
29933046
2994 // Detect whether the initialization expression actually uses the3047 // Detect whether the initialization expression actually uses the
...@@ -3133,7 +3186,7 @@ fn varDecl(...@@ -3133,7 +3186,7 @@ fn varDecl(
3133 const old_rl_ty_inst = gz.rl_ty_inst;3186 const old_rl_ty_inst = gz.rl_ty_inst;
3134 defer gz.rl_ty_inst = old_rl_ty_inst;3187 defer gz.rl_ty_inst = old_rl_ty_inst;
31353188
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 var resolve_inferred_alloc: Zir.Inst.Ref = .none;3190 var resolve_inferred_alloc: Zir.Inst.Ref = .none;
3138 const var_data: struct {3191 const var_data: struct {
3139 result_info: ResultInfo,3192 result_info: ResultInfo,
...@@ -3211,7 +3264,7 @@ fn emitDbgNode(gz: *GenZir, node: Ast.Node.Index) !void {...@@ -3211,7 +3264,7 @@ fn emitDbgNode(gz: *GenZir, node: Ast.Node.Index) !void {
3211 // The instruction emitted here is for debugging runtime code.3264 // The instruction emitted here is for debugging runtime code.
3212 // If the current block will be evaluated only during semantic analysis3265 // If the current block will be evaluated only during semantic analysis
3213 // then no dbg_stmt ZIR instruction is needed.3266 // then no dbg_stmt ZIR instruction is needed.
3214 if (gz.force_comptime) return;3267 if (gz.is_comptime) return;
32153268
3216 const astgen = gz.astgen;3269 const astgen = gz.astgen;
3217 astgen.advanceSourceCursorToNode(node);3270 astgen.advanceSourceCursorToNode(node);
...@@ -3631,7 +3684,7 @@ fn fnDecl(...@@ -3631,7 +3684,7 @@ fn fnDecl(
3631 astgen.advanceSourceCursorToNode(decl_node);3684 astgen.advanceSourceCursorToNode(decl_node);
36323685
3633 var decl_gz: GenZir = .{3686 var decl_gz: GenZir = .{
3634 .force_comptime = true,3687 .is_comptime = true,
3635 .decl_node_index = fn_proto.ast.proto_node,3688 .decl_node_index = fn_proto.ast.proto_node,
3636 .decl_line = astgen.source_line,3689 .decl_line = astgen.source_line,
3637 .parent = scope,3690 .parent = scope,
...@@ -3642,7 +3695,7 @@ fn fnDecl(...@@ -3642,7 +3695,7 @@ fn fnDecl(
3642 defer decl_gz.unstack();3695 defer decl_gz.unstack();
36433696
3644 var fn_gz: GenZir = .{3697 var fn_gz: GenZir = .{
3645 .force_comptime = false,3698 .is_comptime = false,
3646 .decl_node_index = fn_proto.ast.proto_node,3699 .decl_node_index = fn_proto.ast.proto_node,
3647 .decl_line = decl_gz.decl_line,3700 .decl_line = decl_gz.decl_line,
3648 .parent = &decl_gz.base,3701 .parent = &decl_gz.base,
...@@ -4005,7 +4058,7 @@ fn globalVarDecl(...@@ -4005,7 +4058,7 @@ fn globalVarDecl(
4005 .decl_node_index = node,4058 .decl_node_index = node,
4006 .decl_line = astgen.source_line,4059 .decl_line = astgen.source_line,
4007 .astgen = astgen,4060 .astgen = astgen,
4008 .force_comptime = true,4061 .is_comptime = true,
4009 .anon_name_strategy = .parent,4062 .anon_name_strategy = .parent,
4010 .instructions = gz.instructions,4063 .instructions = gz.instructions,
4011 .instructions_top = gz.instructions.items.len,4064 .instructions_top = gz.instructions.items.len,
...@@ -4156,7 +4209,7 @@ fn comptimeDecl(...@@ -4156,7 +4209,7 @@ fn comptimeDecl(
4156 astgen.advanceSourceCursorToNode(node);4209 astgen.advanceSourceCursorToNode(node);
41574210
4158 var decl_block: GenZir = .{4211 var decl_block: GenZir = .{
4159 .force_comptime = true,4212 .is_comptime = true,
4160 .decl_node_index = node,4213 .decl_node_index = node,
4161 .decl_line = astgen.source_line,4214 .decl_line = astgen.source_line,
4162 .parent = scope,4215 .parent = scope,
...@@ -4210,7 +4263,7 @@ fn usingnamespaceDecl(...@@ -4210,7 +4263,7 @@ fn usingnamespaceDecl(
4210 astgen.advanceSourceCursorToNode(node);4263 astgen.advanceSourceCursorToNode(node);
42114264
4212 var decl_block: GenZir = .{4265 var decl_block: GenZir = .{
4213 .force_comptime = true,4266 .is_comptime = true,
4214 .decl_node_index = node,4267 .decl_node_index = node,
4215 .decl_line = astgen.source_line,4268 .decl_line = astgen.source_line,
4216 .parent = scope,4269 .parent = scope,
...@@ -4257,7 +4310,7 @@ fn testDecl(...@@ -4257,7 +4310,7 @@ fn testDecl(
4257 astgen.advanceSourceCursorToNode(node);4310 astgen.advanceSourceCursorToNode(node);
42584311
4259 var decl_block: GenZir = .{4312 var decl_block: GenZir = .{
4260 .force_comptime = true,4313 .is_comptime = true,
4261 .decl_node_index = node,4314 .decl_node_index = node,
4262 .decl_line = astgen.source_line,4315 .decl_line = astgen.source_line,
4263 .parent = scope,4316 .parent = scope,
...@@ -4353,7 +4406,7 @@ fn testDecl(...@@ -4353,7 +4406,7 @@ fn testDecl(
4353 };4406 };
43544407
4355 var fn_block: GenZir = .{4408 var fn_block: GenZir = .{
4356 .force_comptime = false,4409 .is_comptime = false,
4357 .decl_node_index = node,4410 .decl_node_index = node,
4358 .decl_line = decl_block.decl_line,4411 .decl_line = decl_block.decl_line,
4359 .parent = &decl_block.base,4412 .parent = &decl_block.base,
...@@ -4477,7 +4530,7 @@ fn structDeclInner(...@@ -4477,7 +4530,7 @@ fn structDeclInner(
4477 .decl_node_index = node,4530 .decl_node_index = node,
4478 .decl_line = gz.decl_line,4531 .decl_line = gz.decl_line,
4479 .astgen = astgen,4532 .astgen = astgen,
4480 .force_comptime = true,4533 .is_comptime = true,
4481 .instructions = gz.instructions,4534 .instructions = gz.instructions,
4482 .instructions_top = gz.instructions.items.len,4535 .instructions_top = gz.instructions.items.len,
4483 };4536 };
...@@ -4720,7 +4773,7 @@ fn unionDeclInner(...@@ -4720,7 +4773,7 @@ fn unionDeclInner(
4720 .decl_node_index = node,4773 .decl_node_index = node,
4721 .decl_line = gz.decl_line,4774 .decl_line = gz.decl_line,
4722 .astgen = astgen,4775 .astgen = astgen,
4723 .force_comptime = true,4776 .is_comptime = true,
4724 .instructions = gz.instructions,4777 .instructions = gz.instructions,
4725 .instructions_top = gz.instructions.items.len,4778 .instructions_top = gz.instructions.items.len,
4726 };4779 };
...@@ -5006,7 +5059,7 @@ fn containerDecl(...@@ -5006,7 +5059,7 @@ fn containerDecl(
5006 .decl_node_index = node,5059 .decl_node_index = node,
5007 .decl_line = gz.decl_line,5060 .decl_line = gz.decl_line,
5008 .astgen = astgen,5061 .astgen = astgen,
5009 .force_comptime = true,5062 .is_comptime = true,
5010 .instructions = gz.instructions,5063 .instructions = gz.instructions,
5011 .instructions_top = gz.instructions.items.len,5064 .instructions_top = gz.instructions.items.len,
5012 };5065 };
...@@ -5115,7 +5168,7 @@ fn containerDecl(...@@ -5115,7 +5168,7 @@ fn containerDecl(
5115 .decl_node_index = node,5168 .decl_node_index = node,
5116 .decl_line = gz.decl_line,5169 .decl_line = gz.decl_line,
5117 .astgen = astgen,5170 .astgen = astgen,
5118 .force_comptime = true,5171 .is_comptime = true,
5119 .instructions = gz.instructions,5172 .instructions = gz.instructions,
5120 .instructions_top = gz.instructions.items.len,5173 .instructions_top = gz.instructions.items.len,
5121 };5174 };
...@@ -5304,7 +5357,7 @@ fn tryExpr(...@@ -5304,7 +5357,7 @@ fn tryExpr(
5304 // Then we will save the line/column so that we can emit another one that goes5357 // Then we will save the line/column so that we can emit another one that goes
5305 // "backwards" because we want to evaluate the operand, but then put the debug5358 // "backwards" because we want to evaluate the operand, but then put the debug
5306 // info back at the try keyword for error return tracing.5359 // info back at the try keyword for error return tracing.
5307 if (!parent_gz.force_comptime) {5360 if (!parent_gz.is_comptime) {
5308 try emitDbgNode(parent_gz, node);5361 try emitDbgNode(parent_gz, node);
5309 }5362 }
5310 const try_line = astgen.source_line - parent_gz.decl_line;5363 const try_line = astgen.source_line - parent_gz.decl_line;
...@@ -5316,17 +5369,7 @@ fn tryExpr(...@@ -5316,17 +5369,7 @@ fn tryExpr(
5316 };5369 };
5317 // This could be a pointer or value depending on the `ri` parameter.5370 // This could be a pointer or value depending on the `ri` parameter.
5318 const operand = try reachableExpr(parent_gz, scope, operand_ri, operand_node, node);5371 const operand = try reachableExpr(parent_gz, scope, operand_ri, operand_node, node);
5319 const is_inline = parent_gz.force_comptime;5372 const block_tag: Zir.Inst.Tag = if (operand_ri.rl == .ref) .try_ptr else .@"try";
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 };
5330 const try_inst = try parent_gz.makeBlockInst(block_tag, node);5373 const try_inst = try parent_gz.makeBlockInst(block_tag, node);
5331 try parent_gz.instructions.append(astgen.gpa, try_inst);5374 try parent_gz.instructions.append(astgen.gpa, try_inst);
53325375
...@@ -5382,11 +5425,9 @@ fn orelseCatchExpr(...@@ -5382,11 +5425,9 @@ fn orelseCatchExpr(
5382 // up for this fact by calling rvalue on the else branch.5425 // up for this fact by calling rvalue on the else branch.
5383 const operand = try reachableExpr(&block_scope, &block_scope.base, operand_ri, lhs, rhs);5426 const operand = try reachableExpr(&block_scope, &block_scope.base, operand_ri, lhs, rhs);
5384 const cond = try block_scope.addUnNode(cond_op, operand, node);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;5428 const condbr = try block_scope.addCondBr(.condbr, node);
5386 const condbr = try block_scope.addCondBr(condbr_tag, node);
53875429
5388 const block_tag: Zir.Inst.Tag = if (parent_gz.force_comptime) .block_inline else .block;5430 const block = try parent_gz.makeBlockInst(.block, node);
5389 const block = try parent_gz.makeBlockInst(block_tag, node);
5390 try block_scope.setBlockBody(block);5431 try block_scope.setBlockBody(block);
5391 // block_scope unstacked now, can add new instructions to parent_gz5432 // block_scope unstacked now, can add new instructions to parent_gz
5392 try parent_gz.instructions.append(astgen.gpa, block);5433 try parent_gz.instructions.append(astgen.gpa, block);
...@@ -5445,7 +5486,6 @@ fn orelseCatchExpr(...@@ -5445,7 +5486,6 @@ fn orelseCatchExpr(
5445 // instructions into place until we know whether to keep store_to_block_ptr5486 // instructions into place until we know whether to keep store_to_block_ptr
5446 // instructions or not.5487 // instructions or not.
54475488
5448 const break_tag: Zir.Inst.Tag = if (parent_gz.force_comptime) .break_inline else .@"break";
5449 const result = try finishThenElseBlock(5489 const result = try finishThenElseBlock(
5450 parent_gz,5490 parent_gz,
5451 ri,5491 ri,
...@@ -5461,7 +5501,7 @@ fn orelseCatchExpr(...@@ -5461,7 +5501,7 @@ fn orelseCatchExpr(
5461 rhs,5501 rhs,
5462 block,5502 block,
5463 block,5503 block,
5464 break_tag,5504 .@"break",
5465 );5505 );
5466 return result;5506 return result;
5467}5507}
...@@ -5747,11 +5787,9 @@ fn ifExpr(...@@ -5747,11 +5787,9 @@ fn ifExpr(
5747 }5787 }
5748 };5788 };
57495789
5750 const condbr_tag: Zir.Inst.Tag = if (parent_gz.force_comptime) .condbr_inline else .condbr;5790 const condbr = try block_scope.addCondBr(.condbr, node);
5751 const condbr = try block_scope.addCondBr(condbr_tag, node);
57525791
5753 const block_tag: Zir.Inst.Tag = if (parent_gz.force_comptime) .block_inline else .block;5792 const block = try parent_gz.makeBlockInst(.block, node);
5754 const block = try parent_gz.makeBlockInst(block_tag, node);
5755 try block_scope.setBlockBody(block);5793 try block_scope.setBlockBody(block);
5756 // block_scope unstacked now, can add new instructions to parent_gz5794 // block_scope unstacked now, can add new instructions to parent_gz
5757 try parent_gz.instructions.append(astgen.gpa, block);5795 try parent_gz.instructions.append(astgen.gpa, block);
...@@ -5891,7 +5929,6 @@ fn ifExpr(...@@ -5891,7 +5929,6 @@ fn ifExpr(
5891 },5929 },
5892 };5930 };
58935931
5894 const break_tag: Zir.Inst.Tag = if (parent_gz.force_comptime) .break_inline else .@"break";
5895 const result = try finishThenElseBlock(5932 const result = try finishThenElseBlock(
5896 parent_gz,5933 parent_gz,
5897 ri,5934 ri,
...@@ -5907,7 +5944,7 @@ fn ifExpr(...@@ -5907,7 +5944,7 @@ fn ifExpr(
5907 else_info.src,5944 else_info.src,
5908 block,5945 block,
5909 block,5946 block,
5910 break_tag,5947 .@"break",
5911 );5948 );
5912 return result;5949 return result;
5913}5950}
...@@ -6043,7 +6080,7 @@ fn whileExpr(...@@ -6043,7 +6080,7 @@ fn whileExpr(
6043 try astgen.checkLabelRedefinition(scope, label_token);6080 try astgen.checkLabelRedefinition(scope, label_token);
6044 }6081 }
60456082
6046 const is_inline = parent_gz.force_comptime or while_full.inline_token != null;6083 const is_inline = while_full.inline_token != null;
6047 const loop_tag: Zir.Inst.Tag = if (is_inline) .block_inline else .loop;6084 const loop_tag: Zir.Inst.Tag = if (is_inline) .block_inline else .loop;
6048 const loop_block = try parent_gz.makeBlockInst(loop_tag, node);6085 const loop_block = try parent_gz.makeBlockInst(loop_tag, node);
6049 try parent_gz.instructions.append(astgen.gpa, loop_block);6086 try parent_gz.instructions.append(astgen.gpa, loop_block);
...@@ -6315,7 +6352,7 @@ fn forExpr(...@@ -6315,7 +6352,7 @@ fn forExpr(
6315 try astgen.checkLabelRedefinition(scope, label_token);6352 try astgen.checkLabelRedefinition(scope, label_token);
6316 }6353 }
63176354
6318 const is_inline = parent_gz.force_comptime or for_full.inline_token != null;6355 const is_inline = for_full.inline_token != null;
6319 const tree = astgen.tree;6356 const tree = astgen.tree;
6320 const token_tags = tree.tokens.items(.tag);6357 const token_tags = tree.tokens.items(.tag);
6321 const node_tags = tree.nodes.items(.tag);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,7 +7151,7 @@ fn ret(gz: *GenZir, scope: *Scope, node: Ast.Node.Index) InnerError!Zir.Inst.Ref
7114 // Then we will save the line/column so that we can emit another one that goes7151 // Then we will save the line/column so that we can emit another one that goes
7115 // "backwards" because we want to evaluate the operand, but then put the debug7152 // "backwards" because we want to evaluate the operand, but then put the debug
7116 // info back at the return keyword for error return tracing.7153 // info back at the return keyword for error return tracing.
7117 if (!gz.force_comptime) {7154 if (!gz.is_comptime) {
7118 try emitDbgNode(gz, node);7155 try emitDbgNode(gz, node);
7119 }7156 }
7120 const ret_line = astgen.source_line - gz.decl_line;7157 const ret_line = astgen.source_line - gz.decl_line;
...@@ -7859,7 +7896,7 @@ fn typeOf(...@@ -7859,7 +7896,7 @@ fn typeOf(
7859 const typeof_inst = try gz.makeBlockInst(.typeof_builtin, node);7896 const typeof_inst = try gz.makeBlockInst(.typeof_builtin, node);
78607897
7861 var typeof_scope = gz.makeSubBlock(scope);7898 var typeof_scope = gz.makeSubBlock(scope);
7862 typeof_scope.force_comptime = false;7899 typeof_scope.is_comptime = false;
7863 typeof_scope.c_import = false;7900 typeof_scope.c_import = false;
7864 defer typeof_scope.unstack();7901 defer typeof_scope.unstack();
78657902
...@@ -7880,7 +7917,7 @@ fn typeOf(...@@ -7880,7 +7917,7 @@ fn typeOf(
7880 const typeof_inst = try gz.addExtendedMultiOpPayloadIndex(.typeof_peer, payload_index, args.len);7917 const typeof_inst = try gz.addExtendedMultiOpPayloadIndex(.typeof_peer, payload_index, args.len);
78817918
7882 var typeof_scope = gz.makeSubBlock(scope);7919 var typeof_scope = gz.makeSubBlock(scope);
7883 typeof_scope.force_comptime = false;7920 typeof_scope.is_comptime = false;
78847921
7885 for (args, 0..) |arg, i| {7922 for (args, 0..) |arg, i| {
7886 const param_ref = try reachableExpr(&typeof_scope, &typeof_scope.base, .{ .rl = .none }, arg, node);7923 const param_ref = try reachableExpr(&typeof_scope, &typeof_scope.base, .{ .rl = .none }, arg, node);
...@@ -8207,7 +8244,7 @@ fn builtinCall(...@@ -8207,7 +8244,7 @@ fn builtinCall(
8207 },8244 },
8208 .panic => {8245 .panic => {
8209 try emitDbgNode(gz, node);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 .trap => {8249 .trap => {
8213 try emitDbgNode(gz, node);8250 try emitDbgNode(gz, node);
...@@ -8431,7 +8468,6 @@ fn builtinCall(...@@ -8431,7 +8468,6 @@ fn builtinCall(
8431 .args = args,8468 .args = args,
8432 .flags = .{8469 .flags = .{
8433 .is_nosuspend = gz.nosuspend_node != 0,8470 .is_nosuspend = gz.nosuspend_node != 0,
8434 .is_comptime = gz.force_comptime,
8435 .ensure_result_used = false,8471 .ensure_result_used = false,
8436 },8472 },
8437 });8473 });
...@@ -8644,15 +8680,14 @@ fn simpleUnOp(...@@ -8644,15 +8680,14 @@ fn simpleUnOp(
8644 operand_node: Ast.Node.Index,8680 operand_node: Ast.Node.Index,
8645 tag: Zir.Inst.Tag,8681 tag: Zir.Inst.Tag,
8646) InnerError!Zir.Inst.Ref {8682) InnerError!Zir.Inst.Ref {
8647 const prev_force_comptime = gz.force_comptime;
8648 defer gz.force_comptime = prev_force_comptime;
8649
8650 switch (tag) {8683 switch (tag) {
8651 .tag_name, .error_name, .ptr_to_int => try emitDbgNode(gz, node),8684 .tag_name, .error_name, .ptr_to_int => try emitDbgNode(gz, node),
8652 .compile_error => gz.force_comptime = true,
8653 else => {},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 const result = try gz.addUnNode(tag, operand, node);8691 const result = try gz.addUnNode(tag, operand, node);
8657 return rvalue(gz, ri, result, node);8692 return rvalue(gz, ri, result, node);
8658}8693}
...@@ -8814,7 +8849,7 @@ fn cImport(...@@ -8814,7 +8849,7 @@ fn cImport(
8814 if (gz.c_import) return gz.astgen.failNode(node, "cannot nest @cImport", .{});8849 if (gz.c_import) return gz.astgen.failNode(node, "cannot nest @cImport", .{});
88158850
8816 var block_scope = gz.makeSubBlock(scope);8851 var block_scope = gz.makeSubBlock(scope);
8817 block_scope.force_comptime = true;8852 block_scope.is_comptime = true;
8818 block_scope.c_import = true;8853 block_scope.c_import = true;
8819 defer block_scope.unstack();8854 defer block_scope.unstack();
88208855
...@@ -8860,7 +8895,7 @@ fn callExpr(...@@ -8860,7 +8895,7 @@ fn callExpr(
88608895
8861 const callee = try calleeExpr(gz, scope, call.ast.fn_expr);8896 const callee = try calleeExpr(gz, scope, call.ast.fn_expr);
8862 const modifier: std.builtin.CallModifier = blk: {8897 const modifier: std.builtin.CallModifier = blk: {
8863 if (gz.force_comptime) {8898 if (gz.is_comptime) {
8864 break :blk .compile_time;8899 break :blk .compile_time;
8865 }8900 }
8866 if (call.async_token != null) {8901 if (call.async_token != null) {
...@@ -10875,7 +10910,10 @@ const Scope = struct {...@@ -10875,7 +10910,10 @@ const Scope = struct {
10875const GenZir = struct {10910const GenZir = struct {
10876 const base_tag: Scope.Tag = .gen_zir;10911 const base_tag: Scope.Tag = .gen_zir;
10877 base: Scope = Scope{ .tag = base_tag },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 /// This is set to true for inline loops; false otherwise.10917 /// This is set to true for inline loops; false otherwise.
10880 is_inline: bool = false,10918 is_inline: bool = false,
10881 c_import: bool = false,10919 c_import: bool = false,
...@@ -10962,7 +11000,7 @@ const GenZir = struct {...@@ -10962,7 +11000,7 @@ const GenZir = struct {
1096211000
10963 fn makeSubBlock(gz: *GenZir, scope: *Scope) GenZir {11001 fn makeSubBlock(gz: *GenZir, scope: *Scope) GenZir {
10964 return .{11002 return .{
10965 .force_comptime = gz.force_comptime,11003 .is_comptime = gz.is_comptime,
10966 .c_import = gz.c_import,11004 .c_import = gz.c_import,
10967 .decl_node_index = gz.decl_node_index,11005 .decl_node_index = gz.decl_node_index,
10968 .decl_line = gz.decl_line,11006 .decl_line = gz.decl_line,
...@@ -12405,7 +12443,7 @@ const GenZir = struct {...@@ -12405,7 +12443,7 @@ const GenZir = struct {
12405 }12443 }
1240612444
12407 fn addDbgVar(gz: *GenZir, tag: Zir.Inst.Tag, name: u32, inst: Zir.Inst.Ref) !void {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;
1240912447
12410 _ = try gz.add(.{ .tag = tag, .data = .{12448 _ = try gz.add(.{ .tag = tag, .data = .{
12411 .str_op = .{12449 .str_op = .{
...@@ -12416,13 +12454,13 @@ const GenZir = struct {...@@ -12416,13 +12454,13 @@ const GenZir = struct {
12416 }12454 }
1241712455
12418 fn addDbgBlockBegin(gz: *GenZir) !void {12456 fn addDbgBlockBegin(gz: *GenZir) !void {
12419 if (gz.force_comptime) return;12457 if (gz.is_comptime) return;
1242012458
12421 _ = try gz.add(.{ .tag = .dbg_block_begin, .data = undefined });12459 _ = try gz.add(.{ .tag = .dbg_block_begin, .data = undefined });
12422 }12460 }
1242312461
12424 fn addDbgBlockEnd(gz: *GenZir) !void {12462 fn addDbgBlockEnd(gz: *GenZir) !void {
12425 if (gz.force_comptime) return;12463 if (gz.is_comptime) return;
12426 const gpa = gz.astgen.gpa;12464 const gpa = gz.astgen.gpa;
1242712465
12428 const tags = gz.astgen.instructions.items(.tag);12466 const tags = gz.astgen.instructions.items(.tag);
...@@ -12554,7 +12592,7 @@ fn detectLocalShadowing(...@@ -12554,7 +12592,7 @@ fn detectLocalShadowing(
12554/// Advances the source cursor to the main token of `node` if not in comptime scope.12592/// Advances the source cursor to the main token of `node` if not in comptime scope.
12555/// Usually paired with `emitDbgStmt`.12593/// Usually paired with `emitDbgStmt`.
12556fn maybeAdvanceSourceCursorToMainToken(gz: *GenZir, node: Ast.Node.Index) void {12594fn maybeAdvanceSourceCursorToMainToken(gz: *GenZir, node: Ast.Node.Index) void {
12557 if (gz.force_comptime) return;12595 if (gz.is_comptime) return;
1255812596
12559 const tree = gz.astgen.tree;12597 const tree = gz.astgen.tree;
12560 const token_starts = tree.tokens.items(.start);12598 const token_starts = tree.tokens.items(.start);
...@@ -12765,7 +12803,7 @@ fn countBodyLenAfterFixups(astgen: *AstGen, body: []const Zir.Inst.Index) u32 {...@@ -12765,7 +12803,7 @@ fn countBodyLenAfterFixups(astgen: *AstGen, body: []const Zir.Inst.Index) u32 {
12765}12803}
1276612804
12767fn emitDbgStmt(gz: *GenZir, line: u32, column: u32) !void {12805fn emitDbgStmt(gz: *GenZir, line: u32, column: u32) !void {
12768 if (gz.force_comptime) return;12806 if (gz.is_comptime) return;
1276912807
12770 _ = try gz.add(.{ .tag = .dbg_stmt, .data = .{12808 _ = try gz.add(.{ .tag = .dbg_stmt, .data = .{
12771 .dbg_stmt = .{12809 .dbg_stmt = .{
src/Sema.zig+23-89
...@@ -1112,8 +1112,7 @@ fn analyzeBodyInner(...@@ -1112,8 +1112,7 @@ fn analyzeBodyInner(
1112 .ret_load => break sema.zirRetLoad(block, inst),1112 .ret_load => break sema.zirRetLoad(block, inst),
1113 .ret_err_value => break sema.zirRetErrValue(block, inst),1113 .ret_err_value => break sema.zirRetErrValue(block, inst),
1114 .@"unreachable" => break sema.zirUnreachable(block, inst),1114 .@"unreachable" => break sema.zirUnreachable(block, inst),
1115 .panic => break sema.zirPanic(block, inst, false),1115 .panic => break sema.zirPanic(block, inst),
1116 .panic_comptime => break sema.zirPanic(block, inst, true),
1117 .trap => break sema.zirTrap(block, inst),1116 .trap => break sema.zirTrap(block, inst),
1118 // zig fmt: on1117 // zig fmt: on
11191118
...@@ -1292,22 +1291,12 @@ fn analyzeBodyInner(...@@ -1292,22 +1291,12 @@ fn analyzeBodyInner(
1292 continue;1291 continue;
1293 },1292 },
1294 .validate_struct_init => {1293 .validate_struct_init => {
1295 try sema.zirValidateStructInit(block, inst, false);1294 try sema.zirValidateStructInit(block, inst);
1296 i += 1;
1297 continue;
1298 },
1299 .validate_struct_init_comptime => {
1300 try sema.zirValidateStructInit(block, inst, true);
1301 i += 1;1295 i += 1;
1302 continue;1296 continue;
1303 },1297 },
1304 .validate_array_init => {1298 .validate_array_init => {
1305 try sema.zirValidateArrayInit(block, inst, false);1299 try sema.zirValidateArrayInit(block, inst);
1306 i += 1;
1307 continue;
1308 },
1309 .validate_array_init_comptime => {
1310 try sema.zirValidateArrayInit(block, inst, true);
1311 i += 1;1300 i += 1;
1312 continue;1301 continue;
1313 },1302 },
...@@ -1464,8 +1453,10 @@ fn analyzeBodyInner(...@@ -1464,8 +1453,10 @@ fn analyzeBodyInner(
1464 break break_data.inst;1453 break break_data.inst;
1465 }1454 }
1466 },1455 },
1467 .block => blk: {1456 .block, .block_comptime => blk: {
1468 if (!block.is_comptime) break :blk try sema.zirBlock(block, inst);1457 if (!block.is_comptime) {
1458 break :blk try sema.zirBlock(block, inst, tags[inst] == .block_comptime);
1459 }
1469 // Same as `block_inline`. TODO https://github.com/ziglang/zig/issues/82201460 // Same as `block_inline`. TODO https://github.com/ziglang/zig/issues/8220
1470 const inst_data = datas[inst].pl_node;1461 const inst_data = datas[inst].pl_node;
1471 const extra = sema.code.extraData(Zir.Inst.Block, inst_data.payload_index);1462 const extra = sema.code.extraData(Zir.Inst.Block, inst_data.payload_index);
...@@ -1649,38 +1640,6 @@ fn analyzeBodyInner(...@@ -1649,38 +1640,6 @@ fn analyzeBodyInner(
1649 break break_data.inst;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 .try_ptr => blk: {1643 .try_ptr => blk: {
1685 if (!block.is_comptime) break :blk try sema.zirTryPtr(block, inst);1644 if (!block.is_comptime) break :blk try sema.zirTryPtr(block, inst);
1686 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;1645 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
...@@ -1707,28 +1666,6 @@ fn analyzeBodyInner(...@@ -1707,28 +1666,6 @@ fn analyzeBodyInner(
1707 break break_data.inst;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 .@"defer" => blk: {1669 .@"defer" => blk: {
1733 const inst_data = sema.code.instructions.items(.data)[inst].@"defer";1670 const inst_data = sema.code.instructions.items(.data)[inst].@"defer";
1734 const defer_body = sema.code.extra[inst_data.index..][0..inst_data.len];1671 const defer_body = sema.code.extra[inst_data.index..][0..inst_data.len];
...@@ -4175,7 +4112,6 @@ fn zirValidateStructInit(...@@ -4175,7 +4112,6 @@ fn zirValidateStructInit(
4175 sema: *Sema,4112 sema: *Sema,
4176 block: *Block,4113 block: *Block,
4177 inst: Zir.Inst.Index,4114 inst: Zir.Inst.Index,
4178 is_comptime: bool,
4179) CompileError!void {4115) CompileError!void {
4180 const tracy = trace(@src());4116 const tracy = trace(@src());
4181 defer tracy.end();4117 defer tracy.end();
...@@ -4194,7 +4130,6 @@ fn zirValidateStructInit(...@@ -4194,7 +4130,6 @@ fn zirValidateStructInit(
4194 agg_ty,4130 agg_ty,
4195 init_src,4131 init_src,
4196 instrs,4132 instrs,
4197 is_comptime,
4198 ),4133 ),
4199 .Union => return sema.validateUnionInit(4134 .Union => return sema.validateUnionInit(
4200 block,4135 block,
...@@ -4202,7 +4137,6 @@ fn zirValidateStructInit(...@@ -4202,7 +4137,6 @@ fn zirValidateStructInit(
4202 init_src,4137 init_src,
4203 instrs,4138 instrs,
4204 object_ptr,4139 object_ptr,
4205 is_comptime,
4206 ),4140 ),
4207 else => unreachable,4141 else => unreachable,
4208 }4142 }
...@@ -4215,7 +4149,6 @@ fn validateUnionInit(...@@ -4215,7 +4149,6 @@ fn validateUnionInit(
4215 init_src: LazySrcLoc,4149 init_src: LazySrcLoc,
4216 instrs: []const Zir.Inst.Index,4150 instrs: []const Zir.Inst.Index,
4217 union_ptr: Air.Inst.Ref,4151 union_ptr: Air.Inst.Ref,
4218 is_comptime: bool,
4219) CompileError!void {4152) CompileError!void {
4220 if (instrs.len != 1) {4153 if (instrs.len != 1) {
4221 const msg = msg: {4154 const msg = msg: {
...@@ -4238,7 +4171,7 @@ fn validateUnionInit(...@@ -4238,7 +4171,7 @@ fn validateUnionInit(
4238 return sema.failWithOwnedErrorMsg(msg);4171 return sema.failWithOwnedErrorMsg(msg);
4239 }4172 }
42404173
4241 if ((is_comptime or block.is_comptime) and4174 if (block.is_comptime and
4242 (try sema.resolveDefinedValue(block, init_src, union_ptr)) != null)4175 (try sema.resolveDefinedValue(block, init_src, union_ptr)) != null)
4243 {4176 {
4244 // In this case, comptime machinery already did everything. No work to do here.4177 // In this case, comptime machinery already did everything. No work to do here.
...@@ -4342,7 +4275,6 @@ fn validateStructInit(...@@ -4342,7 +4275,6 @@ fn validateStructInit(
4342 struct_ty: Type,4275 struct_ty: Type,
4343 init_src: LazySrcLoc,4276 init_src: LazySrcLoc,
4344 instrs: []const Zir.Inst.Index,4277 instrs: []const Zir.Inst.Index,
4345 is_comptime: bool,
4346) CompileError!void {4278) CompileError!void {
4347 const gpa = sema.gpa;4279 const gpa = sema.gpa;
43484280
...@@ -4382,7 +4314,7 @@ fn validateStructInit(...@@ -4382,7 +4314,7 @@ fn validateStructInit(
4382 errdefer if (root_msg) |msg| msg.destroy(sema.gpa);4314 errdefer if (root_msg) |msg| msg.destroy(sema.gpa);
43834315
4384 const struct_ptr = try sema.resolveInst(struct_ptr_zir_ref);4316 const struct_ptr = try sema.resolveInst(struct_ptr_zir_ref);
4385 if ((is_comptime or block.is_comptime) and4317 if (block.is_comptime and
4386 (try sema.resolveDefinedValue(block, init_src, struct_ptr)) != null)4318 (try sema.resolveDefinedValue(block, init_src, struct_ptr)) != null)
4387 {4319 {
4388 try sema.resolveStructLayout(struct_ty);4320 try sema.resolveStructLayout(struct_ty);
...@@ -4606,7 +4538,6 @@ fn zirValidateArrayInit(...@@ -4606,7 +4538,6 @@ fn zirValidateArrayInit(
4606 sema: *Sema,4538 sema: *Sema,
4607 block: *Block,4539 block: *Block,
4608 inst: Zir.Inst.Index,4540 inst: Zir.Inst.Index,
4609 is_comptime: bool,
4610) CompileError!void {4541) CompileError!void {
4611 const validate_inst = sema.code.instructions.items(.data)[inst].pl_node;4542 const validate_inst = sema.code.instructions.items(.data)[inst].pl_node;
4612 const init_src = validate_inst.src();4543 const init_src = validate_inst.src();
...@@ -4654,7 +4585,7 @@ fn zirValidateArrayInit(...@@ -4654,7 +4585,7 @@ fn zirValidateArrayInit(
4654 else => unreachable,4585 else => unreachable,
4655 };4586 };
46564587
4657 if ((is_comptime or block.is_comptime) and4588 if (block.is_comptime and
4658 (try sema.resolveDefinedValue(block, init_src, array_ptr)) != null)4589 (try sema.resolveDefinedValue(block, init_src, array_ptr)) != null)
4659 {4590 {
4660 // In this case the comptime machinery will have evaluated the store instructions4591 // In this case the comptime machinery will have evaluated the store instructions
...@@ -5222,12 +5153,12 @@ fn zirCompileLog(...@@ -5222,12 +5153,12 @@ fn zirCompileLog(
5222 return Air.Inst.Ref.void_value;5153 return Air.Inst.Ref.void_value;
5223}5154}
52245155
5225fn zirPanic(sema: *Sema, block: *Block, inst: Zir.Inst.Index, force_comptime: bool) CompileError!Zir.Inst.Index {5156fn zirPanic(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Zir.Inst.Index {
5226 const inst_data = sema.code.instructions.items(.data)[inst].un_node;5157 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
5227 const src = inst_data.src();5158 const src = inst_data.src();
5228 const msg_inst = try sema.resolveInst(inst_data.operand);5159 const msg_inst = try sema.resolveInst(inst_data.operand);
52295160
5230 if (block.is_comptime or force_comptime) {5161 if (block.is_comptime) {
5231 return sema.fail(block, src, "encountered @panic at comptime", .{});5162 return sema.fail(block, src, "encountered @panic at comptime", .{});
5232 }5163 }
5233 try sema.panicWithMsg(block, src, msg_inst);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,7 +5372,7 @@ fn zirSuspendBlock(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) Comp
5441 return sema.failWithUseOfAsync(parent_block, src);5372 return sema.failWithUseOfAsync(parent_block, src);
5442}5373}
54435374
5444fn zirBlock(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {5375fn zirBlock(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index, force_comptime: bool) CompileError!Air.Inst.Ref {
5445 const tracy = trace(@src());5376 const tracy = trace(@src());
5446 defer tracy.end();5377 defer tracy.end();
54475378
...@@ -5479,7 +5410,7 @@ fn zirBlock(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileErro...@@ -5479,7 +5410,7 @@ fn zirBlock(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileErro
5479 .instructions = .{},5410 .instructions = .{},
5480 .label = &label,5411 .label = &label,
5481 .inlining = parent_block.inlining,5412 .inlining = parent_block.inlining,
5482 .is_comptime = parent_block.is_comptime,5413 .is_comptime = parent_block.is_comptime or force_comptime,
5483 .comptime_reason = parent_block.comptime_reason,5414 .comptime_reason = parent_block.comptime_reason,
5484 .is_typeof = parent_block.is_typeof,5415 .is_typeof = parent_block.is_typeof,
5485 .want_safety = parent_block.want_safety,5416 .want_safety = parent_block.want_safety,
...@@ -17140,7 +17071,7 @@ fn zirUnreachable(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -17140,7 +17071,7 @@ fn zirUnreachable(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
17140 const inst_data = sema.code.instructions.items(.data)[inst].@"unreachable";17071 const inst_data = sema.code.instructions.items(.data)[inst].@"unreachable";
17141 const src = inst_data.src();17072 const src = inst_data.src();
1714217073
17143 if (block.is_comptime or inst_data.force_comptime) {17074 if (block.is_comptime) {
17144 return sema.fail(block, src, "reached unreachable code", .{});17075 return sema.fail(block, src, "reached unreachable code", .{});
17145 }17076 }
17146 // TODO Add compile error for @optimizeFor occurring too late in a scope.17077 // TODO Add compile error for @optimizeFor occurring too late in a scope.
...@@ -17410,6 +17341,8 @@ fn analyzeRet(...@@ -17410,6 +17341,8 @@ fn analyzeRet(
17410 try inlining.merges.results.append(sema.gpa, operand);17341 try inlining.merges.results.append(sema.gpa, operand);
17411 _ = try block.addBr(inlining.merges.block_inst, operand);17342 _ = try block.addBr(inlining.merges.block_inst, operand);
17412 return always_noreturn;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 }
1741417347
17415 try sema.resolveTypeLayout(sema.fn_ret_ty);17348 try sema.resolveTypeLayout(sema.fn_ret_ty);
...@@ -17422,6 +17355,7 @@ fn analyzeRet(...@@ -17422,6 +17355,7 @@ fn analyzeRet(
17422 }17355 }
1742317356
17424 _ = try block.addUnOp(.ret, operand);17357 _ = try block.addUnOp(.ret, operand);
17358
17425 return always_noreturn;17359 return always_noreturn;
17426}17360}
1742717361
...@@ -21560,7 +21494,7 @@ fn zirBuiltinCall(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -21560,7 +21494,7 @@ fn zirBuiltinCall(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
21560 switch (modifier) {21494 switch (modifier) {
21561 // These can be upgraded to comptime or nosuspend calls.21495 // These can be upgraded to comptime or nosuspend calls.
21562 .auto, .never_tail, .no_async => {21496 .auto, .never_tail, .no_async => {
21563 if (extra.flags.is_comptime) {21497 if (block.is_comptime) {
21564 if (modifier == .never_tail) {21498 if (modifier == .never_tail) {
21565 return sema.fail(block, modifier_src, "unable to perform 'never_tail' call at compile-time", .{});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,12 +21509,12 @@ fn zirBuiltinCall(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
21575 return sema.fail(block, func_src, "modifier '{s}' requires a comptime-known function", .{@tagName(modifier)});21509 return sema.fail(block, func_src, "modifier '{s}' requires a comptime-known function", .{@tagName(modifier)});
21576 };21510 };
2157721511
21578 if (extra.flags.is_comptime) {21512 if (block.is_comptime) {
21579 modifier = .compile_time;21513 modifier = .compile_time;
21580 }21514 }
21581 },21515 },
21582 .always_tail => {21516 .always_tail => {
21583 if (extra.flags.is_comptime) {21517 if (block.is_comptime) {
21584 modifier = .compile_time;21518 modifier = .compile_time;
21585 }21519 }
21586 },21520 },
...@@ -21588,12 +21522,12 @@ fn zirBuiltinCall(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -21588,12 +21522,12 @@ fn zirBuiltinCall(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
21588 if (extra.flags.is_nosuspend) {21522 if (extra.flags.is_nosuspend) {
21589 return sema.fail(block, modifier_src, "modifier 'async_kw' cannot be used inside nosuspend block", .{});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 return sema.fail(block, modifier_src, "modifier 'async_kw' cannot be used in combination with comptime function call", .{});21526 return sema.fail(block, modifier_src, "modifier 'async_kw' cannot be used in combination with comptime function call", .{});
21593 }21527 }
21594 },21528 },
21595 .never_inline => {21529 .never_inline => {
21596 if (extra.flags.is_comptime) {21530 if (block.is_comptime) {
21597 return sema.fail(block, modifier_src, "unable to perform 'never_inline' call at compile-time", .{});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,6 +258,9 @@ pub const Inst = struct {
258 /// A labeled block of code, which can return a value.258 /// A labeled block of code, which can return a value.
259 /// Uses the `pl_node` union field. Payload is `Block`.259 /// Uses the `pl_node` union field. Payload is `Block`.
260 block,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 /// A list of instructions which are analyzed in the parent context, without264 /// A list of instructions which are analyzed in the parent context, without
262 /// generating a runtime block. Must terminate with an "inline" variant of265 /// generating a runtime block. Must terminate with an "inline" variant of
263 /// a noreturn instruction.266 /// a noreturn instruction.
...@@ -338,14 +341,8 @@ pub const Inst = struct {...@@ -338,14 +341,8 @@ pub const Inst = struct {
338 /// payload value, as if `err_union_payload_unsafe` was executed on the operand.341 /// payload value, as if `err_union_payload_unsafe` was executed on the operand.
339 /// Uses the `pl_node` union field. Payload is `Try`.342 /// Uses the `pl_node` union field. Payload is `Try`.
340 @"try",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 /// Same as `try` except the operand is a pointer and the result is a pointer.344 /// Same as `try` except the operand is a pointer and the result is a pointer.
346 try_ptr,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 /// An error set type definition. Contains a list of field names.346 /// An error set type definition. Contains a list of field names.
350 /// Uses the `pl_node` union field. Payload is `ErrorSetDecl`.347 /// Uses the `pl_node` union field. Payload is `ErrorSetDecl`.
351 error_set_decl,348 error_set_decl,
...@@ -723,9 +720,6 @@ pub const Inst = struct {...@@ -723,9 +720,6 @@ pub const Inst = struct {
723 /// because it must use one of them to find out the struct type.720 /// because it must use one of them to find out the struct type.
724 /// Uses the `pl_node` field. Payload is `Block`.721 /// Uses the `pl_node` field. Payload is `Block`.
725 validate_struct_init,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 /// Given a set of `elem_ptr_imm` instructions, assumes they are all part of an723 /// Given a set of `elem_ptr_imm` instructions, assumes they are all part of an
730 /// array initialization expression, and emits a compile error if the number of724 /// array initialization expression, and emits a compile error if the number of
731 /// elements does not match the array type.725 /// elements does not match the array type.
...@@ -733,9 +727,6 @@ pub const Inst = struct {...@@ -733,9 +727,6 @@ pub const Inst = struct {
733 /// because it must use one of them to find out the array type.727 /// because it must use one of them to find out the array type.
734 /// Uses the `pl_node` field. Payload is `Block`.728 /// Uses the `pl_node` field. Payload is `Block`.
735 validate_array_init,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 /// Check that operand type supports the dereference operand (.*).730 /// Check that operand type supports the dereference operand (.*).
740 /// Uses the `un_node` field.731 /// Uses the `un_node` field.
741 validate_deref,732 validate_deref,
...@@ -806,8 +797,6 @@ pub const Inst = struct {...@@ -806,8 +797,6 @@ pub const Inst = struct {
806 error_name,797 error_name,
807 /// Implement builtin `@panic`. Uses `un_node`.798 /// Implement builtin `@panic`. Uses `un_node`.
808 panic,799 panic,
809 /// Same as `panic` but forces comptime.
810 panic_comptime,
811 /// Implements `@trap`.800 /// Implements `@trap`.
812 /// Uses the `node` field.801 /// Uses the `node` field.
813 trap,802 trap,
...@@ -1050,6 +1039,7 @@ pub const Inst = struct {...@@ -1050,6 +1039,7 @@ pub const Inst = struct {
1050 .bitcast,1039 .bitcast,
1051 .bit_or,1040 .bit_or,
1052 .block,1041 .block,
1042 .block_comptime,
1053 .block_inline,1043 .block_inline,
1054 .suspend_block,1044 .suspend_block,
1055 .loop,1045 .loop,
...@@ -1162,9 +1152,7 @@ pub const Inst = struct {...@@ -1162,9 +1152,7 @@ pub const Inst = struct {
1162 .validate_array_init_ty,1152 .validate_array_init_ty,
1163 .validate_struct_init_ty,1153 .validate_struct_init_ty,
1164 .validate_struct_init,1154 .validate_struct_init,
1165 .validate_struct_init_comptime,
1166 .validate_array_init,1155 .validate_array_init,
1167 .validate_array_init_comptime,
1168 .validate_deref,1156 .validate_deref,
1169 .struct_init_empty,1157 .struct_init_empty,
1170 .struct_init,1158 .struct_init,
...@@ -1254,8 +1242,6 @@ pub const Inst = struct {...@@ -1254,8 +1242,6 @@ pub const Inst = struct {
1254 .ret_type,1242 .ret_type,
1255 .@"try",1243 .@"try",
1256 .try_ptr,1244 .try_ptr,
1257 //.try_inline,
1258 //.try_ptr_inline,
1259 .@"defer",1245 .@"defer",
1260 .defer_err_code,1246 .defer_err_code,
1261 .save_err_ret_index,1247 .save_err_ret_index,
...@@ -1276,7 +1262,6 @@ pub const Inst = struct {...@@ -1276,7 +1262,6 @@ pub const Inst = struct {
1276 .repeat,1262 .repeat,
1277 .repeat_inline,1263 .repeat_inline,
1278 .panic,1264 .panic,
1279 .panic_comptime,
1280 .trap,1265 .trap,
1281 .check_comptime_control_flow,1266 .check_comptime_control_flow,
1282 => true,1267 => true,
...@@ -1318,9 +1303,7 @@ pub const Inst = struct {...@@ -1318,9 +1303,7 @@ pub const Inst = struct {
1318 .validate_array_init_ty,1303 .validate_array_init_ty,
1319 .validate_struct_init_ty,1304 .validate_struct_init_ty,
1320 .validate_struct_init,1305 .validate_struct_init,
1321 .validate_struct_init_comptime,
1322 .validate_array_init,1306 .validate_array_init,
1323 .validate_array_init_comptime,
1324 .validate_deref,1307 .validate_deref,
1325 .@"export",1308 .@"export",
1326 .export_value,1309 .export_value,
...@@ -1365,6 +1348,7 @@ pub const Inst = struct {...@@ -1365,6 +1348,7 @@ pub const Inst = struct {
1365 .bitcast,1348 .bitcast,
1366 .bit_or,1349 .bit_or,
1367 .block,1350 .block,
1351 .block_comptime,
1368 .block_inline,1352 .block_inline,
1369 .suspend_block,1353 .suspend_block,
1370 .loop,1354 .loop,
...@@ -1552,13 +1536,10 @@ pub const Inst = struct {...@@ -1552,13 +1536,10 @@ pub const Inst = struct {
1552 .repeat,1536 .repeat,
1553 .repeat_inline,1537 .repeat_inline,
1554 .panic,1538 .panic,
1555 .panic_comptime,
1556 .trap,1539 .trap,
1557 .for_len,1540 .for_len,
1558 .@"try",1541 .@"try",
1559 .try_ptr,1542 .try_ptr,
1560 //.try_inline,
1561 //.try_ptr_inline,
1562 => false,1543 => false,
15631544
1564 .extended => switch (data.extended.opcode) {1545 .extended => switch (data.extended.opcode) {
...@@ -1603,6 +1584,7 @@ pub const Inst = struct {...@@ -1603,6 +1584,7 @@ pub const Inst = struct {
1603 .bit_not = .un_node,1584 .bit_not = .un_node,
1604 .bit_or = .pl_node,1585 .bit_or = .pl_node,
1605 .block = .pl_node,1586 .block = .pl_node,
1587 .block_comptime = .pl_node,
1606 .block_inline = .pl_node,1588 .block_inline = .pl_node,
1607 .suspend_block = .pl_node,1589 .suspend_block = .pl_node,
1608 .bool_not = .un_node,1590 .bool_not = .un_node,
...@@ -1624,8 +1606,6 @@ pub const Inst = struct {...@@ -1624,8 +1606,6 @@ pub const Inst = struct {
1624 .condbr_inline = .pl_node,1606 .condbr_inline = .pl_node,
1625 .@"try" = .pl_node,1607 .@"try" = .pl_node,
1626 .try_ptr = .pl_node,1608 .try_ptr = .pl_node,
1627 //.try_inline = .pl_node,
1628 //.try_ptr_inline = .pl_node,
1629 .error_set_decl = .pl_node,1609 .error_set_decl = .pl_node,
1630 .error_set_decl_anon = .pl_node,1610 .error_set_decl_anon = .pl_node,
1631 .error_set_decl_func = .pl_node,1611 .error_set_decl_func = .pl_node,
...@@ -1721,9 +1701,7 @@ pub const Inst = struct {...@@ -1721,9 +1701,7 @@ pub const Inst = struct {
1721 .validate_array_init_ty = .pl_node,1701 .validate_array_init_ty = .pl_node,
1722 .validate_struct_init_ty = .un_node,1702 .validate_struct_init_ty = .un_node,
1723 .validate_struct_init = .pl_node,1703 .validate_struct_init = .pl_node,
1724 .validate_struct_init_comptime = .pl_node,
1725 .validate_array_init = .pl_node,1704 .validate_array_init = .pl_node,
1726 .validate_array_init_comptime = .pl_node,
1727 .validate_deref = .un_node,1705 .validate_deref = .un_node,
1728 .struct_init_empty = .un_node,1706 .struct_init_empty = .un_node,
1729 .field_type = .pl_node,1707 .field_type = .pl_node,
...@@ -1750,7 +1728,6 @@ pub const Inst = struct {...@@ -1750,7 +1728,6 @@ pub const Inst = struct {
1750 .embed_file = .un_node,1728 .embed_file = .un_node,
1751 .error_name = .un_node,1729 .error_name = .un_node,
1752 .panic = .un_node,1730 .panic = .un_node,
1753 .panic_comptime = .un_node,
1754 .trap = .node,1731 .trap = .node,
1755 .set_runtime_safety = .un_node,1732 .set_runtime_safety = .un_node,
1756 .sqrt = .un_node,1733 .sqrt = .un_node,
...@@ -2605,7 +2582,6 @@ pub const Inst = struct {...@@ -2605,7 +2582,6 @@ pub const Inst = struct {
2605 /// Offset from Decl AST node index.2582 /// Offset from Decl AST node index.
2606 /// `Tag` determines which kind of AST node this points to.2583 /// `Tag` determines which kind of AST node this points to.
2607 src_node: i32,2584 src_node: i32,
2608 force_comptime: bool,
26092585
2610 pub fn src(self: @This()) LazySrcLoc {2586 pub fn src(self: @This()) LazySrcLoc {
2611 return LazySrcLoc.nodeOffset(self.src_node);2587 return LazySrcLoc.nodeOffset(self.src_node);
...@@ -2920,9 +2896,8 @@ pub const Inst = struct {...@@ -2920,9 +2896,8 @@ pub const Inst = struct {
29202896
2921 pub const Flags = packed struct {2897 pub const Flags = packed struct {
2922 is_nosuspend: bool,2898 is_nosuspend: bool,
2923 is_comptime: bool,
2924 ensure_result_used: bool,2899 ensure_result_used: bool,
2925 _: u29 = undefined,2900 _: u30 = undefined,
29262901
2927 comptime {2902 comptime {
2928 if (@sizeOf(Flags) != 4 or @bitSizeOf(Flags) != 32)2903 if (@sizeOf(Flags) != 4 or @bitSizeOf(Flags) != 32)
...@@ -3912,7 +3887,7 @@ fn findDeclsInner(...@@ -3912,7 +3887,7 @@ fn findDeclsInner(
39123887
3913 // Block instructions, recurse over the bodies.3888 // Block instructions, recurse over the bodies.
39143889
3915 .block, .block_inline => {3890 .block, .block_comptime, .block_inline => {
3916 const inst_data = datas[inst].pl_node;3891 const inst_data = datas[inst].pl_node;
3917 const extra = zir.extraData(Inst.Block, inst_data.payload_index);3892 const extra = zir.extraData(Inst.Block, inst_data.payload_index);
3918 const body = zir.extra[extra.end..][0..extra.data.body_len];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,7 +4114,9 @@ pub fn getFnInfo(zir: Zir, fn_inst: Inst.Index) FnInfo {
4139 },4114 },
4140 else => unreachable,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 const param_block = zir.extraData(Inst.Block, datas[info.param_block].pl_node.payload_index);4120 const param_block = zir.extraData(Inst.Block, datas[info.param_block].pl_node.payload_index);
4144 const param_body = zir.extra[param_block.end..][0..param_block.data.body_len];4121 const param_body = zir.extra[param_block.end..][0..param_block.data.body_len];
4145 var total_params_len: u32 = 0;4122 var total_params_len: u32 = 0;
src/print_zir.zig+1-4
...@@ -195,7 +195,6 @@ const Writer = struct {...@@ -195,7 +195,6 @@ const Writer = struct {
195 .embed_file,195 .embed_file,
196 .error_name,196 .error_name,
197 .panic,197 .panic,
198 .panic_comptime,
199 .set_runtime_safety,198 .set_runtime_safety,
200 .sqrt,199 .sqrt,
201 .sin,200 .sin,
...@@ -365,13 +364,12 @@ const Writer = struct {...@@ -365,13 +364,12 @@ const Writer = struct {
365 .call => try self.writeCall(stream, inst),364 .call => try self.writeCall(stream, inst),
366365
367 .block,366 .block,
367 .block_comptime,
368 .block_inline,368 .block_inline,
369 .suspend_block,369 .suspend_block,
370 .loop,370 .loop,
371 .validate_struct_init,371 .validate_struct_init,
372 .validate_struct_init_comptime,
373 .validate_array_init,372 .validate_array_init,
374 .validate_array_init_comptime,
375 .c_import,373 .c_import,
376 .typeof_builtin,374 .typeof_builtin,
377 => try self.writeBlock(stream, inst),375 => try self.writeBlock(stream, inst),
...@@ -811,7 +809,6 @@ const Writer = struct {...@@ -811,7 +809,6 @@ const Writer = struct {
811809
812 try self.writeFlag(stream, "nodiscard ", extra.flags.ensure_result_used);810 try self.writeFlag(stream, "nodiscard ", extra.flags.ensure_result_used);
813 try self.writeFlag(stream, "nosuspend ", extra.flags.is_nosuspend);811 try self.writeFlag(stream, "nosuspend ", extra.flags.is_nosuspend);
814 try self.writeFlag(stream, "comptime ", extra.flags.is_comptime);
815812
816 try self.writeInstRef(stream, extra.modifier);813 try self.writeInstRef(stream, extra.modifier);
817 try stream.writeAll(", ");814 try stream.writeAll(", ");
test/behavior/cast.zig+1-10
...@@ -1455,7 +1455,7 @@ test "floatToInt to zero-bit int" {...@@ -1455,7 +1455,7 @@ test "floatToInt to zero-bit int" {
1455 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1455 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1456 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1456 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
14571457
1458 var a: f32 = 0.0;1458 const a: f32 = 0.0;
1459 comptime try std.testing.expect(@floatToInt(u0, a) == 0);1459 comptime try std.testing.expect(@floatToInt(u0, a) == 0);
1460}1460}
14611461
...@@ -1507,15 +1507,6 @@ test "optional pointer coerced to optional allowzero pointer" {...@@ -1507,15 +1507,6 @@ test "optional pointer coerced to optional allowzero pointer" {
1507 try expect(@ptrToInt(q.?) == 4);1507 try expect(@ptrToInt(q.?) == 4);
1508}1508}
15091509
1510test "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
1519test "single item pointer to pointer to array to slice" {1510test "single item pointer to pointer to array to slice" {
1520 var x: i32 = 1234;1511 var x: i32 = 1234;
1521 try expect(@as([]const i32, @as(*[1]i32, &x))[0] == 1234);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,9 +181,7 @@ fn testTryToTrickEvalWithRuntimeIf(b: bool) usize {
181 const result = if (b) false else true;181 const result = if (b) false else true;
182 _ = result;182 _ = result;
183 }183 }
184 comptime {184 return comptime i;
185 return i;
186 }
187}185}
188186
189test "@setEvalBranchQuota" {187test "@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,7 +16,6 @@ pub export fn entry2() void {
16// backend=stage216// backend=stage2
17// target=native17// target=native
18//18//
19// :4:15: error: unable to resolve comptime value19// :4:15: error: unable to evaluate comptime expression
20// :4:15: note: condition in comptime branch must be comptime-known20// :4:13: note: operation is runtime due to this operand
21// :11:11: error: unable to resolve comptime value21// :11:11: error: unable to evaluate comptime expression
22// :11:11: note: condition in comptime branch must be comptime-known
test/cases/compile_errors/ignored_comptime_value.zig+4-10
...@@ -5,13 +5,7 @@ export fn b() void {...@@ -5,13 +5,7 @@ export fn b() void {
5 comptime bar();5 comptime bar();
6}6}
7fn bar() u8 {7fn bar() u8 {
8 const u32_max = @import("std").math.maxInt(u32);8 return 2;
9
10 @setEvalBranchQuota(u32_max);
11 var x: u32 = 0;
12 while (x != u32_max) : (x +%= 1) {}
13
14 return 0;
15}9}
1610
17// error11// error
...@@ -21,6 +15,6 @@ fn bar() u8 {...@@ -21,6 +15,6 @@ fn bar() u8 {
21// :2:5: error: value of type 'comptime_int' ignored15// :2:5: error: value of type 'comptime_int' ignored
22// :2:5: note: all non-void values must be used16// :2:5: note: all non-void values must be used
23// :2:5: note: this error can be suppressed by assigning the value to '_'17// :2:5: note: this error can be suppressed by assigning the value to '_'
24// :5:17: error: value of type 'u8' ignored18// :5:5: error: value of type 'u8' ignored
25// :5:17: note: all non-void values must be used19// :5:5: note: all non-void values must be used
26// :5:17: note: this error can be suppressed by assigning the value to '_'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,7 +718,7 @@ const TestManifestConfigDefaults = struct {
718 if (@"type" == .@"error") {718 if (@"type" == .@"error") {
719 return "native";719 return "native";
720 }720 }
721 comptime {721 return comptime blk: {
722 var defaults: []const u8 = "";722 var defaults: []const u8 = "";
723 // TODO should we only return "mainstream" targets by default here?723 // TODO should we only return "mainstream" targets by default here?
724 // TODO we should also specify ABIs explicitly as the backends are724 // TODO we should also specify ABIs explicitly as the backends are
...@@ -735,8 +735,8 @@ const TestManifestConfigDefaults = struct {...@@ -735,8 +735,8 @@ const TestManifestConfigDefaults = struct {
735 defaults = defaults ++ "x86_64-windows" ++ ",";735 defaults = defaults ++ "x86_64-windows" ++ ",";
736 // Wasm736 // Wasm
737 defaults = defaults ++ "wasm32-wasi";737 defaults = defaults ++ "wasm32-wasi";
738 return defaults;738 break :blk defaults;
739 }739 };
740 } else if (std.mem.eql(u8, key, "output_mode")) {740 } else if (std.mem.eql(u8, key, "output_mode")) {
741 return switch (@"type") {741 return switch (@"type") {
742 .@"error" => "Obj",742 .@"error" => "Obj",