authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2023-08-14 13:06:47+01:00
committergravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2023-08-15 11:45:23+01:00
log083ee8e0e28ed0d1c4e1df6b5aa12f2709731b50
treebe33c2a904c85361b9f732d6e57284754859f8e0
parent6e2eb208aac8bb6065992bd19a6c0cc772648263
signaturelock-open Commit is signed but in an unrecognized format.

InternPool: preserve indices of builtin types when resolved

Some builtin types have a special InternPool index (e.g. `.type_info_type`) so that AstGen can refer to them before semantic analysis. Unfortunately, this previously led to a second index existing to refer to the type once it was resolved, complicating Sema by having the concept of an "unresolved" type index. This change makes Sema modify these InternPool indices in-place to contain the expanded representation when resolved. The analysis of the corresponding decls is caught in `Module.semaDecl`, and a field is set on Sema telling it which index to place struct/union/enum types at. This system could break if `std.builtin` contained complex decls which evaluate multiple struct types, but this will be caught by the assertions in `InternPool.resolveBuiltinType`. The AstGen result types which were disabled in 6917a8c have been re-enabled. Resolves: #16603

6 files changed, 293 insertions(+), 211 deletions(-)

src/AstGen.zig+6-24
...@@ -8384,10 +8384,7 @@ fn builtinCall(...@@ -8384,10 +8384,7 @@ fn builtinCall(
8384 local_val.used = ident_token;8384 local_val.used = ident_token;
8385 _ = try gz.addPlNode(.export_value, node, Zir.Inst.ExportValue{8385 _ = try gz.addPlNode(.export_value, node, Zir.Inst.ExportValue{
8386 .operand = local_val.inst,8386 .operand = local_val.inst,
8387 // TODO: the result location here should be `.{ .coerced_ty = .export_options_type }`, but8387 .options = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = .export_options_type } }, params[1]),
8388 // that currently hits assertions in Sema due to type resolution issues.
8389 // See #16603
8390 .options = try comptimeExpr(gz, scope, .{ .rl = .none }, params[1]),
8391 });8388 });
8392 return rvalue(gz, ri, .void_value, node);8389 return rvalue(gz, ri, .void_value, node);
8393 }8390 }
...@@ -8402,10 +8399,7 @@ fn builtinCall(...@@ -8402,10 +8399,7 @@ fn builtinCall(
8402 const loaded = try gz.addUnNode(.load, local_ptr.ptr, node);8399 const loaded = try gz.addUnNode(.load, local_ptr.ptr, node);
8403 _ = try gz.addPlNode(.export_value, node, Zir.Inst.ExportValue{8400 _ = try gz.addPlNode(.export_value, node, Zir.Inst.ExportValue{
8404 .operand = loaded,8401 .operand = loaded,
8405 // TODO: the result location here should be `.{ .coerced_ty = .export_options_type }`, but8402 .options = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = .export_options_type } }, params[1]),
8406 // that currently hits assertions in Sema due to type resolution issues.
8407 // See #16603
8408 .options = try comptimeExpr(gz, scope, .{ .rl = .none }, params[1]),
8409 });8403 });
8410 return rvalue(gz, ri, .void_value, node);8404 return rvalue(gz, ri, .void_value, node);
8411 }8405 }
...@@ -8439,10 +8433,7 @@ fn builtinCall(...@@ -8439,10 +8433,7 @@ fn builtinCall(
8439 },8433 },
8440 else => return astgen.failNode(params[0], "symbol to export must identify a declaration", .{}),8434 else => return astgen.failNode(params[0], "symbol to export must identify a declaration", .{}),
8441 }8435 }
8442 // TODO: the result location here should be `.{ .coerced_ty = .export_options_type }`, but8436 const options = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = .export_options_type } }, params[1]);
8443 // that currently hits assertions in Sema due to type resolution issues.
8444 // See #16603
8445 const options = try comptimeExpr(gz, scope, .{ .rl = .none }, params[1]);
8446 _ = try gz.addPlNode(.@"export", node, Zir.Inst.Export{8437 _ = try gz.addPlNode(.@"export", node, Zir.Inst.Export{
8447 .namespace = namespace,8438 .namespace = namespace,
8448 .decl_name = decl_name,8439 .decl_name = decl_name,
...@@ -8452,10 +8443,7 @@ fn builtinCall(...@@ -8452,10 +8443,7 @@ fn builtinCall(
8452 },8443 },
8453 .@"extern" => {8444 .@"extern" => {
8454 const type_inst = try typeExpr(gz, scope, params[0]);8445 const type_inst = try typeExpr(gz, scope, params[0]);
8455 // TODO: the result location here should be `.{ .coerced_ty = .extern_options_type }`, but8446 const options = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = .extern_options_type } }, params[1]);
8456 // that currently hits assertions in Sema due to type resolution issues.
8457 // See #16603
8458 const options = try comptimeExpr(gz, scope, .{ .rl = .none }, params[1]);
8459 const result = try gz.addExtendedPayload(.builtin_extern, Zir.Inst.BinNode{8447 const result = try gz.addExtendedPayload(.builtin_extern, Zir.Inst.BinNode{
8460 .node = gz.nodeIndexToRelative(node),8448 .node = gz.nodeIndexToRelative(node),
8461 .lhs = type_inst,8449 .lhs = type_inst,
...@@ -8559,10 +8547,7 @@ fn builtinCall(...@@ -8559,10 +8547,7 @@ fn builtinCall(
8559 // zig fmt: on8547 // zig fmt: on
85608548
8561 .Type => {8549 .Type => {
8562 // TODO: the result location here should be `.{ .coerced_ty = .type_info_type }`, but8550 const operand = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .type_info_type } }, params[0]);
8563 // that currently hits assertions in Sema due to type resolution issues.
8564 // See #16603
8565 const operand = try expr(gz, scope, .{ .rl = .none }, params[0]);
85668551
8567 const gpa = gz.astgen.gpa;8552 const gpa = gz.astgen.gpa;
85688553
...@@ -8834,10 +8819,7 @@ fn builtinCall(...@@ -8834,10 +8819,7 @@ fn builtinCall(
8834 },8819 },
8835 .prefetch => {8820 .prefetch => {
8836 const ptr = try expr(gz, scope, .{ .rl = .none }, params[0]);8821 const ptr = try expr(gz, scope, .{ .rl = .none }, params[0]);
8837 // TODO: the result location here should be `.{ .coerced_ty = .preftech_options_type }`, but8822 const options = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = .prefetch_options_type } }, params[1]);
8838 // that currently hits assertions in Sema due to type resolution issues.
8839 // See #16603
8840 const options = try comptimeExpr(gz, scope, .{ .rl = .none }, params[1]);
8841 _ = try gz.addExtendedPayload(.prefetch, Zir.Inst.BinNode{8823 _ = try gz.addExtendedPayload(.prefetch, Zir.Inst.BinNode{
8842 .node = gz.nodeIndexToRelative(node),8824 .node = gz.nodeIndexToRelative(node),
8843 .lhs = ptr,8825 .lhs = ptr,
src/InternPool.zig+30
...@@ -7176,3 +7176,33 @@ fn unwrapCoercedFunc(ip: *const InternPool, i: Index) Index {...@@ -7176,3 +7176,33 @@ fn unwrapCoercedFunc(ip: *const InternPool, i: Index) Index {
7176 else => unreachable,7176 else => unreachable,
7177 };7177 };
7178}7178}
7179
7180/// Having resolved a builtin type to a real struct/union/enum (which is now at `resolverd_index`),
7181/// make `want_index` refer to this type instead. This invalidates `resolved_index`, so must be
7182/// called only when it is guaranteed that no reference to `resolved_index` exists.
7183pub fn resolveBuiltinType(ip: *InternPool, want_index: Index, resolved_index: Index) void {
7184 assert(@intFromEnum(want_index) >= @intFromEnum(Index.first_type));
7185 assert(@intFromEnum(want_index) <= @intFromEnum(Index.last_type));
7186
7187 // Make sure the type isn't already resolved!
7188 assert(ip.indexToKey(want_index) == .simple_type);
7189
7190 // Make sure it's the same kind of type
7191 assert((ip.zigTypeTagOrPoison(want_index) catch unreachable) ==
7192 (ip.zigTypeTagOrPoison(resolved_index) catch unreachable));
7193
7194 // Copy the data
7195 const item = ip.items.get(@intFromEnum(resolved_index));
7196 ip.items.set(@intFromEnum(want_index), item);
7197
7198 if (std.debug.runtime_safety) {
7199 // Make the value unreachable - this is a weird value which will make (incorrect) existing
7200 // references easier to spot
7201 ip.items.set(@intFromEnum(resolved_index), .{
7202 .tag = .simple_value,
7203 .data = @intFromEnum(SimpleValue.@"unreachable"),
7204 });
7205 } else {
7206 // TODO: add the index to a free-list for reuse
7207 }
7208}
src/Module.zig+51-4
...@@ -770,9 +770,8 @@ pub const Decl = struct {...@@ -770,9 +770,8 @@ pub const Decl = struct {
770770
771 /// Gets the namespace that this Decl creates by being a struct, union,771 /// Gets the namespace that this Decl creates by being a struct, union,
772 /// enum, or opaque.772 /// enum, or opaque.
773 /// Only returns it if the Decl is the owner.773 pub fn getInnerNamespaceIndex(decl: Decl, mod: *Module) Namespace.OptionalIndex {
774 pub fn getOwnedInnerNamespaceIndex(decl: Decl, mod: *Module) Namespace.OptionalIndex {774 if (!decl.has_tv) return .none;
775 if (!decl.owns_tv) return .none;
776 return switch (decl.val.ip_index) {775 return switch (decl.val.ip_index) {
777 .empty_struct_type => .none,776 .empty_struct_type => .none,
778 .none => .none,777 .none => .none,
...@@ -786,11 +785,22 @@ pub const Decl = struct {...@@ -786,11 +785,22 @@ pub const Decl = struct {
786 };785 };
787 }786 }
788787
789 /// Same as `getInnerNamespaceIndex` but additionally obtains the pointer.788 /// Like `getInnerNamespaceIndex`, but only returns it if the Decl is the owner.
789 pub fn getOwnedInnerNamespaceIndex(decl: Decl, mod: *Module) Namespace.OptionalIndex {
790 if (!decl.owns_tv) return .none;
791 return decl.getInnerNamespaceIndex(mod);
792 }
793
794 /// Same as `getOwnedInnerNamespaceIndex` but additionally obtains the pointer.
790 pub fn getOwnedInnerNamespace(decl: Decl, mod: *Module) ?*Namespace {795 pub fn getOwnedInnerNamespace(decl: Decl, mod: *Module) ?*Namespace {
791 return mod.namespacePtrUnwrap(decl.getOwnedInnerNamespaceIndex(mod));796 return mod.namespacePtrUnwrap(decl.getOwnedInnerNamespaceIndex(mod));
792 }797 }
793798
799 /// Same as `getInnerNamespaceIndex` but additionally obtains the pointer.
800 pub fn getInnerNamespace(decl: Decl, mod: *Module) ?*Namespace {
801 return mod.namespacePtrUnwrap(decl.getInnerNamespaceIndex(mod));
802 }
803
794 pub fn dump(decl: *Decl) void {804 pub fn dump(decl: *Decl) void {
795 const loc = std.zig.findLineColumn(decl.scope.source.bytes, decl.src);805 const loc = std.zig.findLineColumn(decl.scope.source.bytes, decl.src);
796 std.debug.print("{s}:{d}:{d} name={d} status={s}", .{806 std.debug.print("{s}:{d}:{d} name={d} status={s}", .{
...@@ -4283,6 +4293,40 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {...@@ -4283,6 +4293,40 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
4283 const zir = decl.getFileScope(mod).zir;4293 const zir = decl.getFileScope(mod).zir;
4284 const zir_datas = zir.instructions.items(.data);4294 const zir_datas = zir.instructions.items(.data);
42854295
4296 // TODO: figure out how this works under incremental changes to builtin.zig!
4297 const builtin_type_target_index: InternPool.Index = blk: {
4298 const std_mod = mod.main_pkg.table.get("std").?;
4299 if (decl.getFileScope(mod).pkg != std_mod) break :blk .none;
4300 // We're in the std module.
4301 const std_file = (try mod.importPkg(std_mod)).file;
4302 const std_decl = mod.declPtr(std_file.root_decl.unwrap().?);
4303 const std_namespace = std_decl.getInnerNamespace(mod).?;
4304 const builtin_str = try mod.intern_pool.getOrPutString(gpa, "builtin");
4305 const builtin_decl = mod.declPtr(std_namespace.decls.getKeyAdapted(builtin_str, DeclAdapter{ .mod = mod }) orelse break :blk .none);
4306 const builtin_namespace = builtin_decl.getInnerNamespaceIndex(mod).unwrap() orelse break :blk .none;
4307 if (decl.src_namespace != builtin_namespace) break :blk .none;
4308 // We're in builtin.zig. This could be a builtin we need to add to a specific InternPool index.
4309 const decl_name = mod.intern_pool.stringToSlice(decl.name);
4310 for ([_]struct { []const u8, InternPool.Index }{
4311 .{ "AtomicOrder", .atomic_order_type },
4312 .{ "AtomicRmwOp", .atomic_rmw_op_type },
4313 .{ "CallingConvention", .calling_convention_type },
4314 .{ "AddressSpace", .address_space_type },
4315 .{ "FloatMode", .float_mode_type },
4316 .{ "ReduceOp", .reduce_op_type },
4317 .{ "CallModifier", .call_modifier_type },
4318 .{ "PrefetchOptions", .prefetch_options_type },
4319 .{ "ExportOptions", .export_options_type },
4320 .{ "ExternOptions", .extern_options_type },
4321 .{ "Type", .type_info_type },
4322 }) |pair| {
4323 if (std.mem.eql(u8, decl_name, pair[0])) {
4324 break :blk pair[1];
4325 }
4326 }
4327 break :blk .none;
4328 };
4329
4286 decl.analysis = .in_progress;4330 decl.analysis = .in_progress;
42874331
4288 var analysis_arena = std.heap.ArenaAllocator.init(gpa);4332 var analysis_arena = std.heap.ArenaAllocator.init(gpa);
...@@ -4304,6 +4348,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {...@@ -4304,6 +4348,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
4304 .fn_ret_ty_ies = null,4348 .fn_ret_ty_ies = null,
4305 .owner_func_index = .none,4349 .owner_func_index = .none,
4306 .comptime_mutable_decls = &comptime_mutable_decls,4350 .comptime_mutable_decls = &comptime_mutable_decls,
4351 .builtin_type_target_index = builtin_type_target_index,
4307 };4352 };
4308 defer sema.deinit();4353 defer sema.deinit();
43094354
...@@ -4340,6 +4385,8 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {...@@ -4340,6 +4385,8 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
4340 const extra = zir.extraData(Zir.Inst.Block, inst_data.payload_index);4385 const extra = zir.extraData(Zir.Inst.Block, inst_data.payload_index);
4341 const body = zir.extra[extra.end..][0..extra.data.body_len];4386 const body = zir.extra[extra.end..][0..extra.data.body_len];
4342 const result_ref = (try sema.analyzeBodyBreak(&block_scope, body)).?.operand;4387 const result_ref = (try sema.analyzeBodyBreak(&block_scope, body)).?.operand;
4388 // We'll do some other bits with the Sema. Clear the type target index just in case they analyze any type.
4389 sema.builtin_type_target_index = .none;
4343 try wip_captures.finalize();4390 try wip_captures.finalize();
4344 for (comptime_mutable_decls.items) |ct_decl_index| {4391 for (comptime_mutable_decls.items) |ct_decl_index| {
4345 const ct_decl = mod.declPtr(ct_decl_index);4392 const ct_decl = mod.declPtr(ct_decl_index);
src/Sema.zig+205-171
...@@ -107,6 +107,10 @@ comptime_mutable_decls: *std.ArrayList(Decl.Index),...@@ -107,6 +107,10 @@ comptime_mutable_decls: *std.ArrayList(Decl.Index),
107/// one encountered, the conflicting source location can be shown.107/// one encountered, the conflicting source location can be shown.
108prev_stack_alignment_src: ?LazySrcLoc = null,108prev_stack_alignment_src: ?LazySrcLoc = null,
109109
110/// While analyzing a type which has a special InternPool index, this is set to the index at which
111/// the struct/enum/union type created should be placed. Otherwise, it is `.none`.
112builtin_type_target_index: InternPool.Index = .none,
113
110const std = @import("std");114const std = @import("std");
111const math = std.math;115const math = std.math;
112const mem = std.mem;116const mem = std.mem;
...@@ -1956,8 +1960,8 @@ pub fn setupErrorReturnTrace(sema: *Sema, block: *Block, last_arg_index: usize)...@@ -1956,8 +1960,8 @@ pub fn setupErrorReturnTrace(sema: *Sema, block: *Block, last_arg_index: usize)
1956 const addrs_ptr = try err_trace_block.addTy(.alloc, try mod.singleMutPtrType(addr_arr_ty));1960 const addrs_ptr = try err_trace_block.addTy(.alloc, try mod.singleMutPtrType(addr_arr_ty));
19571961
1958 // var st: StackTrace = undefined;1962 // var st: StackTrace = undefined;
1959 const unresolved_stack_trace_ty = try sema.getBuiltinType("StackTrace");1963 const stack_trace_ty = try sema.getBuiltinType("StackTrace");
1960 const stack_trace_ty = try sema.resolveTypeFields(unresolved_stack_trace_ty);1964 try sema.resolveTypeFields(stack_trace_ty);
1961 const st_ptr = try err_trace_block.addTy(.alloc, try mod.singleMutPtrType(stack_trace_ty));1965 const st_ptr = try err_trace_block.addTy(.alloc, try mod.singleMutPtrType(stack_trace_ty));
19621966
1963 // st.instruction_addresses = &addrs;1967 // st.instruction_addresses = &addrs;
...@@ -2890,10 +2894,17 @@ fn zirStructDecl(...@@ -2890,10 +2894,17 @@ fn zirStructDecl(
2890 });2894 });
2891 errdefer mod.destroyStruct(struct_index);2895 errdefer mod.destroyStruct(struct_index);
28922896
2893 const struct_ty = try mod.intern_pool.get(gpa, .{ .struct_type = .{2897 const struct_ty = ty: {
2894 .index = struct_index.toOptional(),2898 const ty = try mod.intern_pool.get(gpa, .{ .struct_type = .{
2895 .namespace = new_namespace_index.toOptional(),2899 .index = struct_index.toOptional(),
2896 } });2900 .namespace = new_namespace_index.toOptional(),
2901 } });
2902 if (sema.builtin_type_target_index != .none) {
2903 mod.intern_pool.resolveBuiltinType(sema.builtin_type_target_index, ty);
2904 break :ty sema.builtin_type_target_index;
2905 }
2906 break :ty ty;
2907 };
2897 // TODO: figure out InternPool removals for incremental compilation2908 // TODO: figure out InternPool removals for incremental compilation
2898 //errdefer mod.intern_pool.remove(struct_ty);2909 //errdefer mod.intern_pool.remove(struct_ty);
28992910
...@@ -3084,18 +3095,25 @@ fn zirEnumDecl(...@@ -3084,18 +3095,25 @@ fn zirEnumDecl(
3084 if (bag != 0) break true;3095 if (bag != 0) break true;
3085 } else false;3096 } else false;
30863097
3087 const incomplete_enum = try mod.intern_pool.getIncompleteEnum(gpa, .{3098 const incomplete_enum = incomplete_enum: {
3088 .decl = new_decl_index,3099 var incomplete_enum = try mod.intern_pool.getIncompleteEnum(gpa, .{
3089 .namespace = new_namespace_index.toOptional(),3100 .decl = new_decl_index,
3090 .fields_len = fields_len,3101 .namespace = new_namespace_index.toOptional(),
3091 .has_values = any_values,3102 .fields_len = fields_len,
3092 .tag_mode = if (small.nonexhaustive)3103 .has_values = any_values,
3093 .nonexhaustive3104 .tag_mode = if (small.nonexhaustive)
3094 else if (tag_type_ref == .none)3105 .nonexhaustive
3095 .auto3106 else if (tag_type_ref == .none)
3096 else3107 .auto
3097 .explicit,3108 else
3098 });3109 .explicit,
3110 });
3111 if (sema.builtin_type_target_index != .none) {
3112 mod.intern_pool.resolveBuiltinType(sema.builtin_type_target_index, incomplete_enum.index);
3113 incomplete_enum.index = sema.builtin_type_target_index;
3114 }
3115 break :incomplete_enum incomplete_enum;
3116 };
3099 // TODO: figure out InternPool removals for incremental compilation3117 // TODO: figure out InternPool removals for incremental compilation
3100 //errdefer if (!done) mod.intern_pool.remove(incomplete_enum.index);3118 //errdefer if (!done) mod.intern_pool.remove(incomplete_enum.index);
31013119
...@@ -3336,17 +3354,24 @@ fn zirUnionDecl(...@@ -3336,17 +3354,24 @@ fn zirUnionDecl(
3336 });3354 });
3337 errdefer mod.destroyUnion(union_index);3355 errdefer mod.destroyUnion(union_index);
33383356
3339 const union_ty = try mod.intern_pool.get(gpa, .{ .union_type = .{3357 const union_ty = ty: {
3340 .index = union_index,3358 const ty = try mod.intern_pool.get(gpa, .{ .union_type = .{
3341 .runtime_tag = if (small.has_tag_type or small.auto_enum_tag)3359 .index = union_index,
3342 .tagged3360 .runtime_tag = if (small.has_tag_type or small.auto_enum_tag)
3343 else if (small.layout != .Auto)3361 .tagged
3344 .none3362 else if (small.layout != .Auto)
3345 else switch (block.sema.mod.optimizeMode()) {3363 .none
3346 .Debug, .ReleaseSafe => .safety,3364 else switch (block.sema.mod.optimizeMode()) {
3347 .ReleaseFast, .ReleaseSmall => .none,3365 .Debug, .ReleaseSafe => .safety,
3348 },3366 .ReleaseFast, .ReleaseSmall => .none,
3349 } });3367 },
3368 } });
3369 if (sema.builtin_type_target_index != .none) {
3370 mod.intern_pool.resolveBuiltinType(sema.builtin_type_target_index, ty);
3371 break :ty sema.builtin_type_target_index;
3372 }
3373 break :ty ty;
3374 };
3350 // TODO: figure out InternPool removals for incremental compilation3375 // TODO: figure out InternPool removals for incremental compilation
3351 //errdefer mod.intern_pool.remove(union_ty);3376 //errdefer mod.intern_pool.remove(union_ty);
33523377
...@@ -3473,8 +3498,8 @@ fn zirRetPtr(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref {...@@ -3473,8 +3498,8 @@ fn zirRetPtr(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref {
3473 defer tracy.end();3498 defer tracy.end();
34743499
3475 if (block.is_comptime or try sema.typeRequiresComptime(sema.fn_ret_ty)) {3500 if (block.is_comptime or try sema.typeRequiresComptime(sema.fn_ret_ty)) {
3476 const fn_ret_ty = try sema.resolveTypeFields(sema.fn_ret_ty);3501 try sema.resolveTypeFields(sema.fn_ret_ty);
3477 return sema.analyzeComptimeAlloc(block, fn_ret_ty, .none);3502 return sema.analyzeComptimeAlloc(block, sema.fn_ret_ty, .none);
3478 }3503 }
34793504
3480 const target = sema.mod.getTarget();3505 const target = sema.mod.getTarget();
...@@ -4371,7 +4396,7 @@ fn zirValidateArrayInitTy(...@@ -4371,7 +4396,7 @@ fn zirValidateArrayInitTy(
4371 return;4396 return;
4372 },4397 },
4373 .Struct => if (ty.isTuple(mod)) {4398 .Struct => if (ty.isTuple(mod)) {
4374 _ = try sema.resolveTypeFields(ty);4399 try sema.resolveTypeFields(ty);
4375 const array_len = ty.arrayLen(mod);4400 const array_len = ty.arrayLen(mod);
4376 if (extra.init_count > array_len) {4401 if (extra.init_count > array_len) {
4377 return sema.fail(block, src, "expected at most {d} tuple fields; found {d}", .{4402 return sema.fail(block, src, "expected at most {d} tuple fields; found {d}", .{
...@@ -6476,11 +6501,11 @@ pub fn analyzeSaveErrRetIndex(sema: *Sema, block: *Block) SemaError!Air.Inst.Ref...@@ -6476,11 +6501,11 @@ pub fn analyzeSaveErrRetIndex(sema: *Sema, block: *Block) SemaError!Air.Inst.Ref
6476 if (block.is_comptime)6501 if (block.is_comptime)
6477 return .none;6502 return .none;
64786503
6479 const unresolved_stack_trace_ty = sema.getBuiltinType("StackTrace") catch |err| switch (err) {6504 const stack_trace_ty = sema.getBuiltinType("StackTrace") catch |err| switch (err) {
6480 error.NeededSourceLocation, error.GenericPoison, error.ComptimeReturn, error.ComptimeBreak => unreachable,6505 error.NeededSourceLocation, error.GenericPoison, error.ComptimeReturn, error.ComptimeBreak => unreachable,
6481 else => |e| return e,6506 else => |e| return e,
6482 };6507 };
6483 const stack_trace_ty = sema.resolveTypeFields(unresolved_stack_trace_ty) catch |err| switch (err) {6508 sema.resolveTypeFields(stack_trace_ty) catch |err| switch (err) {
6484 error.NeededSourceLocation, error.GenericPoison, error.ComptimeReturn, error.ComptimeBreak => unreachable,6509 error.NeededSourceLocation, error.GenericPoison, error.ComptimeReturn, error.ComptimeBreak => unreachable,
6485 else => |e| return e,6510 else => |e| return e,
6486 };6511 };
...@@ -6522,8 +6547,8 @@ fn popErrorReturnTrace(...@@ -6522,8 +6547,8 @@ fn popErrorReturnTrace(
6522 // AstGen determined this result does not go to an error-handling expr (try/catch/return etc.), or6547 // AstGen determined this result does not go to an error-handling expr (try/catch/return etc.), or
6523 // the result is comptime-known to be a non-error. Either way, pop unconditionally.6548 // the result is comptime-known to be a non-error. Either way, pop unconditionally.
65246549
6525 const unresolved_stack_trace_ty = try sema.getBuiltinType("StackTrace");6550 const stack_trace_ty = try sema.getBuiltinType("StackTrace");
6526 const stack_trace_ty = try sema.resolveTypeFields(unresolved_stack_trace_ty);6551 try sema.resolveTypeFields(stack_trace_ty);
6527 const ptr_stack_trace_ty = try mod.singleMutPtrType(stack_trace_ty);6552 const ptr_stack_trace_ty = try mod.singleMutPtrType(stack_trace_ty);
6528 const err_return_trace = try block.addTy(.err_return_trace, ptr_stack_trace_ty);6553 const err_return_trace = try block.addTy(.err_return_trace, ptr_stack_trace_ty);
6529 const field_name = try mod.intern_pool.getOrPutString(gpa, "index");6554 const field_name = try mod.intern_pool.getOrPutString(gpa, "index");
...@@ -6548,8 +6573,8 @@ fn popErrorReturnTrace(...@@ -6548,8 +6573,8 @@ fn popErrorReturnTrace(
6548 defer then_block.instructions.deinit(gpa);6573 defer then_block.instructions.deinit(gpa);
65496574
6550 // If non-error, then pop the error return trace by restoring the index.6575 // If non-error, then pop the error return trace by restoring the index.
6551 const unresolved_stack_trace_ty = try sema.getBuiltinType("StackTrace");6576 const stack_trace_ty = try sema.getBuiltinType("StackTrace");
6552 const stack_trace_ty = try sema.resolveTypeFields(unresolved_stack_trace_ty);6577 try sema.resolveTypeFields(stack_trace_ty);
6553 const ptr_stack_trace_ty = try mod.singleMutPtrType(stack_trace_ty);6578 const ptr_stack_trace_ty = try mod.singleMutPtrType(stack_trace_ty);
6554 const err_return_trace = try then_block.addTy(.err_return_trace, ptr_stack_trace_ty);6579 const err_return_trace = try then_block.addTy(.err_return_trace, ptr_stack_trace_ty);
6555 const field_name = try mod.intern_pool.getOrPutString(gpa, "index");6580 const field_name = try mod.intern_pool.getOrPutString(gpa, "index");
...@@ -6671,8 +6696,8 @@ fn zirCall(...@@ -6671,8 +6696,8 @@ fn zirCall(
6671 // If any input is an error-type, we might need to pop any trace it generated. Otherwise, we only6696 // If any input is an error-type, we might need to pop any trace it generated. Otherwise, we only
6672 // need to clean-up our own trace if we were passed to a non-error-handling expression.6697 // need to clean-up our own trace if we were passed to a non-error-handling expression.
6673 if (input_is_error or (pop_error_return_trace and return_ty.isError(mod))) {6698 if (input_is_error or (pop_error_return_trace and return_ty.isError(mod))) {
6674 const unresolved_stack_trace_ty = try sema.getBuiltinType("StackTrace");6699 const stack_trace_ty = try sema.getBuiltinType("StackTrace");
6675 const stack_trace_ty = try sema.resolveTypeFields(unresolved_stack_trace_ty);6700 try sema.resolveTypeFields(stack_trace_ty);
6676 const field_name = try mod.intern_pool.getOrPutString(sema.gpa, "index");6701 const field_name = try mod.intern_pool.getOrPutString(sema.gpa, "index");
6677 const field_index = try sema.structFieldIndex(block, stack_trace_ty, field_name, call_src);6702 const field_index = try sema.structFieldIndex(block, stack_trace_ty, field_name, call_src);
66786703
...@@ -8084,7 +8109,7 @@ fn zirOptionalType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro...@@ -8084,7 +8109,7 @@ fn zirOptionalType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
8084fn zirElemTypeIndex(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {8109fn zirElemTypeIndex(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
8085 const mod = sema.mod;8110 const mod = sema.mod;
8086 const bin = sema.code.instructions.items(.data)[inst].bin;8111 const bin = sema.code.instructions.items(.data)[inst].bin;
8087 const operand = sema.resolveType(block, .unneeded, bin.lhs) catch |err| switch (err) {8112 const indexable_ty = sema.resolveType(block, .unneeded, bin.lhs) catch |err| switch (err) {
8088 // Since this is a ZIR instruction that returns a type, encountering8113 // Since this is a ZIR instruction that returns a type, encountering
8089 // generic poison should not result in a failed compilation, but the8114 // generic poison should not result in a failed compilation, but the
8090 // generic poison type. This prevents unnecessary failures when8115 // generic poison type. This prevents unnecessary failures when
...@@ -8092,7 +8117,7 @@ fn zirElemTypeIndex(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr...@@ -8092,7 +8117,7 @@ fn zirElemTypeIndex(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr
8092 error.GenericPoison => return .generic_poison_type,8117 error.GenericPoison => return .generic_poison_type,
8093 else => |e| return e,8118 else => |e| return e,
8094 };8119 };
8095 const indexable_ty = try sema.resolveTypeFields(operand);8120 try sema.resolveTypeFields(indexable_ty);
8096 assert(indexable_ty.isIndexable(mod)); // validated by a previous instruction8121 assert(indexable_ty.isIndexable(mod)); // validated by a previous instruction
8097 if (indexable_ty.zigTypeTag(mod) == .Struct) {8122 if (indexable_ty.zigTypeTag(mod) == .Struct) {
8098 const elem_type = indexable_ty.structFieldType(@intFromEnum(bin.rhs), mod);8123 const elem_type = indexable_ty.structFieldType(@intFromEnum(bin.rhs), mod);
...@@ -8420,8 +8445,8 @@ fn zirIntFromEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -8420,8 +8445,8 @@ fn zirIntFromEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
8420 const enum_tag: Air.Inst.Ref = switch (operand_ty.zigTypeTag(mod)) {8445 const enum_tag: Air.Inst.Ref = switch (operand_ty.zigTypeTag(mod)) {
8421 .Enum => operand,8446 .Enum => operand,
8422 .Union => blk: {8447 .Union => blk: {
8423 const union_ty = try sema.resolveTypeFields(operand_ty);8448 try sema.resolveTypeFields(operand_ty);
8424 const tag_ty = union_ty.unionTagType(mod) orelse {8449 const tag_ty = operand_ty.unionTagType(mod) orelse {
8425 return sema.fail(8450 return sema.fail(
8426 block,8451 block,
8427 operand_src,8452 operand_src,
...@@ -9573,7 +9598,7 @@ fn finishFunc(...@@ -9573,7 +9598,7 @@ fn finishFunc(
9573 // Make sure that StackTrace's fields are resolved so that the backend can9598 // Make sure that StackTrace's fields are resolved so that the backend can
9574 // lower this fn type.9599 // lower this fn type.
9575 const unresolved_stack_trace_ty = try sema.getBuiltinType("StackTrace");9600 const unresolved_stack_trace_ty = try sema.getBuiltinType("StackTrace");
9576 _ = try sema.resolveTypeFields(unresolved_stack_trace_ty);9601 try sema.resolveTypeFields(unresolved_stack_trace_ty);
9577 }9602 }
95789603
9579 return Air.internedToRef(if (opt_func_index != .none) opt_func_index else func_ty);9604 return Air.internedToRef(if (opt_func_index != .none) opt_func_index else func_ty);
...@@ -10890,12 +10915,12 @@ fn switchCond(...@@ -10890,12 +10915,12 @@ fn switchCond(
10890 },10915 },
1089110916
10892 .Union => {10917 .Union => {
10893 const union_ty = try sema.resolveTypeFields(operand_ty);10918 try sema.resolveTypeFields(operand_ty);
10894 const enum_ty = union_ty.unionTagType(mod) orelse {10919 const enum_ty = operand_ty.unionTagType(mod) orelse {
10895 const msg = msg: {10920 const msg = msg: {
10896 const msg = try sema.errMsg(block, src, "switch on union with no attached enum", .{});10921 const msg = try sema.errMsg(block, src, "switch on union with no attached enum", .{});
10897 errdefer msg.destroy(sema.gpa);10922 errdefer msg.destroy(sema.gpa);
10898 if (union_ty.declSrcLocOrNull(mod)) |union_src| {10923 if (operand_ty.declSrcLocOrNull(mod)) |union_src| {
10899 try mod.errNoteNonLazy(union_src, msg, "consider 'union(enum)' here", .{});10924 try mod.errNoteNonLazy(union_src, msg, "consider 'union(enum)' here", .{});
10900 }10925 }
10901 break :msg msg;10926 break :msg msg;
...@@ -12780,9 +12805,9 @@ fn zirHasField(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -12780,9 +12805,9 @@ fn zirHasField(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
12780 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;12805 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
12781 const ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };12806 const ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
12782 const name_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };12807 const name_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };
12783 const unresolved_ty = try sema.resolveType(block, ty_src, extra.lhs);12808 const ty = try sema.resolveType(block, ty_src, extra.lhs);
12784 const field_name = try sema.resolveConstStringIntern(block, name_src, extra.rhs, "field name must be comptime-known");12809 const field_name = try sema.resolveConstStringIntern(block, name_src, extra.rhs, "field name must be comptime-known");
12785 const ty = try sema.resolveTypeFields(unresolved_ty);12810 try sema.resolveTypeFields(ty);
12786 const ip = &mod.intern_pool;12811 const ip = &mod.intern_pool;
1278712812
12788 const has_field = hf: {12813 const has_field = hf: {
...@@ -16141,7 +16166,8 @@ fn analyzeCmpUnionTag(...@@ -16141,7 +16166,8 @@ fn analyzeCmpUnionTag(
16141 op: std.math.CompareOperator,16166 op: std.math.CompareOperator,
16142) CompileError!Air.Inst.Ref {16167) CompileError!Air.Inst.Ref {
16143 const mod = sema.mod;16168 const mod = sema.mod;
16144 const union_ty = try sema.resolveTypeFields(sema.typeOf(un));16169 const union_ty = sema.typeOf(un);
16170 try sema.resolveTypeFields(union_ty);
16145 const union_tag_ty = union_ty.unionTagType(mod) orelse {16171 const union_tag_ty = union_ty.unionTagType(mod) orelse {
16146 const msg = msg: {16172 const msg = msg: {
16147 const msg = try sema.errMsg(block, un_src, "comparison of union and enum literal is only valid for tagged union types", .{});16173 const msg = try sema.errMsg(block, un_src, "comparison of union and enum literal is only valid for tagged union types", .{});
...@@ -17278,11 +17304,10 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17278,11 +17304,10 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17278 break :t union_field_ty_decl.val.toType();17304 break :t union_field_ty_decl.val.toType();
17279 };17305 };
1728017306
17281 const union_ty = try sema.resolveTypeFields(ty);
17282 try sema.resolveTypeLayout(ty); // Getting alignment requires type layout17307 try sema.resolveTypeLayout(ty); // Getting alignment requires type layout
17283 const layout = union_ty.containerLayout(mod);17308 const layout = ty.containerLayout(mod);
1728417309
17285 const union_fields = union_ty.unionFields(mod);17310 const union_fields = ty.unionFields(mod);
17286 const union_field_vals = try gpa.alloc(InternPool.Index, union_fields.count());17311 const union_field_vals = try gpa.alloc(InternPool.Index, union_fields.count());
17287 defer gpa.free(union_field_vals);17312 defer gpa.free(union_field_vals);
1728817313
...@@ -17357,11 +17382,11 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17357,11 +17382,11 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17357 } });17382 } });
17358 };17383 };
1735917384
17360 const decls_val = try sema.typeInfoDecls(block, src, type_info_ty, union_ty.getNamespaceIndex(mod));17385 const decls_val = try sema.typeInfoDecls(block, src, type_info_ty, ty.getNamespaceIndex(mod));
1736117386
17362 const enum_tag_ty_val = try mod.intern(.{ .opt = .{17387 const enum_tag_ty_val = try mod.intern(.{ .opt = .{
17363 .ty = (try mod.optionalType(.type_type)).toIntern(),17388 .ty = (try mod.optionalType(.type_type)).toIntern(),
17364 .val = if (union_ty.unionTagType(mod)) |tag_ty| tag_ty.toIntern() else .none,17389 .val = if (ty.unionTagType(mod)) |tag_ty| tag_ty.toIntern() else .none,
17365 } });17390 } });
1736617391
17367 const container_layout_ty = t: {17392 const container_layout_ty = t: {
...@@ -17429,18 +17454,17 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17429,18 +17454,17 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17429 break :t struct_field_ty_decl.val.toType();17454 break :t struct_field_ty_decl.val.toType();
17430 };17455 };
1743117456
17432 const struct_ty = try sema.resolveTypeFields(ty);
17433 try sema.resolveTypeLayout(ty); // Getting alignment requires type layout17457 try sema.resolveTypeLayout(ty); // Getting alignment requires type layout
17434 const layout = struct_ty.containerLayout(mod);17458 const layout = ty.containerLayout(mod);
1743517459
17436 var struct_field_vals: []InternPool.Index = &.{};17460 var struct_field_vals: []InternPool.Index = &.{};
17437 defer gpa.free(struct_field_vals);17461 defer gpa.free(struct_field_vals);
17438 fv: {17462 fv: {
17439 const struct_type = switch (ip.indexToKey(struct_ty.toIntern())) {17463 const struct_type = switch (ip.indexToKey(ty.toIntern())) {
17440 .anon_struct_type => |tuple| {17464 .anon_struct_type => |tuple| {
17441 struct_field_vals = try gpa.alloc(InternPool.Index, tuple.types.len);17465 struct_field_vals = try gpa.alloc(InternPool.Index, tuple.types.len);
17442 for (struct_field_vals, 0..) |*struct_field_val, i| {17466 for (struct_field_vals, 0..) |*struct_field_val, i| {
17443 const anon_struct_type = ip.indexToKey(struct_ty.toIntern()).anon_struct_type;17467 const anon_struct_type = ip.indexToKey(ty.toIntern()).anon_struct_type;
17444 const field_ty = anon_struct_type.types[i];17468 const field_ty = anon_struct_type.types[i];
17445 const field_val = anon_struct_type.values[i];17469 const field_val = anon_struct_type.values[i];
17446 const name_val = v: {17470 const name_val = v: {
...@@ -17449,7 +17473,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17449,7 +17473,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17449 // TODO: write something like getCoercedInts to avoid needing to dupe17473 // TODO: write something like getCoercedInts to avoid needing to dupe
17450 const bytes = if (tuple.names.len != 0)17474 const bytes = if (tuple.names.len != 0)
17451 // https://github.com/ziglang/zig/issues/1570917475 // https://github.com/ziglang/zig/issues/15709
17452 try sema.arena.dupe(u8, ip.stringToSlice(ip.indexToKey(struct_ty.toIntern()).anon_struct_type.names[i]))17476 try sema.arena.dupe(u8, ip.stringToSlice(ip.indexToKey(ty.toIntern()).anon_struct_type.names[i]))
17453 else17477 else
17454 try std.fmt.allocPrint(sema.arena, "{d}", .{i});17478 try std.fmt.allocPrint(sema.arena, "{d}", .{i});
17455 const new_decl_ty = try mod.arrayType(.{17479 const new_decl_ty = try mod.arrayType(.{
...@@ -17582,12 +17606,12 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17582,12 +17606,12 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17582 } });17606 } });
17583 };17607 };
1758417608
17585 const decls_val = try sema.typeInfoDecls(block, src, type_info_ty, struct_ty.getNamespaceIndex(mod));17609 const decls_val = try sema.typeInfoDecls(block, src, type_info_ty, ty.getNamespaceIndex(mod));
1758617610
17587 const backing_integer_val = try mod.intern(.{ .opt = .{17611 const backing_integer_val = try mod.intern(.{ .opt = .{
17588 .ty = (try mod.optionalType(.type_type)).toIntern(),17612 .ty = (try mod.optionalType(.type_type)).toIntern(),
17589 .val = if (layout == .Packed) val: {17613 .val = if (layout == .Packed) val: {
17590 const struct_obj = mod.typeToStruct(struct_ty).?;17614 const struct_obj = mod.typeToStruct(ty).?;
17591 assert(struct_obj.haveLayout());17615 assert(struct_obj.haveLayout());
17592 assert(struct_obj.backing_int_ty.isInt(mod));17616 assert(struct_obj.backing_int_ty.isInt(mod));
17593 break :val struct_obj.backing_int_ty.toIntern();17617 break :val struct_obj.backing_int_ty.toIntern();
...@@ -17617,7 +17641,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17617,7 +17641,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17617 // decls: []const Declaration,17641 // decls: []const Declaration,
17618 decls_val,17642 decls_val,
17619 // is_tuple: bool,17643 // is_tuple: bool,
17620 Value.makeBool(struct_ty.isTuple(mod)).toIntern(),17644 Value.makeBool(ty.isTuple(mod)).toIntern(),
17621 };17645 };
17622 return Air.internedToRef((try mod.intern(.{ .un = .{17646 return Air.internedToRef((try mod.intern(.{ .un = .{
17623 .ty = type_info_ty.toIntern(),17647 .ty = type_info_ty.toIntern(),
...@@ -17644,8 +17668,8 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17644,8 +17668,8 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17644 break :t type_opaque_ty_decl.val.toType();17668 break :t type_opaque_ty_decl.val.toType();
17645 };17669 };
1764617670
17647 const opaque_ty = try sema.resolveTypeFields(ty);17671 try sema.resolveTypeFields(ty);
17648 const decls_val = try sema.typeInfoDecls(block, src, type_info_ty, opaque_ty.getNamespaceIndex(mod));17672 const decls_val = try sema.typeInfoDecls(block, src, type_info_ty, ty.getNamespaceIndex(mod));
1764917673
17650 const field_values = .{17674 const field_values = .{
17651 // decls: []const Declaration,17675 // decls: []const Declaration,
...@@ -18511,8 +18535,8 @@ fn retWithErrTracing(...@@ -18511,8 +18535,8 @@ fn retWithErrTracing(
18511 else => true,18535 else => true,
18512 };18536 };
18513 const gpa = sema.gpa;18537 const gpa = sema.gpa;
18514 const unresolved_stack_trace_ty = try sema.getBuiltinType("StackTrace");18538 const stack_trace_ty = try sema.getBuiltinType("StackTrace");
18515 const stack_trace_ty = try sema.resolveTypeFields(unresolved_stack_trace_ty);18539 try sema.resolveTypeFields(stack_trace_ty);
18516 const ptr_stack_trace_ty = try mod.singleMutPtrType(stack_trace_ty);18540 const ptr_stack_trace_ty = try mod.singleMutPtrType(stack_trace_ty);
18517 const err_return_trace = try block.addTy(.err_return_trace, ptr_stack_trace_ty);18541 const err_return_trace = try block.addTy(.err_return_trace, ptr_stack_trace_ty);
18518 const return_err_fn = try sema.getBuiltin("returnError");18542 const return_err_fn = try sema.getBuiltin("returnError");
...@@ -18874,14 +18898,14 @@ fn zirStructInitEmpty(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE...@@ -18874,14 +18898,14 @@ fn zirStructInitEmpty(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE
18874fn structInitEmpty(18898fn structInitEmpty(
18875 sema: *Sema,18899 sema: *Sema,
18876 block: *Block,18900 block: *Block,
18877 obj_ty: Type,18901 struct_ty: Type,
18878 dest_src: LazySrcLoc,18902 dest_src: LazySrcLoc,
18879 init_src: LazySrcLoc,18903 init_src: LazySrcLoc,
18880) CompileError!Air.Inst.Ref {18904) CompileError!Air.Inst.Ref {
18881 const mod = sema.mod;18905 const mod = sema.mod;
18882 const gpa = sema.gpa;18906 const gpa = sema.gpa;
18883 // This logic must be synchronized with that in `zirStructInit`.18907 // This logic must be synchronized with that in `zirStructInit`.
18884 const struct_ty = try sema.resolveTypeFields(obj_ty);18908 try sema.resolveTypeFields(struct_ty);
1888518909
18886 // The init values to use for the struct instance.18910 // The init values to use for the struct instance.
18887 const field_inits = try gpa.alloc(Air.Inst.Ref, struct_ty.structFieldCount(mod));18911 const field_inits = try gpa.alloc(Air.Inst.Ref, struct_ty.structFieldCount(mod));
...@@ -19674,8 +19698,7 @@ fn fieldType(...@@ -19674,8 +19698,7 @@ fn fieldType(
19674 const mod = sema.mod;19698 const mod = sema.mod;
19675 var cur_ty = aggregate_ty;19699 var cur_ty = aggregate_ty;
19676 while (true) {19700 while (true) {
19677 const resolved_ty = try sema.resolveTypeFields(cur_ty);19701 try sema.resolveTypeFields(cur_ty);
19678 cur_ty = resolved_ty;
19679 switch (cur_ty.zigTypeTag(mod)) {19702 switch (cur_ty.zigTypeTag(mod)) {
19680 .Struct => switch (mod.intern_pool.indexToKey(cur_ty.toIntern())) {19703 .Struct => switch (mod.intern_pool.indexToKey(cur_ty.toIntern())) {
19681 .anon_struct_type => |anon_struct| {19704 .anon_struct_type => |anon_struct| {
...@@ -19709,7 +19732,7 @@ fn fieldType(...@@ -19709,7 +19732,7 @@ fn fieldType(
19709 else => {},19732 else => {},
19710 }19733 }
19711 return sema.fail(block, ty_src, "expected struct or union; found '{}'", .{19734 return sema.fail(block, ty_src, "expected struct or union; found '{}'", .{
19712 resolved_ty.fmt(sema.mod),19735 cur_ty.fmt(sema.mod),
19713 });19736 });
19714 }19737 }
19715}19738}
...@@ -19721,8 +19744,8 @@ fn zirErrorReturnTrace(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref {...@@ -19721,8 +19744,8 @@ fn zirErrorReturnTrace(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref {
19721fn getErrorReturnTrace(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref {19744fn getErrorReturnTrace(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref {
19722 const mod = sema.mod;19745 const mod = sema.mod;
19723 const ip = &mod.intern_pool;19746 const ip = &mod.intern_pool;
19724 const unresolved_stack_trace_ty = try sema.getBuiltinType("StackTrace");19747 const stack_trace_ty = try sema.getBuiltinType("StackTrace");
19725 const stack_trace_ty = try sema.resolveTypeFields(unresolved_stack_trace_ty);19748 try sema.resolveTypeFields(stack_trace_ty);
19726 const ptr_stack_trace_ty = try mod.singleMutPtrType(stack_trace_ty);19749 const ptr_stack_trace_ty = try mod.singleMutPtrType(stack_trace_ty);
19727 const opt_ptr_stack_trace_ty = try mod.optionalType(ptr_stack_trace_ty.toIntern());19750 const opt_ptr_stack_trace_ty = try mod.optionalType(ptr_stack_trace_ty.toIntern());
1972819751
...@@ -20048,14 +20071,10 @@ fn zirReify(...@@ -20048,14 +20071,10 @@ fn zirReify(
20048 (try alignment_val.getUnsignedIntAdvanced(mod, sema)).?,20071 (try alignment_val.getUnsignedIntAdvanced(mod, sema)).?,
20049 );20072 );
2005020073
20051 const unresolved_elem_ty = child_val.toType();20074 const elem_ty = child_val.toType();
20052 const elem_ty = if (abi_align == .none)20075 if (abi_align != .none) {
20053 unresolved_elem_ty
20054 else t: {
20055 const elem_ty = try sema.resolveTypeFields(unresolved_elem_ty);
20056 try sema.resolveTypeLayout(elem_ty);20076 try sema.resolveTypeLayout(elem_ty);
20057 break :t elem_ty;20077 }
20058 };
2005920078
20060 const ptr_size = mod.toEnum(std.builtin.Type.Pointer.Size, size_val);20079 const ptr_size = mod.toEnum(std.builtin.Type.Pointer.Size, size_val);
2006120080
...@@ -25070,8 +25089,8 @@ fn prepareSimplePanic(sema: *Sema, block: *Block) !void {...@@ -25070,8 +25089,8 @@ fn prepareSimplePanic(sema: *Sema, block: *Block) !void {
25070 }25089 }
2507125090
25072 if (mod.null_stack_trace == .none) {25091 if (mod.null_stack_trace == .none) {
25073 const unresolved_stack_trace_ty = try sema.getBuiltinType("StackTrace");25092 const stack_trace_ty = try sema.getBuiltinType("StackTrace");
25074 const stack_trace_ty = try sema.resolveTypeFields(unresolved_stack_trace_ty);25093 try sema.resolveTypeFields(stack_trace_ty);
25075 const target = mod.getTarget();25094 const target = mod.getTarget();
25076 const ptr_stack_trace_ty = try mod.ptrType(.{25095 const ptr_stack_trace_ty = try mod.ptrType(.{
25077 .child = stack_trace_ty.toIntern(),25096 .child = stack_trace_ty.toIntern(),
...@@ -25523,14 +25542,14 @@ fn fieldVal(...@@ -25523,14 +25542,14 @@ fn fieldVal(
25523 return inst;25542 return inst;
25524 }25543 }
25525 }25544 }
25526 const union_ty = try sema.resolveTypeFields(child_type);25545 try sema.resolveTypeFields(child_type);
25527 if (union_ty.unionTagType(mod)) |enum_ty| {25546 if (child_type.unionTagType(mod)) |enum_ty| {
25528 if (enum_ty.enumFieldIndex(field_name, mod)) |field_index_usize| {25547 if (enum_ty.enumFieldIndex(field_name, mod)) |field_index_usize| {
25529 const field_index = @as(u32, @intCast(field_index_usize));25548 const field_index = @as(u32, @intCast(field_index_usize));
25530 return Air.internedToRef((try mod.enumValueFieldIndex(enum_ty, field_index)).toIntern());25549 return Air.internedToRef((try mod.enumValueFieldIndex(enum_ty, field_index)).toIntern());
25531 }25550 }
25532 }25551 }
25533 return sema.failWithBadMemberAccess(block, union_ty, field_name_src, field_name);25552 return sema.failWithBadMemberAccess(block, child_type, field_name_src, field_name);
25534 },25553 },
25535 .Enum => {25554 .Enum => {
25536 if (child_type.getNamespaceIndex(mod).unwrap()) |namespace| {25555 if (child_type.getNamespaceIndex(mod).unwrap()) |namespace| {
...@@ -25749,8 +25768,8 @@ fn fieldPtr(...@@ -25749,8 +25768,8 @@ fn fieldPtr(
25749 return inst;25768 return inst;
25750 }25769 }
25751 }25770 }
25752 const union_ty = try sema.resolveTypeFields(child_type);25771 try sema.resolveTypeFields(child_type);
25753 if (union_ty.unionTagType(mod)) |enum_ty| {25772 if (child_type.unionTagType(mod)) |enum_ty| {
25754 if (enum_ty.enumFieldIndex(field_name, mod)) |field_index| {25773 if (enum_ty.enumFieldIndex(field_name, mod)) |field_index| {
25755 const field_index_u32 = @as(u32, @intCast(field_index));25774 const field_index_u32 = @as(u32, @intCast(field_index));
25756 var anon_decl = try block.startAnonDecl();25775 var anon_decl = try block.startAnonDecl();
...@@ -25854,35 +25873,35 @@ fn fieldCallBind(...@@ -25854,35 +25873,35 @@ fn fieldCallBind(
25854 find_field: {25873 find_field: {
25855 switch (concrete_ty.zigTypeTag(mod)) {25874 switch (concrete_ty.zigTypeTag(mod)) {
25856 .Struct => {25875 .Struct => {
25857 const struct_ty = try sema.resolveTypeFields(concrete_ty);25876 try sema.resolveTypeFields(concrete_ty);
25858 if (mod.typeToStruct(struct_ty)) |struct_obj| {25877 if (mod.typeToStruct(concrete_ty)) |struct_obj| {
25859 const field_index_usize = struct_obj.fields.getIndex(field_name) orelse25878 const field_index_usize = struct_obj.fields.getIndex(field_name) orelse
25860 break :find_field;25879 break :find_field;
25861 const field_index = @as(u32, @intCast(field_index_usize));25880 const field_index = @as(u32, @intCast(field_index_usize));
25862 const field = struct_obj.fields.values()[field_index];25881 const field = struct_obj.fields.values()[field_index];
2586325882
25864 return sema.finishFieldCallBind(block, src, ptr_ty, field.ty, field_index, object_ptr);25883 return sema.finishFieldCallBind(block, src, ptr_ty, field.ty, field_index, object_ptr);
25865 } else if (struct_ty.isTuple(mod)) {25884 } else if (concrete_ty.isTuple(mod)) {
25866 if (ip.stringEqlSlice(field_name, "len")) {25885 if (ip.stringEqlSlice(field_name, "len")) {
25867 return .{ .direct = try mod.intRef(Type.usize, struct_ty.structFieldCount(mod)) };25886 return .{ .direct = try mod.intRef(Type.usize, concrete_ty.structFieldCount(mod)) };
25868 }25887 }
25869 if (field_name.toUnsigned(ip)) |field_index| {25888 if (field_name.toUnsigned(ip)) |field_index| {
25870 if (field_index >= struct_ty.structFieldCount(mod)) break :find_field;25889 if (field_index >= concrete_ty.structFieldCount(mod)) break :find_field;
25871 return sema.finishFieldCallBind(block, src, ptr_ty, struct_ty.structFieldType(field_index, mod), field_index, object_ptr);25890 return sema.finishFieldCallBind(block, src, ptr_ty, concrete_ty.structFieldType(field_index, mod), field_index, object_ptr);
25872 }25891 }
25873 } else {25892 } else {
25874 const max = struct_ty.structFieldCount(mod);25893 const max = concrete_ty.structFieldCount(mod);
25875 for (0..max) |i_usize| {25894 for (0..max) |i_usize| {
25876 const i = @as(u32, @intCast(i_usize));25895 const i = @as(u32, @intCast(i_usize));
25877 if (field_name == struct_ty.structFieldName(i, mod)) {25896 if (field_name == concrete_ty.structFieldName(i, mod)) {
25878 return sema.finishFieldCallBind(block, src, ptr_ty, struct_ty.structFieldType(i, mod), i, object_ptr);25897 return sema.finishFieldCallBind(block, src, ptr_ty, concrete_ty.structFieldType(i, mod), i, object_ptr);
25879 }25898 }
25880 }25899 }
25881 }25900 }
25882 },25901 },
25883 .Union => {25902 .Union => {
25884 const union_ty = try sema.resolveTypeFields(concrete_ty);25903 try sema.resolveTypeFields(concrete_ty);
25885 const fields = union_ty.unionFields(mod);25904 const fields = concrete_ty.unionFields(mod);
25886 const field_index_usize = fields.getIndex(field_name) orelse break :find_field;25905 const field_index_usize = fields.getIndex(field_name) orelse break :find_field;
25887 const field_index = @as(u32, @intCast(field_index_usize));25906 const field_index = @as(u32, @intCast(field_index_usize));
25888 const field = fields.values()[field_index];25907 const field = fields.values()[field_index];
...@@ -26081,13 +26100,13 @@ fn structFieldPtr(...@@ -26081,13 +26100,13 @@ fn structFieldPtr(
26081 struct_ptr: Air.Inst.Ref,26100 struct_ptr: Air.Inst.Ref,
26082 field_name: InternPool.NullTerminatedString,26101 field_name: InternPool.NullTerminatedString,
26083 field_name_src: LazySrcLoc,26102 field_name_src: LazySrcLoc,
26084 unresolved_struct_ty: Type,26103 struct_ty: Type,
26085 initializing: bool,26104 initializing: bool,
26086) CompileError!Air.Inst.Ref {26105) CompileError!Air.Inst.Ref {
26087 const mod = sema.mod;26106 const mod = sema.mod;
26088 assert(unresolved_struct_ty.zigTypeTag(mod) == .Struct);26107 assert(struct_ty.zigTypeTag(mod) == .Struct);
2608926108
26090 const struct_ty = try sema.resolveTypeFields(unresolved_struct_ty);26109 try sema.resolveTypeFields(struct_ty);
26091 try sema.resolveStructLayout(struct_ty);26110 try sema.resolveStructLayout(struct_ty);
2609226111
26093 if (struct_ty.isTuple(mod)) {26112 if (struct_ty.isTuple(mod)) {
...@@ -26234,12 +26253,12 @@ fn structFieldVal(...@@ -26234,12 +26253,12 @@ fn structFieldVal(
26234 struct_byval: Air.Inst.Ref,26253 struct_byval: Air.Inst.Ref,
26235 field_name: InternPool.NullTerminatedString,26254 field_name: InternPool.NullTerminatedString,
26236 field_name_src: LazySrcLoc,26255 field_name_src: LazySrcLoc,
26237 unresolved_struct_ty: Type,26256 struct_ty: Type,
26238) CompileError!Air.Inst.Ref {26257) CompileError!Air.Inst.Ref {
26239 const mod = sema.mod;26258 const mod = sema.mod;
26240 assert(unresolved_struct_ty.zigTypeTag(mod) == .Struct);26259 assert(struct_ty.zigTypeTag(mod) == .Struct);
2624126260
26242 const struct_ty = try sema.resolveTypeFields(unresolved_struct_ty);26261 try sema.resolveTypeFields(struct_ty);
26243 switch (mod.intern_pool.indexToKey(struct_ty.toIntern())) {26262 switch (mod.intern_pool.indexToKey(struct_ty.toIntern())) {
26244 .struct_type => |struct_type| {26263 .struct_type => |struct_type| {
26245 const struct_obj = mod.structPtrUnwrap(struct_type.index).?;26264 const struct_obj = mod.structPtrUnwrap(struct_type.index).?;
...@@ -26361,17 +26380,17 @@ fn unionFieldPtr(...@@ -26361,17 +26380,17 @@ fn unionFieldPtr(
26361 union_ptr: Air.Inst.Ref,26380 union_ptr: Air.Inst.Ref,
26362 field_name: InternPool.NullTerminatedString,26381 field_name: InternPool.NullTerminatedString,
26363 field_name_src: LazySrcLoc,26382 field_name_src: LazySrcLoc,
26364 unresolved_union_ty: Type,26383 union_ty: Type,
26365 initializing: bool,26384 initializing: bool,
26366) CompileError!Air.Inst.Ref {26385) CompileError!Air.Inst.Ref {
26367 const mod = sema.mod;26386 const mod = sema.mod;
26368 const ip = &mod.intern_pool;26387 const ip = &mod.intern_pool;
2636926388
26370 assert(unresolved_union_ty.zigTypeTag(mod) == .Union);26389 assert(union_ty.zigTypeTag(mod) == .Union);
2637126390
26372 const union_ptr_ty = sema.typeOf(union_ptr);26391 const union_ptr_ty = sema.typeOf(union_ptr);
26373 const union_ptr_info = union_ptr_ty.ptrInfo(mod);26392 const union_ptr_info = union_ptr_ty.ptrInfo(mod);
26374 const union_ty = try sema.resolveTypeFields(unresolved_union_ty);26393 try sema.resolveTypeFields(union_ty);
26375 const union_obj = mod.typeToUnion(union_ty).?;26394 const union_obj = mod.typeToUnion(union_ty).?;
26376 const field_index = try sema.unionFieldIndex(block, union_ty, field_name, field_name_src);26395 const field_index = try sema.unionFieldIndex(block, union_ty, field_name, field_name_src);
26377 const field = union_obj.fields.values()[field_index];26396 const field = union_obj.fields.values()[field_index];
...@@ -26467,13 +26486,13 @@ fn unionFieldVal(...@@ -26467,13 +26486,13 @@ fn unionFieldVal(
26467 union_byval: Air.Inst.Ref,26486 union_byval: Air.Inst.Ref,
26468 field_name: InternPool.NullTerminatedString,26487 field_name: InternPool.NullTerminatedString,
26469 field_name_src: LazySrcLoc,26488 field_name_src: LazySrcLoc,
26470 unresolved_union_ty: Type,26489 union_ty: Type,
26471) CompileError!Air.Inst.Ref {26490) CompileError!Air.Inst.Ref {
26472 const mod = sema.mod;26491 const mod = sema.mod;
26473 const ip = &mod.intern_pool;26492 const ip = &mod.intern_pool;
26474 assert(unresolved_union_ty.zigTypeTag(mod) == .Union);26493 assert(union_ty.zigTypeTag(mod) == .Union);
2647526494
26476 const union_ty = try sema.resolveTypeFields(unresolved_union_ty);26495 try sema.resolveTypeFields(union_ty);
26477 const union_obj = mod.typeToUnion(union_ty).?;26496 const union_obj = mod.typeToUnion(union_ty).?;
26478 const field_index = try sema.unionFieldIndex(block, union_ty, field_name, field_name_src);26497 const field_index = try sema.unionFieldIndex(block, union_ty, field_name, field_name_src);
26479 const field = union_obj.fields.values()[field_index];26498 const field = union_obj.fields.values()[field_index];
...@@ -26733,7 +26752,7 @@ fn tupleFieldPtr(...@@ -26733,7 +26752,7 @@ fn tupleFieldPtr(
26733 const mod = sema.mod;26752 const mod = sema.mod;
26734 const tuple_ptr_ty = sema.typeOf(tuple_ptr);26753 const tuple_ptr_ty = sema.typeOf(tuple_ptr);
26735 const tuple_ty = tuple_ptr_ty.childType(mod);26754 const tuple_ty = tuple_ptr_ty.childType(mod);
26736 _ = try sema.resolveTypeFields(tuple_ty);26755 try sema.resolveTypeFields(tuple_ty);
26737 const field_count = tuple_ty.structFieldCount(mod);26756 const field_count = tuple_ty.structFieldCount(mod);
2673826757
26739 if (field_count == 0) {26758 if (field_count == 0) {
...@@ -26790,7 +26809,8 @@ fn tupleField(...@@ -26790,7 +26809,8 @@ fn tupleField(
26790 field_index: u32,26809 field_index: u32,
26791) CompileError!Air.Inst.Ref {26810) CompileError!Air.Inst.Ref {
26792 const mod = sema.mod;26811 const mod = sema.mod;
26793 const tuple_ty = try sema.resolveTypeFields(sema.typeOf(tuple));26812 const tuple_ty = sema.typeOf(tuple);
26813 try sema.resolveTypeFields(tuple_ty);
26794 const field_count = tuple_ty.structFieldCount(mod);26814 const field_count = tuple_ty.structFieldCount(mod);
2679526815
26796 if (field_count == 0) {26816 if (field_count == 0) {
...@@ -27114,16 +27134,17 @@ const CoerceOpts = struct {...@@ -27114,16 +27134,17 @@ const CoerceOpts = struct {
27114fn coerceExtra(27134fn coerceExtra(
27115 sema: *Sema,27135 sema: *Sema,
27116 block: *Block,27136 block: *Block,
27117 dest_ty_unresolved: Type,27137 dest_ty: Type,
27118 inst: Air.Inst.Ref,27138 inst: Air.Inst.Ref,
27119 inst_src: LazySrcLoc,27139 inst_src: LazySrcLoc,
27120 opts: CoerceOpts,27140 opts: CoerceOpts,
27121) CoersionError!Air.Inst.Ref {27141) CoersionError!Air.Inst.Ref {
27122 if (dest_ty_unresolved.isGenericPoison()) return inst;27142 if (dest_ty.isGenericPoison()) return inst;
27123 const mod = sema.mod;27143 const mod = sema.mod;
27124 const dest_ty_src = inst_src; // TODO better source location27144 const dest_ty_src = inst_src; // TODO better source location
27125 const dest_ty = try sema.resolveTypeFields(dest_ty_unresolved);27145 try sema.resolveTypeFields(dest_ty);
27126 const inst_ty = try sema.resolveTypeFields(sema.typeOf(inst));27146 const inst_ty = sema.typeOf(inst);
27147 try sema.resolveTypeFields(inst_ty);
27127 const target = mod.getTarget();27148 const target = mod.getTarget();
27128 // If the types are the same, we can return the operand.27149 // If the types are the same, we can return the operand.
27129 if (dest_ty.eql(inst_ty, mod))27150 if (dest_ty.eql(inst_ty, mod))
...@@ -29831,16 +29852,15 @@ fn beginComptimePtrLoad(...@@ -29831,16 +29852,15 @@ fn beginComptimePtrLoad(
29831fn bitCast(29852fn bitCast(
29832 sema: *Sema,29853 sema: *Sema,
29833 block: *Block,29854 block: *Block,
29834 dest_ty_unresolved: Type,29855 dest_ty: Type,
29835 inst: Air.Inst.Ref,29856 inst: Air.Inst.Ref,
29836 inst_src: LazySrcLoc,29857 inst_src: LazySrcLoc,
29837 operand_src: ?LazySrcLoc,29858 operand_src: ?LazySrcLoc,
29838) CompileError!Air.Inst.Ref {29859) CompileError!Air.Inst.Ref {
29839 const mod = sema.mod;29860 const mod = sema.mod;
29840 const dest_ty = try sema.resolveTypeFields(dest_ty_unresolved);
29841 try sema.resolveTypeLayout(dest_ty);29861 try sema.resolveTypeLayout(dest_ty);
2984229862
29843 const old_ty = try sema.resolveTypeFields(sema.typeOf(inst));29863 const old_ty = sema.typeOf(inst);
29844 try sema.resolveTypeLayout(old_ty);29864 try sema.resolveTypeLayout(old_ty);
2984529865
29846 const dest_bits = dest_ty.bitSize(mod);29866 const dest_bits = dest_ty.bitSize(mod);
...@@ -30043,8 +30063,8 @@ fn coerceEnumToUnion(...@@ -30043,8 +30063,8 @@ fn coerceEnumToUnion(
3004330063
30044 const union_obj = mod.typeToUnion(union_ty).?;30064 const union_obj = mod.typeToUnion(union_ty).?;
30045 const field = union_obj.fields.values()[field_index];30065 const field = union_obj.fields.values()[field_index];
30046 const field_ty = try sema.resolveTypeFields(field.ty);30066 try sema.resolveTypeFields(field.ty);
30047 if (field_ty.zigTypeTag(mod) == .NoReturn) {30067 if (field.ty.zigTypeTag(mod) == .NoReturn) {
30048 const msg = msg: {30068 const msg = msg: {
30049 const msg = try sema.errMsg(block, inst_src, "cannot initialize 'noreturn' field of union", .{});30069 const msg = try sema.errMsg(block, inst_src, "cannot initialize 'noreturn' field of union", .{});
30050 errdefer msg.destroy(sema.gpa);30070 errdefer msg.destroy(sema.gpa);
...@@ -30058,12 +30078,12 @@ fn coerceEnumToUnion(...@@ -30058,12 +30078,12 @@ fn coerceEnumToUnion(
30058 };30078 };
30059 return sema.failWithOwnedErrorMsg(msg);30079 return sema.failWithOwnedErrorMsg(msg);
30060 }30080 }
30061 const opv = (try sema.typeHasOnePossibleValue(field_ty)) orelse {30081 const opv = (try sema.typeHasOnePossibleValue(field.ty)) orelse {
30062 const msg = msg: {30082 const msg = msg: {
30063 const field_name = union_obj.fields.keys()[field_index];30083 const field_name = union_obj.fields.keys()[field_index];
30064 const msg = try sema.errMsg(block, inst_src, "coercion from enum '{}' to union '{}' must initialize '{}' field '{}'", .{30084 const msg = try sema.errMsg(block, inst_src, "coercion from enum '{}' to union '{}' must initialize '{}' field '{}'", .{
30065 inst_ty.fmt(sema.mod), union_ty.fmt(sema.mod),30085 inst_ty.fmt(sema.mod), union_ty.fmt(sema.mod),
30066 field_ty.fmt(sema.mod), field_name.fmt(ip),30086 field.ty.fmt(sema.mod), field_name.fmt(ip),
30067 });30087 });
30068 errdefer msg.destroy(sema.gpa);30088 errdefer msg.destroy(sema.gpa);
3006930089
...@@ -30427,13 +30447,13 @@ fn coerceTupleToArrayPtrs(...@@ -30427,13 +30447,13 @@ fn coerceTupleToArrayPtrs(
30427fn coerceTupleToStruct(30447fn coerceTupleToStruct(
30428 sema: *Sema,30448 sema: *Sema,
30429 block: *Block,30449 block: *Block,
30430 dest_ty: Type,30450 struct_ty: Type,
30431 inst: Air.Inst.Ref,30451 inst: Air.Inst.Ref,
30432 inst_src: LazySrcLoc,30452 inst_src: LazySrcLoc,
30433) !Air.Inst.Ref {30453) !Air.Inst.Ref {
30434 const mod = sema.mod;30454 const mod = sema.mod;
30435 const ip = &mod.intern_pool;30455 const ip = &mod.intern_pool;
30436 const struct_ty = try sema.resolveTypeFields(dest_ty);30456 try sema.resolveTypeFields(struct_ty);
3043730457
30438 if (struct_ty.isTupleOrAnonStruct(mod)) {30458 if (struct_ty.isTupleOrAnonStruct(mod)) {
30439 return sema.coerceTupleToTuple(block, struct_ty, inst, inst_src);30459 return sema.coerceTupleToTuple(block, struct_ty, inst, inst_src);
...@@ -33729,6 +33749,10 @@ fn resolveLazyValue(sema: *Sema, val: Value) CompileError!Value {...@@ -33729,6 +33749,10 @@ fn resolveLazyValue(sema: *Sema, val: Value) CompileError!Value {
3372933749
33730pub fn resolveTypeLayout(sema: *Sema, ty: Type) CompileError!void {33750pub fn resolveTypeLayout(sema: *Sema, ty: Type) CompileError!void {
33731 const mod = sema.mod;33751 const mod = sema.mod;
33752 switch (mod.intern_pool.indexToKey(ty.toIntern())) {
33753 .simple_type => |simple_type| return sema.resolveSimpleType(simple_type),
33754 else => {},
33755 }
33732 switch (ty.zigTypeTag(mod)) {33756 switch (ty.zigTypeTag(mod)) {
33733 .Struct => return sema.resolveStructLayout(ty),33757 .Struct => return sema.resolveStructLayout(ty),
33734 .Union => return sema.resolveUnionLayout(ty),33758 .Union => return sema.resolveUnionLayout(ty),
...@@ -33769,8 +33793,8 @@ pub fn resolveTypeLayout(sema: *Sema, ty: Type) CompileError!void {...@@ -33769,8 +33793,8 @@ pub fn resolveTypeLayout(sema: *Sema, ty: Type) CompileError!void {
3376933793
33770fn resolveStructLayout(sema: *Sema, ty: Type) CompileError!void {33794fn resolveStructLayout(sema: *Sema, ty: Type) CompileError!void {
33771 const mod = sema.mod;33795 const mod = sema.mod;
33772 const resolved_ty = try sema.resolveTypeFields(ty);33796 try sema.resolveTypeFields(ty);
33773 if (mod.typeToStruct(resolved_ty)) |struct_obj| {33797 if (mod.typeToStruct(ty)) |struct_obj| {
33774 switch (struct_obj.status) {33798 switch (struct_obj.status) {
33775 .none, .have_field_types => {},33799 .none, .have_field_types => {},
33776 .field_types_wip, .layout_wip => {33800 .field_types_wip, .layout_wip => {
...@@ -33806,9 +33830,9 @@ fn resolveStructLayout(sema: *Sema, ty: Type) CompileError!void {...@@ -33806,9 +33830,9 @@ fn resolveStructLayout(sema: *Sema, ty: Type) CompileError!void {
33806 }33830 }
3380733831
33808 struct_obj.status = .have_layout;33832 struct_obj.status = .have_layout;
33809 _ = try sema.resolveTypeRequiresComptime(resolved_ty);33833 _ = try sema.resolveTypeRequiresComptime(ty);
3381033834
33811 if (struct_obj.assumed_runtime_bits and !(try sema.typeHasRuntimeBits(resolved_ty))) {33835 if (struct_obj.assumed_runtime_bits and !(try sema.typeHasRuntimeBits(ty))) {
33812 const msg = try Module.ErrorMsg.create(33836 const msg = try Module.ErrorMsg.create(
33813 sema.gpa,33837 sema.gpa,
33814 struct_obj.srcLoc(mod),33838 struct_obj.srcLoc(mod),
...@@ -34020,8 +34044,8 @@ fn checkMemOperand(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) !void...@@ -34020,8 +34044,8 @@ fn checkMemOperand(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) !void
3402034044
34021fn resolveUnionLayout(sema: *Sema, ty: Type) CompileError!void {34045fn resolveUnionLayout(sema: *Sema, ty: Type) CompileError!void {
34022 const mod = sema.mod;34046 const mod = sema.mod;
34023 const resolved_ty = try sema.resolveTypeFields(ty);34047 try sema.resolveTypeFields(ty);
34024 const union_obj = mod.typeToUnion(resolved_ty).?;34048 const union_obj = mod.typeToUnion(ty).?;
34025 switch (union_obj.status) {34049 switch (union_obj.status) {
34026 .none, .have_field_types => {},34050 .none, .have_field_types => {},
34027 .field_types_wip, .layout_wip => {34051 .field_types_wip, .layout_wip => {
...@@ -34052,9 +34076,9 @@ fn resolveUnionLayout(sema: *Sema, ty: Type) CompileError!void {...@@ -34052,9 +34076,9 @@ fn resolveUnionLayout(sema: *Sema, ty: Type) CompileError!void {
34052 };34076 };
34053 }34077 }
34054 union_obj.status = .have_layout;34078 union_obj.status = .have_layout;
34055 _ = try sema.resolveTypeRequiresComptime(resolved_ty);34079 _ = try sema.resolveTypeRequiresComptime(ty);
3405634080
34057 if (union_obj.assumed_runtime_bits and !(try sema.typeHasRuntimeBits(resolved_ty))) {34081 if (union_obj.assumed_runtime_bits and !(try sema.typeHasRuntimeBits(ty))) {
34058 const msg = try Module.ErrorMsg.create(34082 const msg = try Module.ErrorMsg.create(
34059 sema.gpa,34083 sema.gpa,
34060 union_obj.srcLoc(sema.mod),34084 union_obj.srcLoc(sema.mod),
...@@ -34228,8 +34252,7 @@ pub fn resolveTypeFully(sema: *Sema, ty: Type) CompileError!void {...@@ -34228,8 +34252,7 @@ pub fn resolveTypeFully(sema: *Sema, ty: Type) CompileError!void {
34228 const mod = sema.mod;34252 const mod = sema.mod;
34229 switch (ty.zigTypeTag(mod)) {34253 switch (ty.zigTypeTag(mod)) {
34230 .Pointer => {34254 .Pointer => {
34231 const child_ty = try sema.resolveTypeFields(ty.childType(mod));34255 return sema.resolveTypeFully(ty.childType(mod));
34232 return sema.resolveTypeFully(child_ty);
34233 },34256 },
34234 .Struct => switch (mod.intern_pool.indexToKey(ty.toIntern())) {34257 .Struct => switch (mod.intern_pool.indexToKey(ty.toIntern())) {
34235 .struct_type => return sema.resolveStructFully(ty),34258 .struct_type => return sema.resolveStructFully(ty),
...@@ -34238,6 +34261,7 @@ pub fn resolveTypeFully(sema: *Sema, ty: Type) CompileError!void {...@@ -34238,6 +34261,7 @@ pub fn resolveTypeFully(sema: *Sema, ty: Type) CompileError!void {
34238 try sema.resolveTypeFully(field_ty.toType());34261 try sema.resolveTypeFully(field_ty.toType());
34239 }34262 }
34240 },34263 },
34264 .simple_type => |simple_type| try sema.resolveSimpleType(simple_type),
34241 else => {},34265 else => {},
34242 },34266 },
34243 .Union => return sema.resolveUnionFully(ty),34267 .Union => return sema.resolveUnionFully(ty),
...@@ -34268,8 +34292,8 @@ fn resolveStructFully(sema: *Sema, ty: Type) CompileError!void {...@@ -34268,8 +34292,8 @@ fn resolveStructFully(sema: *Sema, ty: Type) CompileError!void {
34268 try sema.resolveStructLayout(ty);34292 try sema.resolveStructLayout(ty);
3426934293
34270 const mod = sema.mod;34294 const mod = sema.mod;
34271 const resolved_ty = try sema.resolveTypeFields(ty);34295 try sema.resolveTypeFields(ty);
34272 const struct_obj = mod.typeToStruct(resolved_ty).?;34296 const struct_obj = mod.typeToStruct(ty).?;
3427334297
34274 switch (struct_obj.status) {34298 switch (struct_obj.status) {
34275 .none, .have_field_types, .field_types_wip, .layout_wip, .have_layout => {},34299 .none, .have_field_types, .field_types_wip, .layout_wip, .have_layout => {},
...@@ -34298,8 +34322,8 @@ fn resolveUnionFully(sema: *Sema, ty: Type) CompileError!void {...@@ -34298,8 +34322,8 @@ fn resolveUnionFully(sema: *Sema, ty: Type) CompileError!void {
34298 try sema.resolveUnionLayout(ty);34322 try sema.resolveUnionLayout(ty);
3429934323
34300 const mod = sema.mod;34324 const mod = sema.mod;
34301 const resolved_ty = try sema.resolveTypeFields(ty);34325 try sema.resolveTypeFields(ty);
34302 const union_obj = mod.typeToUnion(resolved_ty).?;34326 const union_obj = mod.typeToUnion(ty).?;
34303 switch (union_obj.status) {34327 switch (union_obj.status) {
34304 .none, .have_field_types, .field_types_wip, .layout_wip, .have_layout => {},34328 .none, .have_field_types, .field_types_wip, .layout_wip, .have_layout => {},
34305 .fully_resolved_wip, .fully_resolved => return,34329 .fully_resolved_wip, .fully_resolved => return,
...@@ -34323,7 +34347,7 @@ fn resolveUnionFully(sema: *Sema, ty: Type) CompileError!void {...@@ -34323,7 +34347,7 @@ fn resolveUnionFully(sema: *Sema, ty: Type) CompileError!void {
34323 _ = try sema.typeRequiresComptime(ty);34347 _ = try sema.typeRequiresComptime(ty);
34324}34348}
3432534349
34326pub fn resolveTypeFields(sema: *Sema, ty: Type) CompileError!Type {34350pub fn resolveTypeFields(sema: *Sema, ty: Type) CompileError!void {
34327 const mod = sema.mod;34351 const mod = sema.mod;
3432834352
34329 switch (ty.toIntern()) {34353 switch (ty.toIntern()) {
...@@ -34386,7 +34410,7 @@ pub fn resolveTypeFields(sema: *Sema, ty: Type) CompileError!Type {...@@ -34386,7 +34410,7 @@ pub fn resolveTypeFields(sema: *Sema, ty: Type) CompileError!Type {
34386 .anyerror_void_error_union_type,34410 .anyerror_void_error_union_type,
34387 .generic_poison_type,34411 .generic_poison_type,
34388 .empty_struct_type,34412 .empty_struct_type,
34389 => return ty,34413 => {},
3439034414
34391 .undef => unreachable,34415 .undef => unreachable,
34392 .zero => unreachable,34416 .zero => unreachable,
...@@ -34407,42 +34431,52 @@ pub fn resolveTypeFields(sema: *Sema, ty: Type) CompileError!Type {...@@ -34407,42 +34431,52 @@ pub fn resolveTypeFields(sema: *Sema, ty: Type) CompileError!Type {
34407 .empty_struct => unreachable,34431 .empty_struct => unreachable,
34408 .generic_poison => unreachable,34432 .generic_poison => unreachable,
3440934433
34410 .type_info_type => return sema.getBuiltinType("Type"),34434 else => switch (mod.intern_pool.items.items(.tag)[@intFromEnum(ty.toIntern())]) {
34411 .extern_options_type => return sema.getBuiltinType("ExternOptions"),
34412 .export_options_type => return sema.getBuiltinType("ExportOptions"),
34413 .atomic_order_type => return sema.getBuiltinType("AtomicOrder"),
34414 .atomic_rmw_op_type => return sema.getBuiltinType("AtomicRmwOp"),
34415 .calling_convention_type => return sema.getBuiltinType("CallingConvention"),
34416 .address_space_type => return sema.getBuiltinType("AddressSpace"),
34417 .float_mode_type => return sema.getBuiltinType("FloatMode"),
34418 .reduce_op_type => return sema.getBuiltinType("ReduceOp"),
34419 .call_modifier_type => return sema.getBuiltinType("CallModifier"),
34420 .prefetch_options_type => return sema.getBuiltinType("PrefetchOptions"),
34421
34422 _ => switch (mod.intern_pool.items.items(.tag)[@intFromEnum(ty.toIntern())]) {
34423 .type_struct,34435 .type_struct,
34424 .type_struct_ns,34436 .type_struct_ns,
34425 .type_union_tagged,34437 .type_union_tagged,
34426 .type_union_untagged,34438 .type_union_untagged,
34427 .type_union_safety,34439 .type_union_safety,
34440 .simple_type,
34428 => switch (mod.intern_pool.indexToKey(ty.toIntern())) {34441 => switch (mod.intern_pool.indexToKey(ty.toIntern())) {
34429 .struct_type => |struct_type| {34442 .struct_type => |struct_type| {
34430 const struct_obj = mod.structPtrUnwrap(struct_type.index) orelse return ty;34443 const struct_obj = mod.structPtrUnwrap(struct_type.index) orelse return;
34431 try sema.resolveTypeFieldsStruct(ty, struct_obj);34444 try sema.resolveTypeFieldsStruct(ty, struct_obj);
34432 return ty;
34433 },34445 },
34434 .union_type => |union_type| {34446 .union_type => |union_type| {
34435 const union_obj = mod.unionPtr(union_type.index);34447 const union_obj = mod.unionPtr(union_type.index);
34436 try sema.resolveTypeFieldsUnion(ty, union_obj);34448 try sema.resolveTypeFieldsUnion(ty, union_obj);
34437 return ty;
34438 },34449 },
34450 .simple_type => |simple_type| try sema.resolveSimpleType(simple_type),
34439 else => unreachable,34451 else => unreachable,
34440 },34452 },
34441 else => return ty,34453 else => {},
34442 },34454 },
34443 }34455 }
34444}34456}
3444534457
34458/// Fully resolves a simple type. This is usually a nop, but for builtin types with
34459/// special InternPool indices (such as std.builtin.Type) it will analyze and fully
34460/// resolve the container type.
34461fn resolveSimpleType(sema: *Sema, simple_type: InternPool.SimpleType) CompileError!void {
34462 const builtin_type_name: []const u8 = switch (simple_type) {
34463 .atomic_order => "AtomicOrder",
34464 .atomic_rmw_op => "AtomicRmwOp",
34465 .calling_convention => "CallingConvention",
34466 .address_space => "AddressSpace",
34467 .float_mode => "FloatMode",
34468 .reduce_op => "ReduceOp",
34469 .call_modifier => "CallModifer",
34470 .prefetch_options => "PrefetchOptions",
34471 .export_options => "ExportOptions",
34472 .extern_options => "ExternOptions",
34473 .type_info => "Type",
34474 else => return,
34475 };
34476 // This will fully resolve the type.
34477 _ = try sema.getBuiltinType(builtin_type_name);
34478}
34479
34446fn resolveTypeFieldsStruct(34480fn resolveTypeFieldsStruct(
34447 sema: *Sema,34481 sema: *Sema,
34448 ty: Type,34482 ty: Type,
...@@ -35785,7 +35819,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {...@@ -35785,7 +35819,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
35785 },35819 },
3578635820
35787 .struct_type => |struct_type| {35821 .struct_type => |struct_type| {
35788 const resolved_ty = try sema.resolveTypeFields(ty);35822 try sema.resolveTypeFields(ty);
35789 if (mod.structPtrUnwrap(struct_type.index)) |s| {35823 if (mod.structPtrUnwrap(struct_type.index)) |s| {
35790 const field_vals = try sema.arena.alloc(InternPool.Index, s.fields.count());35824 const field_vals = try sema.arena.alloc(InternPool.Index, s.fields.count());
35791 for (field_vals, s.fields.values(), 0..) |*field_val, field, i| {35825 for (field_vals, s.fields.values(), 0..) |*field_val, field, i| {
...@@ -35793,14 +35827,14 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {...@@ -35793,14 +35827,14 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
35793 field_val.* = field.default_val;35827 field_val.* = field.default_val;
35794 continue;35828 continue;
35795 }35829 }
35796 if (field.ty.eql(resolved_ty, sema.mod)) {35830 if (field.ty.eql(ty, sema.mod)) {
35797 const msg = try Module.ErrorMsg.create(35831 const msg = try Module.ErrorMsg.create(
35798 sema.gpa,35832 sema.gpa,
35799 s.srcLoc(sema.mod),35833 s.srcLoc(sema.mod),
35800 "struct '{}' depends on itself",35834 "struct '{}' depends on itself",
35801 .{ty.fmt(sema.mod)},35835 .{ty.fmt(sema.mod)},
35802 );35836 );
35803 try sema.addFieldErrNote(resolved_ty, i, msg, "while checking this field", .{});35837 try sema.addFieldErrNote(ty, i, msg, "while checking this field", .{});
35804 return sema.failWithOwnedErrorMsg(msg);35838 return sema.failWithOwnedErrorMsg(msg);
35805 }35839 }
35806 if (try sema.typeHasOnePossibleValue(field.ty)) |field_opv| {35840 if (try sema.typeHasOnePossibleValue(field.ty)) |field_opv| {
...@@ -35838,7 +35872,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {...@@ -35838,7 +35872,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
35838 },35872 },
3583935873
35840 .union_type => |union_type| {35874 .union_type => |union_type| {
35841 const resolved_ty = try sema.resolveTypeFields(ty);35875 try sema.resolveTypeFields(ty);
35842 const union_obj = mod.unionPtr(union_type.index);35876 const union_obj = mod.unionPtr(union_type.index);
35843 const tag_val = (try sema.typeHasOnePossibleValue(union_obj.tag_ty)) orelse35877 const tag_val = (try sema.typeHasOnePossibleValue(union_obj.tag_ty)) orelse
35844 return null;35878 return null;
...@@ -35848,20 +35882,20 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {...@@ -35848,20 +35882,20 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
35848 return only.toValue();35882 return only.toValue();
35849 }35883 }
35850 const only_field = fields[0];35884 const only_field = fields[0];
35851 if (only_field.ty.eql(resolved_ty, sema.mod)) {35885 if (only_field.ty.eql(ty, sema.mod)) {
35852 const msg = try Module.ErrorMsg.create(35886 const msg = try Module.ErrorMsg.create(
35853 sema.gpa,35887 sema.gpa,
35854 union_obj.srcLoc(sema.mod),35888 union_obj.srcLoc(sema.mod),
35855 "union '{}' depends on itself",35889 "union '{}' depends on itself",
35856 .{ty.fmt(sema.mod)},35890 .{ty.fmt(sema.mod)},
35857 );35891 );
35858 try sema.addFieldErrNote(resolved_ty, 0, msg, "while checking this field", .{});35892 try sema.addFieldErrNote(ty, 0, msg, "while checking this field", .{});
35859 return sema.failWithOwnedErrorMsg(msg);35893 return sema.failWithOwnedErrorMsg(msg);
35860 }35894 }
35861 const val_val = (try sema.typeHasOnePossibleValue(only_field.ty)) orelse35895 const val_val = (try sema.typeHasOnePossibleValue(only_field.ty)) orelse
35862 return null;35896 return null;
35863 const only = try mod.intern(.{ .un = .{35897 const only = try mod.intern(.{ .un = .{
35864 .ty = resolved_ty.toIntern(),35898 .ty = ty.toIntern(),
35865 .tag = tag_val.toIntern(),35899 .tag = tag_val.toIntern(),
35866 .val = val_val.toIntern(),35900 .val = val_val.toIntern(),
35867 } });35901 } });
...@@ -36431,12 +36465,12 @@ pub fn fnHasRuntimeBits(sema: *Sema, ty: Type) CompileError!bool {...@@ -36431,12 +36465,12 @@ pub fn fnHasRuntimeBits(sema: *Sema, ty: Type) CompileError!bool {
36431fn unionFieldIndex(36465fn unionFieldIndex(
36432 sema: *Sema,36466 sema: *Sema,
36433 block: *Block,36467 block: *Block,
36434 unresolved_union_ty: Type,36468 union_ty: Type,
36435 field_name: InternPool.NullTerminatedString,36469 field_name: InternPool.NullTerminatedString,
36436 field_src: LazySrcLoc,36470 field_src: LazySrcLoc,
36437) !u32 {36471) !u32 {
36438 const mod = sema.mod;36472 const mod = sema.mod;
36439 const union_ty = try sema.resolveTypeFields(unresolved_union_ty);36473 try sema.resolveTypeFields(union_ty);
36440 const union_obj = mod.typeToUnion(union_ty).?;36474 const union_obj = mod.typeToUnion(union_ty).?;
36441 const field_index_usize = union_obj.fields.getIndex(field_name) orelse36475 const field_index_usize = union_obj.fields.getIndex(field_name) orelse
36442 return sema.failWithBadUnionFieldAccess(block, union_obj, field_src, field_name);36476 return sema.failWithBadUnionFieldAccess(block, union_obj, field_src, field_name);
...@@ -36446,12 +36480,12 @@ fn unionFieldIndex(...@@ -36446,12 +36480,12 @@ fn unionFieldIndex(
36446fn structFieldIndex(36480fn structFieldIndex(
36447 sema: *Sema,36481 sema: *Sema,
36448 block: *Block,36482 block: *Block,
36449 unresolved_struct_ty: Type,36483 struct_ty: Type,
36450 field_name: InternPool.NullTerminatedString,36484 field_name: InternPool.NullTerminatedString,
36451 field_src: LazySrcLoc,36485 field_src: LazySrcLoc,
36452) !u32 {36486) !u32 {
36453 const mod = sema.mod;36487 const mod = sema.mod;
36454 const struct_ty = try sema.resolveTypeFields(unresolved_struct_ty);36488 try sema.resolveTypeFields(struct_ty);
36455 if (struct_ty.isAnonStruct(mod)) {36489 if (struct_ty.isAnonStruct(mod)) {
36456 return sema.anonStructFieldIndex(block, struct_ty, field_name, field_src);36490 return sema.anonStructFieldIndex(block, struct_ty, field_name, field_src);
36457 } else {36491 } else {
src/codegen/llvm.zig-11
...@@ -3134,17 +3134,6 @@ pub const Object = struct {...@@ -3134,17 +3134,6 @@ pub const Object = struct {
3134 .null_type,3134 .null_type,
3135 .undefined_type,3135 .undefined_type,
3136 .enum_literal_type,3136 .enum_literal_type,
3137 .atomic_order_type,
3138 .atomic_rmw_op_type,
3139 .calling_convention_type,
3140 .address_space_type,
3141 .float_mode_type,
3142 .reduce_op_type,
3143 .call_modifier_type,
3144 .prefetch_options_type,
3145 .export_options_type,
3146 .extern_options_type,
3147 .type_info_type,
3148 => unreachable,3137 => unreachable,
3149 .manyptr_u8_type,3138 .manyptr_u8_type,
3150 .manyptr_const_u8_type,3139 .manyptr_const_u8_type,
test/cases/compile_errors/wrong_types_given_to_export.zig+1-1
...@@ -7,5 +7,5 @@ comptime {...@@ -7,5 +7,5 @@ comptime {
7// backend=stage27// backend=stage2
8// target=native8// target=native
9//9//
10// :3:21: error: expected type 'builtin.GlobalLinkage', found 'u32'10// :3:51: error: expected type 'builtin.GlobalLinkage', found 'u32'
11// :?:?: note: enum declared here11// :?:?: note: enum declared here