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(
83848384 local_val.used = ident_token;
83858385 _ = try gz.addPlNode(.export_value, node, Zir.Inst.ExportValue{
83868386 .operand = local_val.inst,
8387 // TODO: the result location here should be `.{ .coerced_ty = .export_options_type }`, but
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]),
8387 .options = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = .export_options_type } }, params[1]),
83918388 });
83928389 return rvalue(gz, ri, .void_value, node);
83938390 }
......@@ -8402,10 +8399,7 @@ fn builtinCall(
84028399 const loaded = try gz.addUnNode(.load, local_ptr.ptr, node);
84038400 _ = try gz.addPlNode(.export_value, node, Zir.Inst.ExportValue{
84048401 .operand = loaded,
8405 // TODO: the result location here should be `.{ .coerced_ty = .export_options_type }`, but
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]),
8402 .options = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = .export_options_type } }, params[1]),
84098403 });
84108404 return rvalue(gz, ri, .void_value, node);
84118405 }
......@@ -8439,10 +8433,7 @@ fn builtinCall(
84398433 },
84408434 else => return astgen.failNode(params[0], "symbol to export must identify a declaration", .{}),
84418435 }
8442 // TODO: the result location here should be `.{ .coerced_ty = .export_options_type }`, but
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]);
8436 const options = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = .export_options_type } }, params[1]);
84468437 _ = try gz.addPlNode(.@"export", node, Zir.Inst.Export{
84478438 .namespace = namespace,
84488439 .decl_name = decl_name,
......@@ -8452,10 +8443,7 @@ fn builtinCall(
84528443 },
84538444 .@"extern" => {
84548445 const type_inst = try typeExpr(gz, scope, params[0]);
8455 // TODO: the result location here should be `.{ .coerced_ty = .extern_options_type }`, but
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]);
8446 const options = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = .extern_options_type } }, params[1]);
84598447 const result = try gz.addExtendedPayload(.builtin_extern, Zir.Inst.BinNode{
84608448 .node = gz.nodeIndexToRelative(node),
84618449 .lhs = type_inst,
......@@ -8559,10 +8547,7 @@ fn builtinCall(
85598547 // zig fmt: on
85608548
85618549 .Type => {
8562 // TODO: the result location here should be `.{ .coerced_ty = .type_info_type }`, but
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]);
8550 const operand = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .type_info_type } }, params[0]);
85668551
85678552 const gpa = gz.astgen.gpa;
85688553
......@@ -8834,10 +8819,7 @@ fn builtinCall(
88348819 },
88358820 .prefetch => {
88368821 const ptr = try expr(gz, scope, .{ .rl = .none }, params[0]);
8837 // TODO: the result location here should be `.{ .coerced_ty = .preftech_options_type }`, but
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]);
8822 const options = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = .prefetch_options_type } }, params[1]);
88418823 _ = try gz.addExtendedPayload(.prefetch, Zir.Inst.BinNode{
88428824 .node = gz.nodeIndexToRelative(node),
88438825 .lhs = ptr,
src/InternPool.zig+30
......@@ -7176,3 +7176,33 @@ fn unwrapCoercedFunc(ip: *const InternPool, i: Index) Index {
71767176 else => unreachable,
71777177 };
71787178}
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 {
770770
771771 /// Gets the namespace that this Decl creates by being a struct, union,
772772 /// enum, or opaque.
773 /// Only returns it if the Decl is the owner.
774 pub fn getOwnedInnerNamespaceIndex(decl: Decl, mod: *Module) Namespace.OptionalIndex {
775 if (!decl.owns_tv) return .none;
773 pub fn getInnerNamespaceIndex(decl: Decl, mod: *Module) Namespace.OptionalIndex {
774 if (!decl.has_tv) return .none;
776775 return switch (decl.val.ip_index) {
777776 .empty_struct_type => .none,
778777 .none => .none,
......@@ -786,11 +785,22 @@ pub const Decl = struct {
786785 };
787786 }
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.
790795 pub fn getOwnedInnerNamespace(decl: Decl, mod: *Module) ?*Namespace {
791796 return mod.namespacePtrUnwrap(decl.getOwnedInnerNamespaceIndex(mod));
792797 }
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
794804 pub fn dump(decl: *Decl) void {
795805 const loc = std.zig.findLineColumn(decl.scope.source.bytes, decl.src);
796806 std.debug.print("{s}:{d}:{d} name={d} status={s}", .{
......@@ -4283,6 +4293,40 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
42834293 const zir = decl.getFileScope(mod).zir;
42844294 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
42864330 decl.analysis = .in_progress;
42874331
42884332 var analysis_arena = std.heap.ArenaAllocator.init(gpa);
......@@ -4304,6 +4348,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
43044348 .fn_ret_ty_ies = null,
43054349 .owner_func_index = .none,
43064350 .comptime_mutable_decls = &comptime_mutable_decls,
4351 .builtin_type_target_index = builtin_type_target_index,
43074352 };
43084353 defer sema.deinit();
43094354
......@@ -4340,6 +4385,8 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
43404385 const extra = zir.extraData(Zir.Inst.Block, inst_data.payload_index);
43414386 const body = zir.extra[extra.end..][0..extra.data.body_len];
43424387 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;
43434390 try wip_captures.finalize();
43444391 for (comptime_mutable_decls.items) |ct_decl_index| {
43454392 const ct_decl = mod.declPtr(ct_decl_index);
src/Sema.zig+205-171
......@@ -107,6 +107,10 @@ comptime_mutable_decls: *std.ArrayList(Decl.Index),
107107/// one encountered, the conflicting source location can be shown.
108108prev_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
110114const std = @import("std");
111115const math = std.math;
112116const mem = std.mem;
......@@ -1956,8 +1960,8 @@ pub fn setupErrorReturnTrace(sema: *Sema, block: *Block, last_arg_index: usize)
19561960 const addrs_ptr = try err_trace_block.addTy(.alloc, try mod.singleMutPtrType(addr_arr_ty));
19571961
19581962 // var st: StackTrace = undefined;
1959 const unresolved_stack_trace_ty = try sema.getBuiltinType("StackTrace");
1960 const stack_trace_ty = try sema.resolveTypeFields(unresolved_stack_trace_ty);
1963 const stack_trace_ty = try sema.getBuiltinType("StackTrace");
1964 try sema.resolveTypeFields(stack_trace_ty);
19611965 const st_ptr = try err_trace_block.addTy(.alloc, try mod.singleMutPtrType(stack_trace_ty));
19621966
19631967 // st.instruction_addresses = &addrs;
......@@ -2890,10 +2894,17 @@ fn zirStructDecl(
28902894 });
28912895 errdefer mod.destroyStruct(struct_index);
28922896
2893 const struct_ty = try mod.intern_pool.get(gpa, .{ .struct_type = .{
2894 .index = struct_index.toOptional(),
2895 .namespace = new_namespace_index.toOptional(),
2896 } });
2897 const struct_ty = ty: {
2898 const ty = try mod.intern_pool.get(gpa, .{ .struct_type = .{
2899 .index = struct_index.toOptional(),
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 };
28972908 // TODO: figure out InternPool removals for incremental compilation
28982909 //errdefer mod.intern_pool.remove(struct_ty);
28992910
......@@ -3084,18 +3095,25 @@ fn zirEnumDecl(
30843095 if (bag != 0) break true;
30853096 } else false;
30863097
3087 const incomplete_enum = try mod.intern_pool.getIncompleteEnum(gpa, .{
3088 .decl = new_decl_index,
3089 .namespace = new_namespace_index.toOptional(),
3090 .fields_len = fields_len,
3091 .has_values = any_values,
3092 .tag_mode = if (small.nonexhaustive)
3093 .nonexhaustive
3094 else if (tag_type_ref == .none)
3095 .auto
3096 else
3097 .explicit,
3098 });
3098 const incomplete_enum = incomplete_enum: {
3099 var incomplete_enum = try mod.intern_pool.getIncompleteEnum(gpa, .{
3100 .decl = new_decl_index,
3101 .namespace = new_namespace_index.toOptional(),
3102 .fields_len = fields_len,
3103 .has_values = any_values,
3104 .tag_mode = if (small.nonexhaustive)
3105 .nonexhaustive
3106 else if (tag_type_ref == .none)
3107 .auto
3108 else
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 };
30993117 // TODO: figure out InternPool removals for incremental compilation
31003118 //errdefer if (!done) mod.intern_pool.remove(incomplete_enum.index);
31013119
......@@ -3336,17 +3354,24 @@ fn zirUnionDecl(
33363354 });
33373355 errdefer mod.destroyUnion(union_index);
33383356
3339 const union_ty = try mod.intern_pool.get(gpa, .{ .union_type = .{
3340 .index = union_index,
3341 .runtime_tag = if (small.has_tag_type or small.auto_enum_tag)
3342 .tagged
3343 else if (small.layout != .Auto)
3344 .none
3345 else switch (block.sema.mod.optimizeMode()) {
3346 .Debug, .ReleaseSafe => .safety,
3347 .ReleaseFast, .ReleaseSmall => .none,
3348 },
3349 } });
3357 const union_ty = ty: {
3358 const ty = try mod.intern_pool.get(gpa, .{ .union_type = .{
3359 .index = union_index,
3360 .runtime_tag = if (small.has_tag_type or small.auto_enum_tag)
3361 .tagged
3362 else if (small.layout != .Auto)
3363 .none
3364 else switch (block.sema.mod.optimizeMode()) {
3365 .Debug, .ReleaseSafe => .safety,
3366 .ReleaseFast, .ReleaseSmall => .none,
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 };
33503375 // TODO: figure out InternPool removals for incremental compilation
33513376 //errdefer mod.intern_pool.remove(union_ty);
33523377
......@@ -3473,8 +3498,8 @@ fn zirRetPtr(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref {
34733498 defer tracy.end();
34743499
34753500 if (block.is_comptime or try sema.typeRequiresComptime(sema.fn_ret_ty)) {
3476 const fn_ret_ty = try sema.resolveTypeFields(sema.fn_ret_ty);
3477 return sema.analyzeComptimeAlloc(block, fn_ret_ty, .none);
3501 try sema.resolveTypeFields(sema.fn_ret_ty);
3502 return sema.analyzeComptimeAlloc(block, sema.fn_ret_ty, .none);
34783503 }
34793504
34803505 const target = sema.mod.getTarget();
......@@ -4371,7 +4396,7 @@ fn zirValidateArrayInitTy(
43714396 return;
43724397 },
43734398 .Struct => if (ty.isTuple(mod)) {
4374 _ = try sema.resolveTypeFields(ty);
4399 try sema.resolveTypeFields(ty);
43754400 const array_len = ty.arrayLen(mod);
43764401 if (extra.init_count > array_len) {
43774402 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
64766501 if (block.is_comptime)
64776502 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) {
64806505 error.NeededSourceLocation, error.GenericPoison, error.ComptimeReturn, error.ComptimeBreak => unreachable,
64816506 else => |e| return e,
64826507 };
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) {
64846509 error.NeededSourceLocation, error.GenericPoison, error.ComptimeReturn, error.ComptimeBreak => unreachable,
64856510 else => |e| return e,
64866511 };
......@@ -6522,8 +6547,8 @@ fn popErrorReturnTrace(
65226547 // AstGen determined this result does not go to an error-handling expr (try/catch/return etc.), or
65236548 // 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");
6526 const stack_trace_ty = try sema.resolveTypeFields(unresolved_stack_trace_ty);
6550 const stack_trace_ty = try sema.getBuiltinType("StackTrace");
6551 try sema.resolveTypeFields(stack_trace_ty);
65276552 const ptr_stack_trace_ty = try mod.singleMutPtrType(stack_trace_ty);
65286553 const err_return_trace = try block.addTy(.err_return_trace, ptr_stack_trace_ty);
65296554 const field_name = try mod.intern_pool.getOrPutString(gpa, "index");
......@@ -6548,8 +6573,8 @@ fn popErrorReturnTrace(
65486573 defer then_block.instructions.deinit(gpa);
65496574
65506575 // If non-error, then pop the error return trace by restoring the index.
6551 const unresolved_stack_trace_ty = try sema.getBuiltinType("StackTrace");
6552 const stack_trace_ty = try sema.resolveTypeFields(unresolved_stack_trace_ty);
6576 const stack_trace_ty = try sema.getBuiltinType("StackTrace");
6577 try sema.resolveTypeFields(stack_trace_ty);
65536578 const ptr_stack_trace_ty = try mod.singleMutPtrType(stack_trace_ty);
65546579 const err_return_trace = try then_block.addTy(.err_return_trace, ptr_stack_trace_ty);
65556580 const field_name = try mod.intern_pool.getOrPutString(gpa, "index");
......@@ -6671,8 +6696,8 @@ fn zirCall(
66716696 // If any input is an error-type, we might need to pop any trace it generated. Otherwise, we only
66726697 // need to clean-up our own trace if we were passed to a non-error-handling expression.
66736698 if (input_is_error or (pop_error_return_trace and return_ty.isError(mod))) {
6674 const unresolved_stack_trace_ty = try sema.getBuiltinType("StackTrace");
6675 const stack_trace_ty = try sema.resolveTypeFields(unresolved_stack_trace_ty);
6699 const stack_trace_ty = try sema.getBuiltinType("StackTrace");
6700 try sema.resolveTypeFields(stack_trace_ty);
66766701 const field_name = try mod.intern_pool.getOrPutString(sema.gpa, "index");
66776702 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
80848109fn zirElemTypeIndex(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
80858110 const mod = sema.mod;
80868111 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) {
80888113 // Since this is a ZIR instruction that returns a type, encountering
80898114 // generic poison should not result in a failed compilation, but the
80908115 // generic poison type. This prevents unnecessary failures when
......@@ -8092,7 +8117,7 @@ fn zirElemTypeIndex(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr
80928117 error.GenericPoison => return .generic_poison_type,
80938118 else => |e| return e,
80948119 };
8095 const indexable_ty = try sema.resolveTypeFields(operand);
8120 try sema.resolveTypeFields(indexable_ty);
80968121 assert(indexable_ty.isIndexable(mod)); // validated by a previous instruction
80978122 if (indexable_ty.zigTypeTag(mod) == .Struct) {
80988123 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
84208445 const enum_tag: Air.Inst.Ref = switch (operand_ty.zigTypeTag(mod)) {
84218446 .Enum => operand,
84228447 .Union => blk: {
8423 const union_ty = try sema.resolveTypeFields(operand_ty);
8424 const tag_ty = union_ty.unionTagType(mod) orelse {
8448 try sema.resolveTypeFields(operand_ty);
8449 const tag_ty = operand_ty.unionTagType(mod) orelse {
84258450 return sema.fail(
84268451 block,
84278452 operand_src,
......@@ -9573,7 +9598,7 @@ fn finishFunc(
95739598 // Make sure that StackTrace's fields are resolved so that the backend can
95749599 // lower this fn type.
95759600 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);
95779602 }
95789603
95799604 return Air.internedToRef(if (opt_func_index != .none) opt_func_index else func_ty);
......@@ -10890,12 +10915,12 @@ fn switchCond(
1089010915 },
1089110916
1089210917 .Union => {
10893 const union_ty = try sema.resolveTypeFields(operand_ty);
10894 const enum_ty = union_ty.unionTagType(mod) orelse {
10918 try sema.resolveTypeFields(operand_ty);
10919 const enum_ty = operand_ty.unionTagType(mod) orelse {
1089510920 const msg = msg: {
1089610921 const msg = try sema.errMsg(block, src, "switch on union with no attached enum", .{});
1089710922 errdefer msg.destroy(sema.gpa);
10898 if (union_ty.declSrcLocOrNull(mod)) |union_src| {
10923 if (operand_ty.declSrcLocOrNull(mod)) |union_src| {
1089910924 try mod.errNoteNonLazy(union_src, msg, "consider 'union(enum)' here", .{});
1090010925 }
1090110926 break :msg msg;
......@@ -12780,9 +12805,9 @@ fn zirHasField(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1278012805 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
1278112806 const ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
1278212807 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);
1278412809 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);
1278612811 const ip = &mod.intern_pool;
1278712812
1278812813 const has_field = hf: {
......@@ -16141,7 +16166,8 @@ fn analyzeCmpUnionTag(
1614116166 op: std.math.CompareOperator,
1614216167) CompileError!Air.Inst.Ref {
1614316168 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);
1614516171 const union_tag_ty = union_ty.unionTagType(mod) orelse {
1614616172 const msg = msg: {
1614716173 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
1727817304 break :t union_field_ty_decl.val.toType();
1727917305 };
1728017306
17281 const union_ty = try sema.resolveTypeFields(ty);
1728217307 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);
1728617311 const union_field_vals = try gpa.alloc(InternPool.Index, union_fields.count());
1728717312 defer gpa.free(union_field_vals);
1728817313
......@@ -17357,11 +17382,11 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1735717382 } });
1735817383 };
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
1736217387 const enum_tag_ty_val = try mod.intern(.{ .opt = .{
1736317388 .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,
1736517390 } });
1736617391
1736717392 const container_layout_ty = t: {
......@@ -17429,18 +17454,17 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1742917454 break :t struct_field_ty_decl.val.toType();
1743017455 };
1743117456
17432 const struct_ty = try sema.resolveTypeFields(ty);
1743317457 try sema.resolveTypeLayout(ty); // Getting alignment requires type layout
17434 const layout = struct_ty.containerLayout(mod);
17458 const layout = ty.containerLayout(mod);
1743517459
1743617460 var struct_field_vals: []InternPool.Index = &.{};
1743717461 defer gpa.free(struct_field_vals);
1743817462 fv: {
17439 const struct_type = switch (ip.indexToKey(struct_ty.toIntern())) {
17463 const struct_type = switch (ip.indexToKey(ty.toIntern())) {
1744017464 .anon_struct_type => |tuple| {
1744117465 struct_field_vals = try gpa.alloc(InternPool.Index, tuple.types.len);
1744217466 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;
1744417468 const field_ty = anon_struct_type.types[i];
1744517469 const field_val = anon_struct_type.values[i];
1744617470 const name_val = v: {
......@@ -17449,7 +17473,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1744917473 // TODO: write something like getCoercedInts to avoid needing to dupe
1745017474 const bytes = if (tuple.names.len != 0)
1745117475 // 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]))
1745317477 else
1745417478 try std.fmt.allocPrint(sema.arena, "{d}", .{i});
1745517479 const new_decl_ty = try mod.arrayType(.{
......@@ -17582,12 +17606,12 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1758217606 } });
1758317607 };
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
1758717611 const backing_integer_val = try mod.intern(.{ .opt = .{
1758817612 .ty = (try mod.optionalType(.type_type)).toIntern(),
1758917613 .val = if (layout == .Packed) val: {
17590 const struct_obj = mod.typeToStruct(struct_ty).?;
17614 const struct_obj = mod.typeToStruct(ty).?;
1759117615 assert(struct_obj.haveLayout());
1759217616 assert(struct_obj.backing_int_ty.isInt(mod));
1759317617 break :val struct_obj.backing_int_ty.toIntern();
......@@ -17617,7 +17641,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1761717641 // decls: []const Declaration,
1761817642 decls_val,
1761917643 // is_tuple: bool,
17620 Value.makeBool(struct_ty.isTuple(mod)).toIntern(),
17644 Value.makeBool(ty.isTuple(mod)).toIntern(),
1762117645 };
1762217646 return Air.internedToRef((try mod.intern(.{ .un = .{
1762317647 .ty = type_info_ty.toIntern(),
......@@ -17644,8 +17668,8 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1764417668 break :t type_opaque_ty_decl.val.toType();
1764517669 };
1764617670
17647 const opaque_ty = try sema.resolveTypeFields(ty);
17648 const decls_val = try sema.typeInfoDecls(block, src, type_info_ty, opaque_ty.getNamespaceIndex(mod));
17671 try sema.resolveTypeFields(ty);
17672 const decls_val = try sema.typeInfoDecls(block, src, type_info_ty, ty.getNamespaceIndex(mod));
1764917673
1765017674 const field_values = .{
1765117675 // decls: []const Declaration,
......@@ -18511,8 +18535,8 @@ fn retWithErrTracing(
1851118535 else => true,
1851218536 };
1851318537 const gpa = sema.gpa;
18514 const unresolved_stack_trace_ty = try sema.getBuiltinType("StackTrace");
18515 const stack_trace_ty = try sema.resolveTypeFields(unresolved_stack_trace_ty);
18538 const stack_trace_ty = try sema.getBuiltinType("StackTrace");
18539 try sema.resolveTypeFields(stack_trace_ty);
1851618540 const ptr_stack_trace_ty = try mod.singleMutPtrType(stack_trace_ty);
1851718541 const err_return_trace = try block.addTy(.err_return_trace, ptr_stack_trace_ty);
1851818542 const return_err_fn = try sema.getBuiltin("returnError");
......@@ -18874,14 +18898,14 @@ fn zirStructInitEmpty(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE
1887418898fn structInitEmpty(
1887518899 sema: *Sema,
1887618900 block: *Block,
18877 obj_ty: Type,
18901 struct_ty: Type,
1887818902 dest_src: LazySrcLoc,
1887918903 init_src: LazySrcLoc,
1888018904) CompileError!Air.Inst.Ref {
1888118905 const mod = sema.mod;
1888218906 const gpa = sema.gpa;
1888318907 // 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
1888618910 // The init values to use for the struct instance.
1888718911 const field_inits = try gpa.alloc(Air.Inst.Ref, struct_ty.structFieldCount(mod));
......@@ -19674,8 +19698,7 @@ fn fieldType(
1967419698 const mod = sema.mod;
1967519699 var cur_ty = aggregate_ty;
1967619700 while (true) {
19677 const resolved_ty = try sema.resolveTypeFields(cur_ty);
19678 cur_ty = resolved_ty;
19701 try sema.resolveTypeFields(cur_ty);
1967919702 switch (cur_ty.zigTypeTag(mod)) {
1968019703 .Struct => switch (mod.intern_pool.indexToKey(cur_ty.toIntern())) {
1968119704 .anon_struct_type => |anon_struct| {
......@@ -19709,7 +19732,7 @@ fn fieldType(
1970919732 else => {},
1971019733 }
1971119734 return sema.fail(block, ty_src, "expected struct or union; found '{}'", .{
19712 resolved_ty.fmt(sema.mod),
19735 cur_ty.fmt(sema.mod),
1971319736 });
1971419737 }
1971519738}
......@@ -19721,8 +19744,8 @@ fn zirErrorReturnTrace(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref {
1972119744fn getErrorReturnTrace(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref {
1972219745 const mod = sema.mod;
1972319746 const ip = &mod.intern_pool;
19724 const unresolved_stack_trace_ty = try sema.getBuiltinType("StackTrace");
19725 const stack_trace_ty = try sema.resolveTypeFields(unresolved_stack_trace_ty);
19747 const stack_trace_ty = try sema.getBuiltinType("StackTrace");
19748 try sema.resolveTypeFields(stack_trace_ty);
1972619749 const ptr_stack_trace_ty = try mod.singleMutPtrType(stack_trace_ty);
1972719750 const opt_ptr_stack_trace_ty = try mod.optionalType(ptr_stack_trace_ty.toIntern());
1972819751
......@@ -20048,14 +20071,10 @@ fn zirReify(
2004820071 (try alignment_val.getUnsignedIntAdvanced(mod, sema)).?,
2004920072 );
2005020073
20051 const unresolved_elem_ty = child_val.toType();
20052 const elem_ty = if (abi_align == .none)
20053 unresolved_elem_ty
20054 else t: {
20055 const elem_ty = try sema.resolveTypeFields(unresolved_elem_ty);
20074 const elem_ty = child_val.toType();
20075 if (abi_align != .none) {
2005620076 try sema.resolveTypeLayout(elem_ty);
20057 break :t elem_ty;
20058 };
20077 }
2005920078
2006020079 const ptr_size = mod.toEnum(std.builtin.Type.Pointer.Size, size_val);
2006120080
......@@ -25070,8 +25089,8 @@ fn prepareSimplePanic(sema: *Sema, block: *Block) !void {
2507025089 }
2507125090
2507225091 if (mod.null_stack_trace == .none) {
25073 const unresolved_stack_trace_ty = try sema.getBuiltinType("StackTrace");
25074 const stack_trace_ty = try sema.resolveTypeFields(unresolved_stack_trace_ty);
25092 const stack_trace_ty = try sema.getBuiltinType("StackTrace");
25093 try sema.resolveTypeFields(stack_trace_ty);
2507525094 const target = mod.getTarget();
2507625095 const ptr_stack_trace_ty = try mod.ptrType(.{
2507725096 .child = stack_trace_ty.toIntern(),
......@@ -25523,14 +25542,14 @@ fn fieldVal(
2552325542 return inst;
2552425543 }
2552525544 }
25526 const union_ty = try sema.resolveTypeFields(child_type);
25527 if (union_ty.unionTagType(mod)) |enum_ty| {
25545 try sema.resolveTypeFields(child_type);
25546 if (child_type.unionTagType(mod)) |enum_ty| {
2552825547 if (enum_ty.enumFieldIndex(field_name, mod)) |field_index_usize| {
2552925548 const field_index = @as(u32, @intCast(field_index_usize));
2553025549 return Air.internedToRef((try mod.enumValueFieldIndex(enum_ty, field_index)).toIntern());
2553125550 }
2553225551 }
25533 return sema.failWithBadMemberAccess(block, union_ty, field_name_src, field_name);
25552 return sema.failWithBadMemberAccess(block, child_type, field_name_src, field_name);
2553425553 },
2553525554 .Enum => {
2553625555 if (child_type.getNamespaceIndex(mod).unwrap()) |namespace| {
......@@ -25749,8 +25768,8 @@ fn fieldPtr(
2574925768 return inst;
2575025769 }
2575125770 }
25752 const union_ty = try sema.resolveTypeFields(child_type);
25753 if (union_ty.unionTagType(mod)) |enum_ty| {
25771 try sema.resolveTypeFields(child_type);
25772 if (child_type.unionTagType(mod)) |enum_ty| {
2575425773 if (enum_ty.enumFieldIndex(field_name, mod)) |field_index| {
2575525774 const field_index_u32 = @as(u32, @intCast(field_index));
2575625775 var anon_decl = try block.startAnonDecl();
......@@ -25854,35 +25873,35 @@ fn fieldCallBind(
2585425873 find_field: {
2585525874 switch (concrete_ty.zigTypeTag(mod)) {
2585625875 .Struct => {
25857 const struct_ty = try sema.resolveTypeFields(concrete_ty);
25858 if (mod.typeToStruct(struct_ty)) |struct_obj| {
25876 try sema.resolveTypeFields(concrete_ty);
25877 if (mod.typeToStruct(concrete_ty)) |struct_obj| {
2585925878 const field_index_usize = struct_obj.fields.getIndex(field_name) orelse
2586025879 break :find_field;
2586125880 const field_index = @as(u32, @intCast(field_index_usize));
2586225881 const field = struct_obj.fields.values()[field_index];
2586325882
2586425883 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)) {
2586625885 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)) };
2586825887 }
2586925888 if (field_name.toUnsigned(ip)) |field_index| {
25870 if (field_index >= struct_ty.structFieldCount(mod)) break :find_field;
25871 return sema.finishFieldCallBind(block, src, ptr_ty, struct_ty.structFieldType(field_index, mod), field_index, object_ptr);
25889 if (field_index >= concrete_ty.structFieldCount(mod)) break :find_field;
25890 return sema.finishFieldCallBind(block, src, ptr_ty, concrete_ty.structFieldType(field_index, mod), field_index, object_ptr);
2587225891 }
2587325892 } else {
25874 const max = struct_ty.structFieldCount(mod);
25893 const max = concrete_ty.structFieldCount(mod);
2587525894 for (0..max) |i_usize| {
2587625895 const i = @as(u32, @intCast(i_usize));
25877 if (field_name == struct_ty.structFieldName(i, mod)) {
25878 return sema.finishFieldCallBind(block, src, ptr_ty, struct_ty.structFieldType(i, mod), i, object_ptr);
25896 if (field_name == concrete_ty.structFieldName(i, mod)) {
25897 return sema.finishFieldCallBind(block, src, ptr_ty, concrete_ty.structFieldType(i, mod), i, object_ptr);
2587925898 }
2588025899 }
2588125900 }
2588225901 },
2588325902 .Union => {
25884 const union_ty = try sema.resolveTypeFields(concrete_ty);
25885 const fields = union_ty.unionFields(mod);
25903 try sema.resolveTypeFields(concrete_ty);
25904 const fields = concrete_ty.unionFields(mod);
2588625905 const field_index_usize = fields.getIndex(field_name) orelse break :find_field;
2588725906 const field_index = @as(u32, @intCast(field_index_usize));
2588825907 const field = fields.values()[field_index];
......@@ -26081,13 +26100,13 @@ fn structFieldPtr(
2608126100 struct_ptr: Air.Inst.Ref,
2608226101 field_name: InternPool.NullTerminatedString,
2608326102 field_name_src: LazySrcLoc,
26084 unresolved_struct_ty: Type,
26103 struct_ty: Type,
2608526104 initializing: bool,
2608626105) CompileError!Air.Inst.Ref {
2608726106 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);
2609126110 try sema.resolveStructLayout(struct_ty);
2609226111
2609326112 if (struct_ty.isTuple(mod)) {
......@@ -26234,12 +26253,12 @@ fn structFieldVal(
2623426253 struct_byval: Air.Inst.Ref,
2623526254 field_name: InternPool.NullTerminatedString,
2623626255 field_name_src: LazySrcLoc,
26237 unresolved_struct_ty: Type,
26256 struct_ty: Type,
2623826257) CompileError!Air.Inst.Ref {
2623926258 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);
2624326262 switch (mod.intern_pool.indexToKey(struct_ty.toIntern())) {
2624426263 .struct_type => |struct_type| {
2624526264 const struct_obj = mod.structPtrUnwrap(struct_type.index).?;
......@@ -26361,17 +26380,17 @@ fn unionFieldPtr(
2636126380 union_ptr: Air.Inst.Ref,
2636226381 field_name: InternPool.NullTerminatedString,
2636326382 field_name_src: LazySrcLoc,
26364 unresolved_union_ty: Type,
26383 union_ty: Type,
2636526384 initializing: bool,
2636626385) CompileError!Air.Inst.Ref {
2636726386 const mod = sema.mod;
2636826387 const ip = &mod.intern_pool;
2636926388
26370 assert(unresolved_union_ty.zigTypeTag(mod) == .Union);
26389 assert(union_ty.zigTypeTag(mod) == .Union);
2637126390
2637226391 const union_ptr_ty = sema.typeOf(union_ptr);
2637326392 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);
2637526394 const union_obj = mod.typeToUnion(union_ty).?;
2637626395 const field_index = try sema.unionFieldIndex(block, union_ty, field_name, field_name_src);
2637726396 const field = union_obj.fields.values()[field_index];
......@@ -26467,13 +26486,13 @@ fn unionFieldVal(
2646726486 union_byval: Air.Inst.Ref,
2646826487 field_name: InternPool.NullTerminatedString,
2646926488 field_name_src: LazySrcLoc,
26470 unresolved_union_ty: Type,
26489 union_ty: Type,
2647126490) CompileError!Air.Inst.Ref {
2647226491 const mod = sema.mod;
2647326492 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);
2647726496 const union_obj = mod.typeToUnion(union_ty).?;
2647826497 const field_index = try sema.unionFieldIndex(block, union_ty, field_name, field_name_src);
2647926498 const field = union_obj.fields.values()[field_index];
......@@ -26733,7 +26752,7 @@ fn tupleFieldPtr(
2673326752 const mod = sema.mod;
2673426753 const tuple_ptr_ty = sema.typeOf(tuple_ptr);
2673526754 const tuple_ty = tuple_ptr_ty.childType(mod);
26736 _ = try sema.resolveTypeFields(tuple_ty);
26755 try sema.resolveTypeFields(tuple_ty);
2673726756 const field_count = tuple_ty.structFieldCount(mod);
2673826757
2673926758 if (field_count == 0) {
......@@ -26790,7 +26809,8 @@ fn tupleField(
2679026809 field_index: u32,
2679126810) CompileError!Air.Inst.Ref {
2679226811 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);
2679426814 const field_count = tuple_ty.structFieldCount(mod);
2679526815
2679626816 if (field_count == 0) {
......@@ -27114,16 +27134,17 @@ const CoerceOpts = struct {
2711427134fn coerceExtra(
2711527135 sema: *Sema,
2711627136 block: *Block,
27117 dest_ty_unresolved: Type,
27137 dest_ty: Type,
2711827138 inst: Air.Inst.Ref,
2711927139 inst_src: LazySrcLoc,
2712027140 opts: CoerceOpts,
2712127141) CoersionError!Air.Inst.Ref {
27122 if (dest_ty_unresolved.isGenericPoison()) return inst;
27142 if (dest_ty.isGenericPoison()) return inst;
2712327143 const mod = sema.mod;
2712427144 const dest_ty_src = inst_src; // TODO better source location
27125 const dest_ty = try sema.resolveTypeFields(dest_ty_unresolved);
27126 const inst_ty = try sema.resolveTypeFields(sema.typeOf(inst));
27145 try sema.resolveTypeFields(dest_ty);
27146 const inst_ty = sema.typeOf(inst);
27147 try sema.resolveTypeFields(inst_ty);
2712727148 const target = mod.getTarget();
2712827149 // If the types are the same, we can return the operand.
2712927150 if (dest_ty.eql(inst_ty, mod))
......@@ -29831,16 +29852,15 @@ fn beginComptimePtrLoad(
2983129852fn bitCast(
2983229853 sema: *Sema,
2983329854 block: *Block,
29834 dest_ty_unresolved: Type,
29855 dest_ty: Type,
2983529856 inst: Air.Inst.Ref,
2983629857 inst_src: LazySrcLoc,
2983729858 operand_src: ?LazySrcLoc,
2983829859) CompileError!Air.Inst.Ref {
2983929860 const mod = sema.mod;
29840 const dest_ty = try sema.resolveTypeFields(dest_ty_unresolved);
2984129861 try sema.resolveTypeLayout(dest_ty);
2984229862
29843 const old_ty = try sema.resolveTypeFields(sema.typeOf(inst));
29863 const old_ty = sema.typeOf(inst);
2984429864 try sema.resolveTypeLayout(old_ty);
2984529865
2984629866 const dest_bits = dest_ty.bitSize(mod);
......@@ -30043,8 +30063,8 @@ fn coerceEnumToUnion(
3004330063
3004430064 const union_obj = mod.typeToUnion(union_ty).?;
3004530065 const field = union_obj.fields.values()[field_index];
30046 const field_ty = try sema.resolveTypeFields(field.ty);
30047 if (field_ty.zigTypeTag(mod) == .NoReturn) {
30066 try sema.resolveTypeFields(field.ty);
30067 if (field.ty.zigTypeTag(mod) == .NoReturn) {
3004830068 const msg = msg: {
3004930069 const msg = try sema.errMsg(block, inst_src, "cannot initialize 'noreturn' field of union", .{});
3005030070 errdefer msg.destroy(sema.gpa);
......@@ -30058,12 +30078,12 @@ fn coerceEnumToUnion(
3005830078 };
3005930079 return sema.failWithOwnedErrorMsg(msg);
3006030080 }
30061 const opv = (try sema.typeHasOnePossibleValue(field_ty)) orelse {
30081 const opv = (try sema.typeHasOnePossibleValue(field.ty)) orelse {
3006230082 const msg = msg: {
3006330083 const field_name = union_obj.fields.keys()[field_index];
3006430084 const msg = try sema.errMsg(block, inst_src, "coercion from enum '{}' to union '{}' must initialize '{}' field '{}'", .{
3006530085 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),
3006730087 });
3006830088 errdefer msg.destroy(sema.gpa);
3006930089
......@@ -30427,13 +30447,13 @@ fn coerceTupleToArrayPtrs(
3042730447fn coerceTupleToStruct(
3042830448 sema: *Sema,
3042930449 block: *Block,
30430 dest_ty: Type,
30450 struct_ty: Type,
3043130451 inst: Air.Inst.Ref,
3043230452 inst_src: LazySrcLoc,
3043330453) !Air.Inst.Ref {
3043430454 const mod = sema.mod;
3043530455 const ip = &mod.intern_pool;
30436 const struct_ty = try sema.resolveTypeFields(dest_ty);
30456 try sema.resolveTypeFields(struct_ty);
3043730457
3043830458 if (struct_ty.isTupleOrAnonStruct(mod)) {
3043930459 return sema.coerceTupleToTuple(block, struct_ty, inst, inst_src);
......@@ -33729,6 +33749,10 @@ fn resolveLazyValue(sema: *Sema, val: Value) CompileError!Value {
3372933749
3373033750pub fn resolveTypeLayout(sema: *Sema, ty: Type) CompileError!void {
3373133751 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 }
3373233756 switch (ty.zigTypeTag(mod)) {
3373333757 .Struct => return sema.resolveStructLayout(ty),
3373433758 .Union => return sema.resolveUnionLayout(ty),
......@@ -33769,8 +33793,8 @@ pub fn resolveTypeLayout(sema: *Sema, ty: Type) CompileError!void {
3376933793
3377033794fn resolveStructLayout(sema: *Sema, ty: Type) CompileError!void {
3377133795 const mod = sema.mod;
33772 const resolved_ty = try sema.resolveTypeFields(ty);
33773 if (mod.typeToStruct(resolved_ty)) |struct_obj| {
33796 try sema.resolveTypeFields(ty);
33797 if (mod.typeToStruct(ty)) |struct_obj| {
3377433798 switch (struct_obj.status) {
3377533799 .none, .have_field_types => {},
3377633800 .field_types_wip, .layout_wip => {
......@@ -33806,9 +33830,9 @@ fn resolveStructLayout(sema: *Sema, ty: Type) CompileError!void {
3380633830 }
3380733831
3380833832 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))) {
3381233836 const msg = try Module.ErrorMsg.create(
3381333837 sema.gpa,
3381433838 struct_obj.srcLoc(mod),
......@@ -34020,8 +34044,8 @@ fn checkMemOperand(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) !void
3402034044
3402134045fn resolveUnionLayout(sema: *Sema, ty: Type) CompileError!void {
3402234046 const mod = sema.mod;
34023 const resolved_ty = try sema.resolveTypeFields(ty);
34024 const union_obj = mod.typeToUnion(resolved_ty).?;
34047 try sema.resolveTypeFields(ty);
34048 const union_obj = mod.typeToUnion(ty).?;
3402534049 switch (union_obj.status) {
3402634050 .none, .have_field_types => {},
3402734051 .field_types_wip, .layout_wip => {
......@@ -34052,9 +34076,9 @@ fn resolveUnionLayout(sema: *Sema, ty: Type) CompileError!void {
3405234076 };
3405334077 }
3405434078 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))) {
3405834082 const msg = try Module.ErrorMsg.create(
3405934083 sema.gpa,
3406034084 union_obj.srcLoc(sema.mod),
......@@ -34228,8 +34252,7 @@ pub fn resolveTypeFully(sema: *Sema, ty: Type) CompileError!void {
3422834252 const mod = sema.mod;
3422934253 switch (ty.zigTypeTag(mod)) {
3423034254 .Pointer => {
34231 const child_ty = try sema.resolveTypeFields(ty.childType(mod));
34232 return sema.resolveTypeFully(child_ty);
34255 return sema.resolveTypeFully(ty.childType(mod));
3423334256 },
3423434257 .Struct => switch (mod.intern_pool.indexToKey(ty.toIntern())) {
3423534258 .struct_type => return sema.resolveStructFully(ty),
......@@ -34238,6 +34261,7 @@ pub fn resolveTypeFully(sema: *Sema, ty: Type) CompileError!void {
3423834261 try sema.resolveTypeFully(field_ty.toType());
3423934262 }
3424034263 },
34264 .simple_type => |simple_type| try sema.resolveSimpleType(simple_type),
3424134265 else => {},
3424234266 },
3424334267 .Union => return sema.resolveUnionFully(ty),
......@@ -34268,8 +34292,8 @@ fn resolveStructFully(sema: *Sema, ty: Type) CompileError!void {
3426834292 try sema.resolveStructLayout(ty);
3426934293
3427034294 const mod = sema.mod;
34271 const resolved_ty = try sema.resolveTypeFields(ty);
34272 const struct_obj = mod.typeToStruct(resolved_ty).?;
34295 try sema.resolveTypeFields(ty);
34296 const struct_obj = mod.typeToStruct(ty).?;
3427334297
3427434298 switch (struct_obj.status) {
3427534299 .none, .have_field_types, .field_types_wip, .layout_wip, .have_layout => {},
......@@ -34298,8 +34322,8 @@ fn resolveUnionFully(sema: *Sema, ty: Type) CompileError!void {
3429834322 try sema.resolveUnionLayout(ty);
3429934323
3430034324 const mod = sema.mod;
34301 const resolved_ty = try sema.resolveTypeFields(ty);
34302 const union_obj = mod.typeToUnion(resolved_ty).?;
34325 try sema.resolveTypeFields(ty);
34326 const union_obj = mod.typeToUnion(ty).?;
3430334327 switch (union_obj.status) {
3430434328 .none, .have_field_types, .field_types_wip, .layout_wip, .have_layout => {},
3430534329 .fully_resolved_wip, .fully_resolved => return,
......@@ -34323,7 +34347,7 @@ fn resolveUnionFully(sema: *Sema, ty: Type) CompileError!void {
3432334347 _ = try sema.typeRequiresComptime(ty);
3432434348}
3432534349
34326pub fn resolveTypeFields(sema: *Sema, ty: Type) CompileError!Type {
34350pub fn resolveTypeFields(sema: *Sema, ty: Type) CompileError!void {
3432734351 const mod = sema.mod;
3432834352
3432934353 switch (ty.toIntern()) {
......@@ -34386,7 +34410,7 @@ pub fn resolveTypeFields(sema: *Sema, ty: Type) CompileError!Type {
3438634410 .anyerror_void_error_union_type,
3438734411 .generic_poison_type,
3438834412 .empty_struct_type,
34389 => return ty,
34413 => {},
3439034414
3439134415 .undef => unreachable,
3439234416 .zero => unreachable,
......@@ -34407,42 +34431,52 @@ pub fn resolveTypeFields(sema: *Sema, ty: Type) CompileError!Type {
3440734431 .empty_struct => unreachable,
3440834432 .generic_poison => unreachable,
3440934433
34410 .type_info_type => return sema.getBuiltinType("Type"),
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())]) {
34434 else => switch (mod.intern_pool.items.items(.tag)[@intFromEnum(ty.toIntern())]) {
3442334435 .type_struct,
3442434436 .type_struct_ns,
3442534437 .type_union_tagged,
3442634438 .type_union_untagged,
3442734439 .type_union_safety,
34440 .simple_type,
3442834441 => switch (mod.intern_pool.indexToKey(ty.toIntern())) {
3442934442 .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;
3443134444 try sema.resolveTypeFieldsStruct(ty, struct_obj);
34432 return ty;
3443334445 },
3443434446 .union_type => |union_type| {
3443534447 const union_obj = mod.unionPtr(union_type.index);
3443634448 try sema.resolveTypeFieldsUnion(ty, union_obj);
34437 return ty;
3443834449 },
34450 .simple_type => |simple_type| try sema.resolveSimpleType(simple_type),
3443934451 else => unreachable,
3444034452 },
34441 else => return ty,
34453 else => {},
3444234454 },
3444334455 }
3444434456}
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
3444634480fn resolveTypeFieldsStruct(
3444734481 sema: *Sema,
3444834482 ty: Type,
......@@ -35785,7 +35819,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
3578535819 },
3578635820
3578735821 .struct_type => |struct_type| {
35788 const resolved_ty = try sema.resolveTypeFields(ty);
35822 try sema.resolveTypeFields(ty);
3578935823 if (mod.structPtrUnwrap(struct_type.index)) |s| {
3579035824 const field_vals = try sema.arena.alloc(InternPool.Index, s.fields.count());
3579135825 for (field_vals, s.fields.values(), 0..) |*field_val, field, i| {
......@@ -35793,14 +35827,14 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
3579335827 field_val.* = field.default_val;
3579435828 continue;
3579535829 }
35796 if (field.ty.eql(resolved_ty, sema.mod)) {
35830 if (field.ty.eql(ty, sema.mod)) {
3579735831 const msg = try Module.ErrorMsg.create(
3579835832 sema.gpa,
3579935833 s.srcLoc(sema.mod),
3580035834 "struct '{}' depends on itself",
3580135835 .{ty.fmt(sema.mod)},
3580235836 );
35803 try sema.addFieldErrNote(resolved_ty, i, msg, "while checking this field", .{});
35837 try sema.addFieldErrNote(ty, i, msg, "while checking this field", .{});
3580435838 return sema.failWithOwnedErrorMsg(msg);
3580535839 }
3580635840 if (try sema.typeHasOnePossibleValue(field.ty)) |field_opv| {
......@@ -35838,7 +35872,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
3583835872 },
3583935873
3584035874 .union_type => |union_type| {
35841 const resolved_ty = try sema.resolveTypeFields(ty);
35875 try sema.resolveTypeFields(ty);
3584235876 const union_obj = mod.unionPtr(union_type.index);
3584335877 const tag_val = (try sema.typeHasOnePossibleValue(union_obj.tag_ty)) orelse
3584435878 return null;
......@@ -35848,20 +35882,20 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
3584835882 return only.toValue();
3584935883 }
3585035884 const only_field = fields[0];
35851 if (only_field.ty.eql(resolved_ty, sema.mod)) {
35885 if (only_field.ty.eql(ty, sema.mod)) {
3585235886 const msg = try Module.ErrorMsg.create(
3585335887 sema.gpa,
3585435888 union_obj.srcLoc(sema.mod),
3585535889 "union '{}' depends on itself",
3585635890 .{ty.fmt(sema.mod)},
3585735891 );
35858 try sema.addFieldErrNote(resolved_ty, 0, msg, "while checking this field", .{});
35892 try sema.addFieldErrNote(ty, 0, msg, "while checking this field", .{});
3585935893 return sema.failWithOwnedErrorMsg(msg);
3586035894 }
3586135895 const val_val = (try sema.typeHasOnePossibleValue(only_field.ty)) orelse
3586235896 return null;
3586335897 const only = try mod.intern(.{ .un = .{
35864 .ty = resolved_ty.toIntern(),
35898 .ty = ty.toIntern(),
3586535899 .tag = tag_val.toIntern(),
3586635900 .val = val_val.toIntern(),
3586735901 } });
......@@ -36431,12 +36465,12 @@ pub fn fnHasRuntimeBits(sema: *Sema, ty: Type) CompileError!bool {
3643136465fn unionFieldIndex(
3643236466 sema: *Sema,
3643336467 block: *Block,
36434 unresolved_union_ty: Type,
36468 union_ty: Type,
3643536469 field_name: InternPool.NullTerminatedString,
3643636470 field_src: LazySrcLoc,
3643736471) !u32 {
3643836472 const mod = sema.mod;
36439 const union_ty = try sema.resolveTypeFields(unresolved_union_ty);
36473 try sema.resolveTypeFields(union_ty);
3644036474 const union_obj = mod.typeToUnion(union_ty).?;
3644136475 const field_index_usize = union_obj.fields.getIndex(field_name) orelse
3644236476 return sema.failWithBadUnionFieldAccess(block, union_obj, field_src, field_name);
......@@ -36446,12 +36480,12 @@ fn unionFieldIndex(
3644636480fn structFieldIndex(
3644736481 sema: *Sema,
3644836482 block: *Block,
36449 unresolved_struct_ty: Type,
36483 struct_ty: Type,
3645036484 field_name: InternPool.NullTerminatedString,
3645136485 field_src: LazySrcLoc,
3645236486) !u32 {
3645336487 const mod = sema.mod;
36454 const struct_ty = try sema.resolveTypeFields(unresolved_struct_ty);
36488 try sema.resolveTypeFields(struct_ty);
3645536489 if (struct_ty.isAnonStruct(mod)) {
3645636490 return sema.anonStructFieldIndex(block, struct_ty, field_name, field_src);
3645736491 } else {
src/codegen/llvm.zig-11
......@@ -3134,17 +3134,6 @@ pub const Object = struct {
31343134 .null_type,
31353135 .undefined_type,
31363136 .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,
31483137 => unreachable,
31493138 .manyptr_u8_type,
31503139 .manyptr_const_u8_type,
test/cases/compile_errors/wrong_types_given_to_export.zig+1-1
......@@ -7,5 +7,5 @@ comptime {
77// backend=stage2
88// target=native
99//
10// :3:21: error: expected type 'builtin.GlobalLinkage', found 'u32'
10// :3:51: error: expected type 'builtin.GlobalLinkage', found 'u32'
1111// :?:?: note: enum declared here