authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-08-15 15:20:21-07:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2023-08-15 15:20:21-07:00
log340a45683ca8e0b23e95f5fb86bd9c827970e6e8
tree222c5820345cb119a2c6262855ad372cd1d19aaa
parentfdce18cd30a5f20688e582386b802ed8e9a46312
parent083ee8e0e28ed0d1c4e1df6b5aa12f2709731b50
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #16815 from mlugg/internpool-same-resolved-index

InternPool: preserve indices of builtin types when resolved

6 files changed, 294 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+206-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) {
......@@ -26872,6 +26892,7 @@ fn elemValArray(
2687226892
2687326893 const runtime_src = if (maybe_undef_array_val != null) elem_index_src else array_src;
2687426894 try sema.requireRuntimeBlock(block, src, runtime_src);
26895 try sema.queueFullTypeResolution(array_ty);
2687526896 if (oob_safety and block.wantSafety()) {
2687626897 // Runtime check is only needed if unable to comptime check
2687726898 if (maybe_index_val == null) {
......@@ -27113,16 +27134,17 @@ const CoerceOpts = struct {
2711327134fn coerceExtra(
2711427135 sema: *Sema,
2711527136 block: *Block,
27116 dest_ty_unresolved: Type,
27137 dest_ty: Type,
2711727138 inst: Air.Inst.Ref,
2711827139 inst_src: LazySrcLoc,
2711927140 opts: CoerceOpts,
2712027141) CoersionError!Air.Inst.Ref {
27121 if (dest_ty_unresolved.isGenericPoison()) return inst;
27142 if (dest_ty.isGenericPoison()) return inst;
2712227143 const mod = sema.mod;
2712327144 const dest_ty_src = inst_src; // TODO better source location
27124 const dest_ty = try sema.resolveTypeFields(dest_ty_unresolved);
27125 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);
2712627148 const target = mod.getTarget();
2712727149 // If the types are the same, we can return the operand.
2712827150 if (dest_ty.eql(inst_ty, mod))
......@@ -29830,16 +29852,15 @@ fn beginComptimePtrLoad(
2983029852fn bitCast(
2983129853 sema: *Sema,
2983229854 block: *Block,
29833 dest_ty_unresolved: Type,
29855 dest_ty: Type,
2983429856 inst: Air.Inst.Ref,
2983529857 inst_src: LazySrcLoc,
2983629858 operand_src: ?LazySrcLoc,
2983729859) CompileError!Air.Inst.Ref {
2983829860 const mod = sema.mod;
29839 const dest_ty = try sema.resolveTypeFields(dest_ty_unresolved);
2984029861 try sema.resolveTypeLayout(dest_ty);
2984129862
29842 const old_ty = try sema.resolveTypeFields(sema.typeOf(inst));
29863 const old_ty = sema.typeOf(inst);
2984329864 try sema.resolveTypeLayout(old_ty);
2984429865
2984529866 const dest_bits = dest_ty.bitSize(mod);
......@@ -30042,8 +30063,8 @@ fn coerceEnumToUnion(
3004230063
3004330064 const union_obj = mod.typeToUnion(union_ty).?;
3004430065 const field = union_obj.fields.values()[field_index];
30045 const field_ty = try sema.resolveTypeFields(field.ty);
30046 if (field_ty.zigTypeTag(mod) == .NoReturn) {
30066 try sema.resolveTypeFields(field.ty);
30067 if (field.ty.zigTypeTag(mod) == .NoReturn) {
3004730068 const msg = msg: {
3004830069 const msg = try sema.errMsg(block, inst_src, "cannot initialize 'noreturn' field of union", .{});
3004930070 errdefer msg.destroy(sema.gpa);
......@@ -30057,12 +30078,12 @@ fn coerceEnumToUnion(
3005730078 };
3005830079 return sema.failWithOwnedErrorMsg(msg);
3005930080 }
30060 const opv = (try sema.typeHasOnePossibleValue(field_ty)) orelse {
30081 const opv = (try sema.typeHasOnePossibleValue(field.ty)) orelse {
3006130082 const msg = msg: {
3006230083 const field_name = union_obj.fields.keys()[field_index];
3006330084 const msg = try sema.errMsg(block, inst_src, "coercion from enum '{}' to union '{}' must initialize '{}' field '{}'", .{
3006430085 inst_ty.fmt(sema.mod), union_ty.fmt(sema.mod),
30065 field_ty.fmt(sema.mod), field_name.fmt(ip),
30086 field.ty.fmt(sema.mod), field_name.fmt(ip),
3006630087 });
3006730088 errdefer msg.destroy(sema.gpa);
3006830089
......@@ -30426,13 +30447,13 @@ fn coerceTupleToArrayPtrs(
3042630447fn coerceTupleToStruct(
3042730448 sema: *Sema,
3042830449 block: *Block,
30429 dest_ty: Type,
30450 struct_ty: Type,
3043030451 inst: Air.Inst.Ref,
3043130452 inst_src: LazySrcLoc,
3043230453) !Air.Inst.Ref {
3043330454 const mod = sema.mod;
3043430455 const ip = &mod.intern_pool;
30435 const struct_ty = try sema.resolveTypeFields(dest_ty);
30456 try sema.resolveTypeFields(struct_ty);
3043630457
3043730458 if (struct_ty.isTupleOrAnonStruct(mod)) {
3043830459 return sema.coerceTupleToTuple(block, struct_ty, inst, inst_src);
......@@ -33728,6 +33749,10 @@ fn resolveLazyValue(sema: *Sema, val: Value) CompileError!Value {
3372833749
3372933750pub fn resolveTypeLayout(sema: *Sema, ty: Type) CompileError!void {
3373033751 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 }
3373133756 switch (ty.zigTypeTag(mod)) {
3373233757 .Struct => return sema.resolveStructLayout(ty),
3373333758 .Union => return sema.resolveUnionLayout(ty),
......@@ -33768,8 +33793,8 @@ pub fn resolveTypeLayout(sema: *Sema, ty: Type) CompileError!void {
3376833793
3376933794fn resolveStructLayout(sema: *Sema, ty: Type) CompileError!void {
3377033795 const mod = sema.mod;
33771 const resolved_ty = try sema.resolveTypeFields(ty);
33772 if (mod.typeToStruct(resolved_ty)) |struct_obj| {
33796 try sema.resolveTypeFields(ty);
33797 if (mod.typeToStruct(ty)) |struct_obj| {
3377333798 switch (struct_obj.status) {
3377433799 .none, .have_field_types => {},
3377533800 .field_types_wip, .layout_wip => {
......@@ -33805,9 +33830,9 @@ fn resolveStructLayout(sema: *Sema, ty: Type) CompileError!void {
3380533830 }
3380633831
3380733832 struct_obj.status = .have_layout;
33808 _ = try sema.resolveTypeRequiresComptime(resolved_ty);
33833 _ = try sema.resolveTypeRequiresComptime(ty);
3380933834
33810 if (struct_obj.assumed_runtime_bits and !(try sema.typeHasRuntimeBits(resolved_ty))) {
33835 if (struct_obj.assumed_runtime_bits and !(try sema.typeHasRuntimeBits(ty))) {
3381133836 const msg = try Module.ErrorMsg.create(
3381233837 sema.gpa,
3381333838 struct_obj.srcLoc(mod),
......@@ -34019,8 +34044,8 @@ fn checkMemOperand(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) !void
3401934044
3402034045fn resolveUnionLayout(sema: *Sema, ty: Type) CompileError!void {
3402134046 const mod = sema.mod;
34022 const resolved_ty = try sema.resolveTypeFields(ty);
34023 const union_obj = mod.typeToUnion(resolved_ty).?;
34047 try sema.resolveTypeFields(ty);
34048 const union_obj = mod.typeToUnion(ty).?;
3402434049 switch (union_obj.status) {
3402534050 .none, .have_field_types => {},
3402634051 .field_types_wip, .layout_wip => {
......@@ -34051,9 +34076,9 @@ fn resolveUnionLayout(sema: *Sema, ty: Type) CompileError!void {
3405134076 };
3405234077 }
3405334078 union_obj.status = .have_layout;
34054 _ = try sema.resolveTypeRequiresComptime(resolved_ty);
34079 _ = try sema.resolveTypeRequiresComptime(ty);
3405534080
34056 if (union_obj.assumed_runtime_bits and !(try sema.typeHasRuntimeBits(resolved_ty))) {
34081 if (union_obj.assumed_runtime_bits and !(try sema.typeHasRuntimeBits(ty))) {
3405734082 const msg = try Module.ErrorMsg.create(
3405834083 sema.gpa,
3405934084 union_obj.srcLoc(sema.mod),
......@@ -34227,8 +34252,7 @@ pub fn resolveTypeFully(sema: *Sema, ty: Type) CompileError!void {
3422734252 const mod = sema.mod;
3422834253 switch (ty.zigTypeTag(mod)) {
3422934254 .Pointer => {
34230 const child_ty = try sema.resolveTypeFields(ty.childType(mod));
34231 return sema.resolveTypeFully(child_ty);
34255 return sema.resolveTypeFully(ty.childType(mod));
3423234256 },
3423334257 .Struct => switch (mod.intern_pool.indexToKey(ty.toIntern())) {
3423434258 .struct_type => return sema.resolveStructFully(ty),
......@@ -34237,6 +34261,7 @@ pub fn resolveTypeFully(sema: *Sema, ty: Type) CompileError!void {
3423734261 try sema.resolveTypeFully(field_ty.toType());
3423834262 }
3423934263 },
34264 .simple_type => |simple_type| try sema.resolveSimpleType(simple_type),
3424034265 else => {},
3424134266 },
3424234267 .Union => return sema.resolveUnionFully(ty),
......@@ -34267,8 +34292,8 @@ fn resolveStructFully(sema: *Sema, ty: Type) CompileError!void {
3426734292 try sema.resolveStructLayout(ty);
3426834293
3426934294 const mod = sema.mod;
34270 const resolved_ty = try sema.resolveTypeFields(ty);
34271 const struct_obj = mod.typeToStruct(resolved_ty).?;
34295 try sema.resolveTypeFields(ty);
34296 const struct_obj = mod.typeToStruct(ty).?;
3427234297
3427334298 switch (struct_obj.status) {
3427434299 .none, .have_field_types, .field_types_wip, .layout_wip, .have_layout => {},
......@@ -34297,8 +34322,8 @@ fn resolveUnionFully(sema: *Sema, ty: Type) CompileError!void {
3429734322 try sema.resolveUnionLayout(ty);
3429834323
3429934324 const mod = sema.mod;
34300 const resolved_ty = try sema.resolveTypeFields(ty);
34301 const union_obj = mod.typeToUnion(resolved_ty).?;
34325 try sema.resolveTypeFields(ty);
34326 const union_obj = mod.typeToUnion(ty).?;
3430234327 switch (union_obj.status) {
3430334328 .none, .have_field_types, .field_types_wip, .layout_wip, .have_layout => {},
3430434329 .fully_resolved_wip, .fully_resolved => return,
......@@ -34322,7 +34347,7 @@ fn resolveUnionFully(sema: *Sema, ty: Type) CompileError!void {
3432234347 _ = try sema.typeRequiresComptime(ty);
3432334348}
3432434349
34325pub fn resolveTypeFields(sema: *Sema, ty: Type) CompileError!Type {
34350pub fn resolveTypeFields(sema: *Sema, ty: Type) CompileError!void {
3432634351 const mod = sema.mod;
3432734352
3432834353 switch (ty.toIntern()) {
......@@ -34385,7 +34410,7 @@ pub fn resolveTypeFields(sema: *Sema, ty: Type) CompileError!Type {
3438534410 .anyerror_void_error_union_type,
3438634411 .generic_poison_type,
3438734412 .empty_struct_type,
34388 => return ty,
34413 => {},
3438934414
3439034415 .undef => unreachable,
3439134416 .zero => unreachable,
......@@ -34406,42 +34431,52 @@ pub fn resolveTypeFields(sema: *Sema, ty: Type) CompileError!Type {
3440634431 .empty_struct => unreachable,
3440734432 .generic_poison => unreachable,
3440834433
34409 .type_info_type => return sema.getBuiltinType("Type"),
34410 .extern_options_type => return sema.getBuiltinType("ExternOptions"),
34411 .export_options_type => return sema.getBuiltinType("ExportOptions"),
34412 .atomic_order_type => return sema.getBuiltinType("AtomicOrder"),
34413 .atomic_rmw_op_type => return sema.getBuiltinType("AtomicRmwOp"),
34414 .calling_convention_type => return sema.getBuiltinType("CallingConvention"),
34415 .address_space_type => return sema.getBuiltinType("AddressSpace"),
34416 .float_mode_type => return sema.getBuiltinType("FloatMode"),
34417 .reduce_op_type => return sema.getBuiltinType("ReduceOp"),
34418 .call_modifier_type => return sema.getBuiltinType("CallModifier"),
34419 .prefetch_options_type => return sema.getBuiltinType("PrefetchOptions"),
34420
34421 _ => switch (mod.intern_pool.items.items(.tag)[@intFromEnum(ty.toIntern())]) {
34434 else => switch (mod.intern_pool.items.items(.tag)[@intFromEnum(ty.toIntern())]) {
3442234435 .type_struct,
3442334436 .type_struct_ns,
3442434437 .type_union_tagged,
3442534438 .type_union_untagged,
3442634439 .type_union_safety,
34440 .simple_type,
3442734441 => switch (mod.intern_pool.indexToKey(ty.toIntern())) {
3442834442 .struct_type => |struct_type| {
34429 const struct_obj = mod.structPtrUnwrap(struct_type.index) orelse return ty;
34443 const struct_obj = mod.structPtrUnwrap(struct_type.index) orelse return;
3443034444 try sema.resolveTypeFieldsStruct(ty, struct_obj);
34431 return ty;
3443234445 },
3443334446 .union_type => |union_type| {
3443434447 const union_obj = mod.unionPtr(union_type.index);
3443534448 try sema.resolveTypeFieldsUnion(ty, union_obj);
34436 return ty;
3443734449 },
34450 .simple_type => |simple_type| try sema.resolveSimpleType(simple_type),
3443834451 else => unreachable,
3443934452 },
34440 else => return ty,
34453 else => {},
3444134454 },
3444234455 }
3444334456}
3444434457
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
3444534480fn resolveTypeFieldsStruct(
3444634481 sema: *Sema,
3444734482 ty: Type,
......@@ -35784,7 +35819,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
3578435819 },
3578535820
3578635821 .struct_type => |struct_type| {
35787 const resolved_ty = try sema.resolveTypeFields(ty);
35822 try sema.resolveTypeFields(ty);
3578835823 if (mod.structPtrUnwrap(struct_type.index)) |s| {
3578935824 const field_vals = try sema.arena.alloc(InternPool.Index, s.fields.count());
3579035825 for (field_vals, s.fields.values(), 0..) |*field_val, field, i| {
......@@ -35792,14 +35827,14 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
3579235827 field_val.* = field.default_val;
3579335828 continue;
3579435829 }
35795 if (field.ty.eql(resolved_ty, sema.mod)) {
35830 if (field.ty.eql(ty, sema.mod)) {
3579635831 const msg = try Module.ErrorMsg.create(
3579735832 sema.gpa,
3579835833 s.srcLoc(sema.mod),
3579935834 "struct '{}' depends on itself",
3580035835 .{ty.fmt(sema.mod)},
3580135836 );
35802 try sema.addFieldErrNote(resolved_ty, i, msg, "while checking this field", .{});
35837 try sema.addFieldErrNote(ty, i, msg, "while checking this field", .{});
3580335838 return sema.failWithOwnedErrorMsg(msg);
3580435839 }
3580535840 if (try sema.typeHasOnePossibleValue(field.ty)) |field_opv| {
......@@ -35837,7 +35872,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
3583735872 },
3583835873
3583935874 .union_type => |union_type| {
35840 const resolved_ty = try sema.resolveTypeFields(ty);
35875 try sema.resolveTypeFields(ty);
3584135876 const union_obj = mod.unionPtr(union_type.index);
3584235877 const tag_val = (try sema.typeHasOnePossibleValue(union_obj.tag_ty)) orelse
3584335878 return null;
......@@ -35847,20 +35882,20 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
3584735882 return only.toValue();
3584835883 }
3584935884 const only_field = fields[0];
35850 if (only_field.ty.eql(resolved_ty, sema.mod)) {
35885 if (only_field.ty.eql(ty, sema.mod)) {
3585135886 const msg = try Module.ErrorMsg.create(
3585235887 sema.gpa,
3585335888 union_obj.srcLoc(sema.mod),
3585435889 "union '{}' depends on itself",
3585535890 .{ty.fmt(sema.mod)},
3585635891 );
35857 try sema.addFieldErrNote(resolved_ty, 0, msg, "while checking this field", .{});
35892 try sema.addFieldErrNote(ty, 0, msg, "while checking this field", .{});
3585835893 return sema.failWithOwnedErrorMsg(msg);
3585935894 }
3586035895 const val_val = (try sema.typeHasOnePossibleValue(only_field.ty)) orelse
3586135896 return null;
3586235897 const only = try mod.intern(.{ .un = .{
35863 .ty = resolved_ty.toIntern(),
35898 .ty = ty.toIntern(),
3586435899 .tag = tag_val.toIntern(),
3586535900 .val = val_val.toIntern(),
3586635901 } });
......@@ -36430,12 +36465,12 @@ pub fn fnHasRuntimeBits(sema: *Sema, ty: Type) CompileError!bool {
3643036465fn unionFieldIndex(
3643136466 sema: *Sema,
3643236467 block: *Block,
36433 unresolved_union_ty: Type,
36468 union_ty: Type,
3643436469 field_name: InternPool.NullTerminatedString,
3643536470 field_src: LazySrcLoc,
3643636471) !u32 {
3643736472 const mod = sema.mod;
36438 const union_ty = try sema.resolveTypeFields(unresolved_union_ty);
36473 try sema.resolveTypeFields(union_ty);
3643936474 const union_obj = mod.typeToUnion(union_ty).?;
3644036475 const field_index_usize = union_obj.fields.getIndex(field_name) orelse
3644136476 return sema.failWithBadUnionFieldAccess(block, union_obj, field_src, field_name);
......@@ -36445,12 +36480,12 @@ fn unionFieldIndex(
3644536480fn structFieldIndex(
3644636481 sema: *Sema,
3644736482 block: *Block,
36448 unresolved_struct_ty: Type,
36483 struct_ty: Type,
3644936484 field_name: InternPool.NullTerminatedString,
3645036485 field_src: LazySrcLoc,
3645136486) !u32 {
3645236487 const mod = sema.mod;
36453 const struct_ty = try sema.resolveTypeFields(unresolved_struct_ty);
36488 try sema.resolveTypeFields(struct_ty);
3645436489 if (struct_ty.isAnonStruct(mod)) {
3645536490 return sema.anonStructFieldIndex(block, struct_ty, field_name, field_src);
3645636491 } 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