From 836d8a1f64cb811641e621799429c54f222717eb Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Wed, 3 May 2023 18:11:07 -0700 Subject: [PATCH] stage2: move most simple types to InternPool --- src/Air.zig | 4 +- src/Module.zig | 53 +-- src/Sema.zig | 509 ++++++++++-------------- src/arch/aarch64/CodeGen.zig | 7 +- src/arch/arm/CodeGen.zig | 7 +- src/arch/sparc64/CodeGen.zig | 2 +- src/arch/wasm/CodeGen.zig | 10 +- src/arch/x86_64/CodeGen.zig | 8 +- src/codegen/c.zig | 16 +- src/codegen/llvm.zig | 38 +- src/codegen/spirv.zig | 6 +- src/print_air.zig | 1 - src/type.zig | 737 +++++++---------------------------- src/value.zig | 28 +- 14 files changed, 438 insertions(+), 988 deletions(-) diff --git a/src/Air.zig b/src/Air.zig index be3ae119e4..1bc9d949e2 100644 --- a/src/Air.zig +++ b/src/Air.zig @@ -1333,7 +1333,7 @@ pub fn typeOfIndex(air: Air, inst: Air.Inst.Index, ip: InternPool) Type { .ret_load, .unreach, .trap, - => return Type.initTag(.noreturn), + => return Type.noreturn, .breakpoint, .dbg_stmt, @@ -1370,7 +1370,7 @@ pub fn typeOfIndex(air: Air, inst: Air.Inst.Index, ip: InternPool) Type { .wasm_memory_grow => return Type.i32, .wasm_memory_size => return Type.u32, - .bool_to_int => return Type.initTag(.u1), + .bool_to_int => return Type.u1, .tag_name, .error_name => return Type.initTag(.const_slice_u8_sentinel_0), diff --git a/src/Module.zig b/src/Module.zig index a4ae107bed..77c20fbcc6 100644 --- a/src/Module.zig +++ b/src/Module.zig @@ -1005,7 +1005,7 @@ pub const Struct = struct { /// If the layout is packed, this is the backing integer type of the packed struct. /// Whether zig chooses this type or the user specifies it, it is stored here. /// This will be set to the noreturn type until status is `have_layout`. - backing_int_ty: Type = Type.initTag(.noreturn), + backing_int_ty: Type = Type.noreturn, status: enum { none, field_types_wip, @@ -1705,31 +1705,34 @@ pub const Fn = struct { is_resolved: bool = false, pub fn addErrorSet(self: *InferredErrorSet, gpa: Allocator, err_set_ty: Type) !void { - switch (err_set_ty.tag()) { - .error_set => { - const names = err_set_ty.castTag(.error_set).?.data.names.keys(); - for (names) |name| { - try self.errors.put(gpa, name, {}); - } - }, - .error_set_single => { - const name = err_set_ty.castTag(.error_set_single).?.data; - try self.errors.put(gpa, name, {}); - }, - .error_set_inferred => { - const ies = err_set_ty.castTag(.error_set_inferred).?.data; - try self.inferred_error_sets.put(gpa, ies, {}); - }, - .error_set_merged => { - const names = err_set_ty.castTag(.error_set_merged).?.data.keys(); - for (names) |name| { - try self.errors.put(gpa, name, {}); - } - }, - .anyerror => { + switch (err_set_ty.ip_index) { + .anyerror_type => { self.is_anyerror = true; }, - else => unreachable, + .none => switch (err_set_ty.tag()) { + .error_set => { + const names = err_set_ty.castTag(.error_set).?.data.names.keys(); + for (names) |name| { + try self.errors.put(gpa, name, {}); + } + }, + .error_set_single => { + const name = err_set_ty.castTag(.error_set_single).?.data; + try self.errors.put(gpa, name, {}); + }, + .error_set_inferred => { + const ies = err_set_ty.castTag(.error_set_inferred).?.data; + try self.inferred_error_sets.put(gpa, ies, {}); + }, + .error_set_merged => { + const names = err_set_ty.castTag(.error_set_merged).?.data.keys(); + for (names) |name| { + try self.errors.put(gpa, name, {}); + } + }, + else => unreachable, + }, + else => @panic("TODO"), } } }; @@ -4566,7 +4569,7 @@ pub fn semaFile(mod: *Module, file: *File) SemaError!void { const struct_obj = try new_decl_arena_allocator.create(Module.Struct); const struct_ty = try Type.Tag.@"struct".create(new_decl_arena_allocator, struct_obj); const struct_val = try Value.Tag.ty.create(new_decl_arena_allocator, struct_ty); - const ty_ty = comptime Type.initTag(.type); + const ty_ty = comptime Type.type; struct_obj.* = .{ .owner_decl = undefined, // set below .fields = .{}, diff --git a/src/Sema.zig b/src/Sema.zig index d03460385e..ea8258717b 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -1776,7 +1776,7 @@ fn analyzeAsType( src: LazySrcLoc, air_inst: Air.Inst.Ref, ) !Type { - const wanted_type = Type.initTag(.type); + const wanted_type = Type.type; const coerced_inst = try sema.coerce(block, wanted_type, air_inst, src); const val = try sema.resolveConstValue(block, src, coerced_inst, "types must be comptime-known"); const ty = val.toType(); @@ -3132,7 +3132,7 @@ fn zirUnionDecl( errdefer mod.abortAnonDecl(new_decl_index); union_obj.* = .{ .owner_decl = new_decl_index, - .tag_ty = Type.initTag(.null), + .tag_ty = Type.null, .fields = .{}, .zir_index = inst, .layout = small.layout, @@ -6362,7 +6362,7 @@ fn zirCall( if (arg_index >= fn_params_len) break :inst Air.Inst.Ref.var_args_param_type; - if (func_ty_info.param_types[arg_index].tag() == .generic_poison) + if (func_ty_info.param_types[arg_index].isGenericPoison()) break :inst Air.Inst.Ref.generic_poison_type; break :inst try sema.addType(func_ty_info.param_types[arg_index]); @@ -8175,7 +8175,7 @@ fn zirMergeErrorSets(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr return sema.fail(block, rhs_src, "expected error set type, found '{}'", .{rhs_ty.fmt(sema.mod)}); // Anything merged with anyerror is anyerror. - if (lhs_ty.tag() == .anyerror or rhs_ty.tag() == .anyerror) { + if (lhs_ty.ip_index == .anyerror_type or rhs_ty.ip_index == .anyerror_type) { return Air.Inst.Ref.anyerror_type; } @@ -8206,7 +8206,7 @@ fn zirEnumLiteral(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError const inst_data = sema.code.instructions.items(.data)[inst].str_tok; const duped_name = try sema.arena.dupe(u8, inst_data.get(sema.code)); return sema.addConstant( - Type.initTag(.enum_literal), + .{ .ip_index = .enum_literal_type, .legacy = undefined }, try Value.Tag.enum_literal.create(sema.arena, duped_name), ); } @@ -8503,6 +8503,7 @@ fn analyzeErrUnionPayload( operand_src: LazySrcLoc, safety_check: bool, ) CompileError!Air.Inst.Ref { + const mod = sema.mod; const payload_ty = err_union_ty.errorUnionPayload(); if (try sema.resolveDefinedValue(block, operand_src, operand)) |val| { if (val.getError()) |name| { @@ -8516,7 +8517,7 @@ fn analyzeErrUnionPayload( // If the error set has no fields then no safety check is needed. if (safety_check and block.wantSafety() and - !err_union_ty.errorUnionSet().errorSetIsEmpty()) + !err_union_ty.errorUnionSet().errorSetIsEmpty(mod)) { try sema.panicUnwrapError(block, operand, .unwrap_errunion_err, .is_non_err); } @@ -8602,7 +8603,7 @@ fn analyzeErrUnionPayloadPtr( // If the error set has no fields then no safety check is needed. if (safety_check and block.wantSafety() and - !err_union_ty.errorUnionSet().errorSetIsEmpty()) + !err_union_ty.errorUnionSet().errorSetIsEmpty(mod)) { try sema.panicUnwrapError(block, operand, .unwrap_errunion_err_ptr, .is_non_err_ptr); } @@ -8701,7 +8702,7 @@ fn zirFunc( break :blk ret_ty; } else |err| switch (err) { error.GenericPoison => { - break :blk Type.initTag(.generic_poison); + break :blk Type.generic_poison; }, else => |e| return e, } @@ -8778,7 +8779,7 @@ fn resolveGenericBody( }; switch (err) { error.GenericPoison => { - if (dest_ty.tag() == .type) { + if (dest_ty.ip_index == .type_type) { return Value.initTag(.generic_poison_type); } else { return Value.initTag(.generic_poison); @@ -9319,7 +9320,7 @@ fn zirParam( // We result the param instruction with a poison value and // insert an anytype parameter. try block.params.append(sema.gpa, .{ - .ty = Type.initTag(.generic_poison), + .ty = Type.generic_poison, .is_comptime = comptime_syntax, .name = param_name, }); @@ -9340,7 +9341,7 @@ fn zirParam( // We result the param instruction with a poison value and // insert an anytype parameter. try block.params.append(sema.gpa, .{ - .ty = Type.initTag(.generic_poison), + .ty = Type.generic_poison, .is_comptime = comptime_syntax, .name = param_name, }); @@ -9438,7 +9439,7 @@ fn zirParamAnytype( // We are evaluating a generic function without any comptime args provided. try block.params.append(sema.gpa, .{ - .ty = Type.initTag(.generic_poison), + .ty = Type.generic_poison, .is_comptime = comptime_syntax, .name = param_name, }); @@ -18877,7 +18878,7 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in }, .ErrorSet => { const payload_val = union_val.val.optionalValue(mod) orelse - return sema.addType(Type.initTag(.anyerror)); + return sema.addType(Type.anyerror); const slice_val = payload_val.castTag(.slice).?.data; const len = try sema.usizeCast(block, src, slice_val.len.toUnsignedInt(mod)); @@ -19150,7 +19151,7 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in errdefer mod.abortAnonDecl(new_decl_index); union_obj.* = .{ .owner_decl = new_decl_index, - .tag_ty = Type.initTag(.null), + .tag_ty = Type.null, .fields = .{}, .zir_index = inst, .layout = layout, @@ -22697,7 +22698,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A extra_index += 1; const ret_ty_tv = sema.resolveInstConst(block, ret_src, ret_ty_ref, "return type must be comptime-known") catch |err| switch (err) { error.GenericPoison => { - break :blk Type.initTag(.generic_poison); + break :blk Type.generic_poison; }, else => |e| return e, }; @@ -23022,7 +23023,7 @@ fn zirBuiltinExtern( new_decl.src_line = sema.owner_decl.src_line; // We only access this decl through the decl_ref with the correct type created // below, so this type doesn't matter - new_decl.ty = Type.Tag.init(.anyopaque); + new_decl.ty = Type.anyopaque; new_decl.val = try Value.Tag.variable.create(new_decl_arena_allocator, new_var); new_decl.@"align" = 0; new_decl.@"linksection" = null; @@ -24380,9 +24381,8 @@ fn fieldCallBind( decl_type.fnParamLen() >= 1) { const first_param_type = decl_type.fnParamType(0); - const first_param_tag = first_param_type.tag(); // zig fmt: off - if (first_param_tag == .generic_poison or ( + if (first_param_type.isGenericPoison() or ( first_param_type.zigTypeTag(mod) == .Pointer and (first_param_type.ptrSize() == .One or first_param_type.ptrSize() == .C) and @@ -25535,10 +25535,7 @@ fn coerceExtra( inst_src: LazySrcLoc, opts: CoerceOpts, ) CoersionError!Air.Inst.Ref { - switch (dest_ty_unresolved.tag()) { - .generic_poison => return inst, - else => {}, - } + if (dest_ty_unresolved.isGenericPoison()) return inst; const dest_ty_src = inst_src; // TODO better source location const dest_ty = try sema.resolveTypeFields(dest_ty_unresolved); const inst_ty = try sema.resolveTypeFields(sema.typeOf(inst)); @@ -25577,7 +25574,8 @@ fn coerceExtra( // cast from ?*T and ?[*]T to ?*anyopaque // but don't do it if the source type is a double pointer - if (dest_ty.isPtrLikeOptional(mod) and dest_ty.elemType2(mod).tag() == .anyopaque and + if (dest_ty.isPtrLikeOptional(mod) and + dest_ty.elemType2(mod).ip_index == .anyopaque_type and inst_ty.isPtrAtRuntime(mod)) anyopaque_check: { if (!sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result)) break :optional; @@ -25715,7 +25713,7 @@ fn coerceExtra( // cast from *T and [*]T to *anyopaque // but don't do it if the source type is a double pointer - if (dest_info.pointee_type.tag() == .anyopaque and inst_ty.zigTypeTag(mod) == .Pointer) to_anyopaque: { + if (dest_info.pointee_type.ip_index == .anyopaque_type and inst_ty.zigTypeTag(mod) == .Pointer) to_anyopaque: { if (!sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result)) break :pointer; const elem_ty = inst_ty.elemType2(mod); if (elem_ty.zigTypeTag(mod) == .Pointer or elem_ty.isPtrLikeOptional(mod)) { @@ -26759,6 +26757,8 @@ fn coerceInMemoryAllowedErrorSets( dest_src: LazySrcLoc, src_src: LazySrcLoc, ) !InMemoryCoercionResult { + const mod = sema.mod; + // Coercion to `anyerror`. Note that this check can return false negatives // in case the error sets did not get resolved. if (dest_ty.isAnyError()) { @@ -26769,36 +26769,41 @@ fn coerceInMemoryAllowedErrorSets( const dst_ies = dst_payload.data; // We will make an effort to return `ok` without resolving either error set, to // avoid unnecessary "unable to resolve error set" dependency loop errors. - switch (src_ty.tag()) { - .error_set_inferred => { - // If both are inferred error sets of functions, and - // the dest includes the source function, the coercion is OK. - // This check is important because it works without forcing a full resolution - // of inferred error sets. - const src_ies = src_ty.castTag(.error_set_inferred).?.data; + switch (src_ty.ip_index) { + .none => switch (src_ty.tag()) { + .error_set_inferred => { + // If both are inferred error sets of functions, and + // the dest includes the source function, the coercion is OK. + // This check is important because it works without forcing a full resolution + // of inferred error sets. + const src_ies = src_ty.castTag(.error_set_inferred).?.data; - if (dst_ies.inferred_error_sets.contains(src_ies)) { - return .ok; - } + if (dst_ies.inferred_error_sets.contains(src_ies)) { + return .ok; + } + }, + .error_set_single => { + const name = src_ty.castTag(.error_set_single).?.data; + if (dst_ies.errors.contains(name)) return .ok; + }, + .error_set_merged => { + const names = src_ty.castTag(.error_set_merged).?.data.keys(); + for (names) |name| { + if (!dst_ies.errors.contains(name)) break; + } else return .ok; + }, + .error_set => { + const names = src_ty.castTag(.error_set).?.data.names.keys(); + for (names) |name| { + if (!dst_ies.errors.contains(name)) break; + } else return .ok; + }, + else => unreachable, }, - .error_set_single => { - const name = src_ty.castTag(.error_set_single).?.data; - if (dst_ies.errors.contains(name)) return .ok; + .anyerror_type => {}, + else => switch (mod.intern_pool.indexToKey(src_ty.ip_index)) { + else => @panic("TODO"), }, - .error_set_merged => { - const names = src_ty.castTag(.error_set_merged).?.data.keys(); - for (names) |name| { - if (!dst_ies.errors.contains(name)) break; - } else return .ok; - }, - .error_set => { - const names = src_ty.castTag(.error_set).?.data.names.keys(); - for (names) |name| { - if (!dst_ies.errors.contains(name)) break; - } else return .ok; - }, - .anyerror => {}, - else => unreachable, } if (dst_ies.func == sema.owner_func) { @@ -26818,79 +26823,87 @@ fn coerceInMemoryAllowedErrorSets( var missing_error_buf = std.ArrayList([]const u8).init(sema.gpa); defer missing_error_buf.deinit(); - switch (src_ty.tag()) { - .error_set_inferred => { - const src_data = src_ty.castTag(.error_set_inferred).?.data; + switch (src_ty.ip_index) { + .none => switch (src_ty.tag()) { + .error_set_inferred => { + const src_data = src_ty.castTag(.error_set_inferred).?.data; - try sema.resolveInferredErrorSet(block, src_src, src_data); - // src anyerror status might have changed after the resolution. - if (src_ty.isAnyError()) { - // dest_ty.isAnyError() == true is already checked for at this point. - return .from_anyerror; - } - - for (src_data.errors.keys()) |key| { - if (!dest_ty.errorSetHasField(key)) { - try missing_error_buf.append(key); + try sema.resolveInferredErrorSet(block, src_src, src_data); + // src anyerror status might have changed after the resolution. + if (src_ty.isAnyError()) { + // dest_ty.isAnyError() == true is already checked for at this point. + return .from_anyerror; } - } - if (missing_error_buf.items.len != 0) { - return InMemoryCoercionResult{ - .missing_error = try sema.arena.dupe([]const u8, missing_error_buf.items), - }; - } + for (src_data.errors.keys()) |key| { + if (!dest_ty.errorSetHasField(key)) { + try missing_error_buf.append(key); + } + } + + if (missing_error_buf.items.len != 0) { + return InMemoryCoercionResult{ + .missing_error = try sema.arena.dupe([]const u8, missing_error_buf.items), + }; + } - return .ok; - }, - .error_set_single => { - const name = src_ty.castTag(.error_set_single).?.data; - if (dest_ty.errorSetHasField(name)) { return .ok; - } - const list = try sema.arena.alloc([]const u8, 1); - list[0] = name; - return InMemoryCoercionResult{ .missing_error = list }; - }, - .error_set_merged => { - const names = src_ty.castTag(.error_set_merged).?.data.keys(); - for (names) |name| { - if (!dest_ty.errorSetHasField(name)) { - try missing_error_buf.append(name); + }, + .error_set_single => { + const name = src_ty.castTag(.error_set_single).?.data; + if (dest_ty.errorSetHasField(name)) { + return .ok; } - } - - if (missing_error_buf.items.len != 0) { - return InMemoryCoercionResult{ - .missing_error = try sema.arena.dupe([]const u8, missing_error_buf.items), - }; - } - - return .ok; - }, - .error_set => { - const names = src_ty.castTag(.error_set).?.data.names.keys(); - for (names) |name| { - if (!dest_ty.errorSetHasField(name)) { - try missing_error_buf.append(name); + const list = try sema.arena.alloc([]const u8, 1); + list[0] = name; + return InMemoryCoercionResult{ .missing_error = list }; + }, + .error_set_merged => { + const names = src_ty.castTag(.error_set_merged).?.data.keys(); + for (names) |name| { + if (!dest_ty.errorSetHasField(name)) { + try missing_error_buf.append(name); + } } - } - if (missing_error_buf.items.len != 0) { - return InMemoryCoercionResult{ - .missing_error = try sema.arena.dupe([]const u8, missing_error_buf.items), - }; - } + if (missing_error_buf.items.len != 0) { + return InMemoryCoercionResult{ + .missing_error = try sema.arena.dupe([]const u8, missing_error_buf.items), + }; + } - return .ok; - }, - .anyerror => switch (dest_ty.tag()) { - .error_set_inferred => unreachable, // Caught by dest_ty.isAnyError() above. - .error_set_single, .error_set_merged, .error_set => return .from_anyerror, - .anyerror => unreachable, // Filtered out above. + return .ok; + }, + .error_set => { + const names = src_ty.castTag(.error_set).?.data.names.keys(); + for (names) |name| { + if (!dest_ty.errorSetHasField(name)) { + try missing_error_buf.append(name); + } + } + + if (missing_error_buf.items.len != 0) { + return InMemoryCoercionResult{ + .missing_error = try sema.arena.dupe([]const u8, missing_error_buf.items), + }; + } + + return .ok; + }, else => unreachable, }, - else => unreachable, + + .anyerror_type => switch (dest_ty.ip_index) { + .none => switch (dest_ty.tag()) { + .error_set_inferred => unreachable, // Caught by dest_ty.isAnyError() above. + .error_set_single, .error_set_merged, .error_set => return .from_anyerror, + else => unreachable, + }, + .anyerror_type => unreachable, // Filtered out above. + else => @panic("TODO"), + }, + + else => @panic("TODO"), } unreachable; @@ -29355,42 +29368,49 @@ fn analyzeIsNonErrComptimeOnly( // exception if the error union error set is known to be empty, // we allow the comparison but always make it comptime-known. const set_ty = operand_ty.errorUnionSet(); - switch (set_ty.tag()) { - .anyerror => {}, - .error_set_inferred => blk: { - // If the error set is empty, we must return a comptime true or false. - // However we want to avoid unnecessarily resolving an inferred error set - // in case it is already non-empty. - const ies = set_ty.castTag(.error_set_inferred).?.data; - if (ies.is_anyerror) break :blk; - if (ies.errors.count() != 0) break :blk; - if (maybe_operand_val == null) { - // Try to avoid resolving inferred error set if possible. + switch (set_ty.ip_index) { + .none => switch (set_ty.tag()) { + .error_set_inferred => blk: { + // If the error set is empty, we must return a comptime true or false. + // However we want to avoid unnecessarily resolving an inferred error set + // in case it is already non-empty. + const ies = set_ty.castTag(.error_set_inferred).?.data; + if (ies.is_anyerror) break :blk; if (ies.errors.count() != 0) break :blk; - if (ies.is_anyerror) break :blk; - for (ies.inferred_error_sets.keys()) |other_ies| { - if (ies == other_ies) continue; - try sema.resolveInferredErrorSet(block, src, other_ies); - if (other_ies.is_anyerror) { - ies.is_anyerror = true; - ies.is_resolved = true; - break :blk; - } + if (maybe_operand_val == null) { + // Try to avoid resolving inferred error set if possible. + if (ies.errors.count() != 0) break :blk; + if (ies.is_anyerror) break :blk; + for (ies.inferred_error_sets.keys()) |other_ies| { + if (ies == other_ies) continue; + try sema.resolveInferredErrorSet(block, src, other_ies); + if (other_ies.is_anyerror) { + ies.is_anyerror = true; + ies.is_resolved = true; + break :blk; + } - if (other_ies.errors.count() != 0) break :blk; + if (other_ies.errors.count() != 0) break :blk; + } + if (ies.func == sema.owner_func) { + // We're checking the inferred errorset of the current function and none of + // its child inferred error sets contained any errors meaning that any value + // so far with this type can't contain errors either. + return Air.Inst.Ref.bool_true; + } + try sema.resolveInferredErrorSet(block, src, ies); + if (ies.is_anyerror) break :blk; + if (ies.errors.count() == 0) return Air.Inst.Ref.bool_true; } - if (ies.func == sema.owner_func) { - // We're checking the inferred errorset of the current function and none of - // its child inferred error sets contained any errors meaning that any value - // so far with this type can't contain errors either. - return Air.Inst.Ref.bool_true; - } - try sema.resolveInferredErrorSet(block, src, ies); - if (ies.is_anyerror) break :blk; - if (ies.errors.count() == 0) return Air.Inst.Ref.bool_true; - } + }, + else => if (set_ty.errorSetNames().len == 0) return Air.Inst.Ref.bool_true, + }, + + .anyerror_type => {}, + + else => switch (mod.intern_pool.indexToKey(set_ty.ip_index)) { + else => @panic("TODO"), }, - else => if (set_ty.errorSetNames().len == 0) return Air.Inst.Ref.bool_true, } if (maybe_operand_val) |err_union| { @@ -30308,43 +30328,48 @@ fn wrapErrorUnionSet( const inst_ty = sema.typeOf(inst); const dest_err_set_ty = dest_ty.errorUnionSet(); if (try sema.resolveMaybeUndefVal(inst)) |val| { - switch (dest_err_set_ty.tag()) { - .anyerror => {}, - .error_set_single => ok: { - const expected_name = val.castTag(.@"error").?.data.name; - const n = dest_err_set_ty.castTag(.error_set_single).?.data; - if (mem.eql(u8, expected_name, n)) break :ok; - return sema.failWithErrorSetCodeMissing(block, inst_src, dest_err_set_ty, inst_ty); - }, - .error_set => { - const expected_name = val.castTag(.@"error").?.data.name; - const error_set = dest_err_set_ty.castTag(.error_set).?.data; - if (!error_set.names.contains(expected_name)) { - return sema.failWithErrorSetCodeMissing(block, inst_src, dest_err_set_ty, inst_ty); - } - }, - .error_set_inferred => ok: { - const expected_name = val.castTag(.@"error").?.data.name; - const ies = dest_err_set_ty.castTag(.error_set_inferred).?.data; + switch (dest_err_set_ty.ip_index) { + .anyerror_type => {}, - // We carefully do this in an order that avoids unnecessarily - // resolving the destination error set type. - if (ies.is_anyerror) break :ok; - if (ies.errors.contains(expected_name)) break :ok; - if (.ok == try sema.coerceInMemoryAllowedErrorSets(block, dest_err_set_ty, inst_ty, inst_src, inst_src)) { - break :ok; - } - - return sema.failWithErrorSetCodeMissing(block, inst_src, dest_err_set_ty, inst_ty); - }, - .error_set_merged => { - const expected_name = val.castTag(.@"error").?.data.name; - const error_set = dest_err_set_ty.castTag(.error_set_merged).?.data; - if (!error_set.contains(expected_name)) { + .none => switch (dest_err_set_ty.tag()) { + .error_set_single => ok: { + const expected_name = val.castTag(.@"error").?.data.name; + const n = dest_err_set_ty.castTag(.error_set_single).?.data; + if (mem.eql(u8, expected_name, n)) break :ok; return sema.failWithErrorSetCodeMissing(block, inst_src, dest_err_set_ty, inst_ty); - } + }, + .error_set => { + const expected_name = val.castTag(.@"error").?.data.name; + const error_set = dest_err_set_ty.castTag(.error_set).?.data; + if (!error_set.names.contains(expected_name)) { + return sema.failWithErrorSetCodeMissing(block, inst_src, dest_err_set_ty, inst_ty); + } + }, + .error_set_inferred => ok: { + const expected_name = val.castTag(.@"error").?.data.name; + const ies = dest_err_set_ty.castTag(.error_set_inferred).?.data; + + // We carefully do this in an order that avoids unnecessarily + // resolving the destination error set type. + if (ies.is_anyerror) break :ok; + if (ies.errors.contains(expected_name)) break :ok; + if (.ok == try sema.coerceInMemoryAllowedErrorSets(block, dest_err_set_ty, inst_ty, inst_src, inst_src)) { + break :ok; + } + + return sema.failWithErrorSetCodeMissing(block, inst_src, dest_err_set_ty, inst_ty); + }, + .error_set_merged => { + const expected_name = val.castTag(.@"error").?.data.name; + const error_set = dest_err_set_ty.castTag(.error_set_merged).?.data; + if (!error_set.contains(expected_name)) { + return sema.failWithErrorSetCodeMissing(block, inst_src, dest_err_set_ty, inst_ty); + } + }, + else => unreachable, }, - else => unreachable, + + else => @panic("TODO"), } return sema.addConstant(dest_ty, val); } @@ -30380,7 +30405,7 @@ fn resolvePeerTypes( ) !Type { const mod = sema.mod; switch (instructions.len) { - 0 => return Type.initTag(.noreturn), + 0 => return Type.noreturn, 1 => return sema.typeOf(instructions[0]), else => {}, } @@ -31445,24 +31470,7 @@ pub fn resolveTypeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool { .i64, .u128, .i128, - .anyopaque, - .bool, - .void, - .anyerror, - .noreturn, - .@"anyframe", - .null, - .undefined, - .atomic_order, - .atomic_rmw_op, - .calling_convention, - .address_space, - .float_mode, - .reduce_op, - .modifier, - .prefetch_options, - .export_options, - .extern_options, + .manyptr_u8, .manyptr_const_u8, .manyptr_const_u8_sentinel_0, @@ -31476,17 +31484,12 @@ pub fn resolveTypeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool { .error_set_inferred, .error_set_merged, .@"opaque", - .generic_poison, .array_u8, .array_u8_sentinel_0, .enum_simple, => false, .single_const_pointer_to_comptime_int, - .type, - .comptime_int, - .enum_literal, - .type_info, .function, => true, @@ -31709,17 +31712,6 @@ pub fn resolveTypeFields(sema: *Sema, ty: Type) CompileError!Type { try sema.resolveTypeFieldsUnion(ty, union_obj); return ty; }, - .type_info => return sema.getBuiltinType("Type"), - .extern_options => return sema.getBuiltinType("ExternOptions"), - .export_options => return sema.getBuiltinType("ExportOptions"), - .atomic_order => return sema.getBuiltinType("AtomicOrder"), - .atomic_rmw_op => return sema.getBuiltinType("AtomicRmwOp"), - .calling_convention => return sema.getBuiltinType("CallingConvention"), - .address_space => return sema.getBuiltinType("AddressSpace"), - .float_mode => return sema.getBuiltinType("FloatMode"), - .reduce_op => return sema.getBuiltinType("ReduceOp"), - .modifier => return sema.getBuiltinType("CallModifier"), - .prefetch_options => return sema.getBuiltinType("PrefetchOptions"), else => return ty, }, @@ -31772,6 +31764,7 @@ pub fn resolveTypeFields(sema: *Sema, ty: Type) CompileError!Type { .const_slice_u8_type, .anyerror_void_error_union_type, .generic_poison_type, + .var_args_param_type, .empty_struct_type, => return ty, @@ -31789,7 +31782,6 @@ pub fn resolveTypeFields(sema: *Sema, ty: Type) CompileError!Type { .bool_false => unreachable, .empty_struct => unreachable, .generic_poison => unreachable, - .var_args_param_type => unreachable, .type_info_type => return sema.getBuiltinType("Type"), .extern_options_type => return sema.getBuiltinType("ExternOptions"), @@ -32118,7 +32110,7 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void return sema.failWithOwnedErrorMsg(msg); } gop.value_ptr.* = .{ - .ty = Type.initTag(.noreturn), + .ty = Type.noreturn, .abi_align = 0, .default_val = Value.initTag(.unreachable_value), .is_comptime = is_comptime, @@ -32552,7 +32544,7 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void { const field_ty: Type = if (!has_type) Type.void else if (field_type_ref == .none) - Type.initTag(.noreturn) + Type.noreturn else sema.resolveType(&block_scope, .unneeded, field_type_ref) catch |err| switch (err) { error.NeededSourceLocation => { @@ -32956,7 +32948,6 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value { }; switch (ty.tag()) { - .comptime_int, .u1, .u8, .i8, @@ -32969,9 +32960,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value { .i64, .u128, .i128, - .bool, - .type, - .anyerror, + .error_set_single, .error_set, .error_set_merged, @@ -32984,28 +32973,14 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value { .const_slice_u8_sentinel_0, .const_slice, .mut_slice, - .anyopaque, .optional_single_mut_pointer, .optional_single_const_pointer, - .enum_literal, .anyerror_void_error_union, .error_set_inferred, .@"opaque", .manyptr_u8, .manyptr_const_u8, .manyptr_const_u8_sentinel_0, - .atomic_order, - .atomic_rmw_op, - .calling_convention, - .address_space, - .float_mode, - .reduce_op, - .modifier, - .prefetch_options, - .export_options, - .extern_options, - .type_info, - .@"anyframe", .anyframe_T, .many_const_pointer, .many_mut_pointer, @@ -33138,10 +33113,6 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value { }, .empty_struct, .empty_struct_literal => return Value.initTag(.empty_struct_value), - .void => return Value.void, - .noreturn => return Value.initTag(.unreachable_value), - .null => return Value.null, - .undefined => return Value.initTag(.undef), .vector, .array, .array_u8 => { if (ty.arrayLen() == 0) @@ -33154,7 +33125,6 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value { .inferred_alloc_const => unreachable, .inferred_alloc_mut => unreachable, - .generic_poison => return error.GenericPoison, } } @@ -33194,34 +33164,12 @@ pub fn addType(sema: *Sema, ty: Type) !Air.Inst.Ref { .i64 => return .i64_type, .u128 => return .u128_type, .i128 => return .i128_type, - .anyopaque => return .anyopaque_type, - .bool => return .bool_type, - .void => return .void_type, - .type => return .type_type, - .anyerror => return .anyerror_type, - .comptime_int => return .comptime_int_type, - .noreturn => return .noreturn_type, - .@"anyframe" => return .anyframe_type, - .null => return .null_type, - .undefined => return .undefined_type, - .enum_literal => return .enum_literal_type, - .atomic_order => return .atomic_order_type, - .atomic_rmw_op => return .atomic_rmw_op_type, - .calling_convention => return .calling_convention_type, - .address_space => return .address_space_type, - .float_mode => return .float_mode_type, - .reduce_op => return .reduce_op_type, - .modifier => return .call_modifier_type, - .prefetch_options => return .prefetch_options_type, - .export_options => return .export_options_type, - .extern_options => return .extern_options_type, - .type_info => return .type_info_type, + .manyptr_u8 => return .manyptr_u8_type, .manyptr_const_u8 => return .manyptr_const_u8_type, .single_const_pointer_to_comptime_int => return .single_const_pointer_to_comptime_int_type, .const_slice_u8 => return .const_slice_u8_type, .anyerror_void_error_union => return .anyerror_void_error_union_type, - .generic_poison => return .generic_poison_type, else => {}, } try sema.air_instructions.append(sema.gpa, .{ @@ -33658,22 +33606,7 @@ pub fn typeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool { .i64, .u128, .i128, - .anyopaque, - .bool, - .void, - .anyerror, - .noreturn, - .@"anyframe", - .atomic_order, - .atomic_rmw_op, - .calling_convention, - .address_space, - .float_mode, - .reduce_op, - .modifier, - .prefetch_options, - .export_options, - .extern_options, + .manyptr_u8, .manyptr_const_u8, .manyptr_const_u8_sentinel_0, @@ -33687,19 +33620,12 @@ pub fn typeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool { .error_set_inferred, .error_set_merged, .@"opaque", - .generic_poison, .array_u8, .array_u8_sentinel_0, .enum_simple, => false, .single_const_pointer_to_comptime_int, - .type, - .comptime_int, - .enum_literal, - .null, - .undefined, - .type_info, .function, => true, @@ -34476,17 +34402,6 @@ fn enumHasInt(sema: *Sema, ty: Type, int: Value) CompileError!bool { const tag_ty = try mod.intType(.unsigned, bits); return sema.intInRange(tag_ty, int, fields_len); }, - .atomic_order, - .atomic_rmw_op, - .calling_convention, - .address_space, - .float_mode, - .reduce_op, - .modifier, - .prefetch_options, - .export_options, - .extern_options, - => unreachable, else => unreachable, } diff --git a/src/arch/aarch64/CodeGen.zig b/src/arch/aarch64/CodeGen.zig index 4671866197..7098cf3f32 100644 --- a/src/arch/aarch64/CodeGen.zig +++ b/src/arch/aarch64/CodeGen.zig @@ -3071,7 +3071,7 @@ fn errUnionErr( const mod = self.bin_file.options.module.?; const err_ty = error_union_ty.errorUnionSet(); const payload_ty = error_union_ty.errorUnionPayload(); - if (err_ty.errorSetIsEmpty()) { + if (err_ty.errorSetIsEmpty(mod)) { return MCValue{ .immediate = 0 }; } if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) { @@ -3151,7 +3151,7 @@ fn errUnionPayload( const mod = self.bin_file.options.module.?; const err_ty = error_union_ty.errorUnionSet(); const payload_ty = error_union_ty.errorUnionPayload(); - if (err_ty.errorSetIsEmpty()) { + if (err_ty.errorSetIsEmpty(mod)) { return try error_union_bind.resolveToMcv(self); } if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) { @@ -4905,9 +4905,10 @@ fn isErr( error_union_bind: ReadArg.Bind, error_union_ty: Type, ) !MCValue { + const mod = self.bin_file.options.module.?; const error_type = error_union_ty.errorUnionSet(); - if (error_type.errorSetIsEmpty()) { + if (error_type.errorSetIsEmpty(mod)) { return MCValue{ .immediate = 0 }; // always false } diff --git a/src/arch/arm/CodeGen.zig b/src/arch/arm/CodeGen.zig index ca4a3826aa..bf94cf55a0 100644 --- a/src/arch/arm/CodeGen.zig +++ b/src/arch/arm/CodeGen.zig @@ -2047,7 +2047,7 @@ fn errUnionErr( const mod = self.bin_file.options.module.?; const err_ty = error_union_ty.errorUnionSet(); const payload_ty = error_union_ty.errorUnionPayload(); - if (err_ty.errorSetIsEmpty()) { + if (err_ty.errorSetIsEmpty(mod)) { return MCValue{ .immediate = 0 }; } if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) { @@ -2124,7 +2124,7 @@ fn errUnionPayload( const mod = self.bin_file.options.module.?; const err_ty = error_union_ty.errorUnionSet(); const payload_ty = error_union_ty.errorUnionPayload(); - if (err_ty.errorSetIsEmpty()) { + if (err_ty.errorSetIsEmpty(mod)) { return try error_union_bind.resolveToMcv(self); } if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) { @@ -4882,9 +4882,10 @@ fn isErr( error_union_bind: ReadArg.Bind, error_union_ty: Type, ) !MCValue { + const mod = self.bin_file.options.module.?; const error_type = error_union_ty.errorUnionSet(); - if (error_type.errorSetIsEmpty()) { + if (error_type.errorSetIsEmpty(mod)) { return MCValue{ .immediate = 0 }; // always false } diff --git a/src/arch/sparc64/CodeGen.zig b/src/arch/sparc64/CodeGen.zig index 343cc2f90e..a519b73235 100644 --- a/src/arch/sparc64/CodeGen.zig +++ b/src/arch/sparc64/CodeGen.zig @@ -3530,7 +3530,7 @@ fn errUnionPayload(self: *Self, error_union_mcv: MCValue, error_union_ty: Type) const mod = self.bin_file.options.module.?; const err_ty = error_union_ty.errorUnionSet(); const payload_ty = error_union_ty.errorUnionPayload(); - if (err_ty.errorSetIsEmpty()) { + if (err_ty.errorSetIsEmpty(mod)) { return error_union_mcv; } if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) { diff --git a/src/arch/wasm/CodeGen.zig b/src/arch/wasm/CodeGen.zig index bbba43d265..2c1e8aa36d 100644 --- a/src/arch/wasm/CodeGen.zig +++ b/src/arch/wasm/CodeGen.zig @@ -1036,8 +1036,8 @@ fn genValtype(ty: Type, mod: *Module) u8 { /// Differently from `genValtype` this also allows `void` to create a block /// with no return type fn genBlockType(ty: Type, mod: *Module) u8 { - return switch (ty.tag()) { - .void, .noreturn => wasm.block_empty, + return switch (ty.ip_index) { + .void_type, .noreturn_type => wasm.block_empty, else => genValtype(ty, mod), }; } @@ -3948,7 +3948,7 @@ fn airIsErr(func: *CodeGen, inst: Air.Inst.Index, opcode: wasm.Opcode) InnerErro const pl_ty = err_union_ty.errorUnionPayload(); const result = result: { - if (err_union_ty.errorUnionSet().errorSetIsEmpty()) { + if (err_union_ty.errorUnionSet().errorSetIsEmpty(mod)) { switch (opcode) { .i32_ne => break :result WValue{ .imm32 = 0 }, .i32_eq => break :result WValue{ .imm32 = 1 }, @@ -4013,7 +4013,7 @@ fn airUnwrapErrUnionError(func: *CodeGen, inst: Air.Inst.Index, op_is_ptr: bool) const payload_ty = err_ty.errorUnionPayload(); const result = result: { - if (err_ty.errorUnionSet().errorSetIsEmpty()) { + if (err_ty.errorUnionSet().errorSetIsEmpty(mod)) { break :result WValue{ .imm32 = 0 }; } @@ -6214,7 +6214,7 @@ fn lowerTry( const pl_ty = err_union_ty.errorUnionPayload(); const pl_has_bits = pl_ty.hasRuntimeBitsIgnoreComptime(mod); - if (!err_union_ty.errorUnionSet().errorSetIsEmpty()) { + if (!err_union_ty.errorUnionSet().errorSetIsEmpty(mod)) { // Block we can jump out of when error is not set try func.startBlock(.block, wasm.block_empty); diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index 865ebe02f7..3e0ca4831b 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -3624,7 +3624,7 @@ fn airUnwrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void { const operand = try self.resolveInst(ty_op.operand); const result: MCValue = result: { - if (err_ty.errorSetIsEmpty()) { + if (err_ty.errorSetIsEmpty(mod)) { break :result MCValue{ .immediate = 0 }; } @@ -5811,7 +5811,7 @@ fn genUnOp(self: *Self, maybe_inst: ?Air.Inst.Index, tag: Air.Inst.Tag, src_air: switch (tag) { .not => { const limb_abi_size = @intCast(u16, @min(src_ty.abiSize(mod), 8)); - const int_info = if (src_ty.tag() == .bool) + const int_info = if (src_ty.ip_index == .bool_type) std.builtin.Type.Int{ .signedness = .unsigned, .bits = 1 } else src_ty.intInfo(mod); @@ -8716,7 +8716,7 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC try self.asmRegisterRegister(.{ ._, .@"test" }, alias_reg, alias_reg); return .{ .eflags = .z }; } - assert(some_info.ty.tag() == .bool); + assert(some_info.ty.ip_index == .bool_type); const opt_abi_size = @intCast(u32, opt_ty.abiSize(mod)); try self.asmRegisterImmediate( .{ ._, .bt }, @@ -8808,7 +8808,7 @@ fn isErr(self: *Self, maybe_inst: ?Air.Inst.Index, ty: Type, operand: MCValue) ! const mod = self.bin_file.options.module.?; const err_type = ty.errorUnionSet(); - if (err_type.errorSetIsEmpty()) { + if (err_type.errorSetIsEmpty(mod)) { return MCValue{ .immediate = 0 }; // always false } diff --git a/src/codegen/c.zig b/src/codegen/c.zig index f4daa56a6d..2e5e45d54c 100644 --- a/src/codegen/c.zig +++ b/src/codegen/c.zig @@ -1508,7 +1508,7 @@ pub const DeclGen = struct { } if (fn_decl.val.castTag(.function)) |func_payload| if (func_payload.data.is_cold) try w.writeAll("zig_cold "); - if (fn_info.return_type.tag() == .noreturn) try w.writeAll("zig_noreturn "); + if (fn_info.return_type.ip_index == .noreturn_type) try w.writeAll("zig_noreturn "); const trailing = try renderTypePrefix( dg.decl_index, @@ -3783,7 +3783,7 @@ fn airNot(f: *Function, inst: Air.Inst.Index) !CValue { const ty_op = f.air.instructions.items(.data)[inst].ty_op; const operand_ty = f.typeOf(ty_op.operand); const scalar_ty = operand_ty.scalarType(mod); - if (scalar_ty.tag() != .bool) return try airUnBuiltinCall(f, inst, "not", .bits); + if (scalar_ty.ip_index != .bool_type) return try airUnBuiltinCall(f, inst, "not", .bits); const op = try f.resolveInst(ty_op.operand); try reap(f, inst, &.{ty_op.operand}); @@ -4292,7 +4292,7 @@ fn airBlock(f: *Function, inst: Air.Inst.Index) !CValue { const writer = f.object.writer(); const inst_ty = f.typeOfIndex(inst); - const result = if (inst_ty.tag() != .void and !f.liveness.isUnused(inst)) + const result = if (inst_ty.ip_index != .void_type and !f.liveness.isUnused(inst)) try f.allocLocal(inst, inst_ty) else .none; @@ -4354,7 +4354,7 @@ fn lowerTry( const payload_ty = err_union_ty.errorUnionPayload(); const payload_has_bits = payload_ty.hasRuntimeBitsIgnoreComptime(mod); - if (!err_union_ty.errorUnionSet().errorSetIsEmpty()) { + if (!err_union_ty.errorUnionSet().errorSetIsEmpty(mod)) { try writer.writeAll("if ("); if (!payload_has_bits) { if (is_ptr) @@ -5549,7 +5549,7 @@ fn airUnwrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue { if (!payload_ty.hasRuntimeBits(mod)) { try f.writeCValue(writer, operand, .Other); } else { - if (!error_ty.errorSetIsEmpty()) + if (!error_ty.errorSetIsEmpty(mod)) if (operand_is_ptr) try f.writeCValueDerefMember(writer, operand, .{ .identifier = "error" }) else @@ -5768,7 +5768,7 @@ fn airIsErr(f: *Function, inst: Air.Inst.Index, is_ptr: bool, operator: []const try f.writeCValue(writer, local, .Other); try writer.writeAll(" = "); - if (!error_ty.errorSetIsEmpty()) + if (!error_ty.errorSetIsEmpty(mod)) if (payload_ty.hasRuntimeBits(mod)) if (is_ptr) try f.writeCValueDerefMember(writer, operand, .{ .identifier = "error" }) @@ -6032,7 +6032,7 @@ fn airCmpBuiltinCall( try writer.writeByte(')'); if (!ref_ret) try writer.print(" {s} {}", .{ compareOperatorC(operator), - try f.fmtIntLiteral(Type.initTag(.i32), Value.zero), + try f.fmtIntLiteral(Type.i32, Value.zero), }); try writer.writeAll(";\n"); try v.end(f, inst, writer); @@ -7749,7 +7749,7 @@ const LowerFnRetTyBuffer = struct { payload: Type.Payload.AnonStruct, }; fn lowerFnRetTy(ret_ty: Type, buffer: *LowerFnRetTyBuffer, mod: *const Module) Type { - if (ret_ty.zigTypeTag(mod) == .NoReturn) return Type.initTag(.noreturn); + if (ret_ty.zigTypeTag(mod) == .NoReturn) return Type.noreturn; if (lowersToArray(ret_ty, mod)) { buffer.names = [1][]const u8{"array"}; diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index ce78b06f2e..232cd9d42f 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -1730,7 +1730,7 @@ pub const Object = struct { return ptr_di_ty; }, .Opaque => { - if (ty.tag() == .anyopaque) { + if (ty.ip_index == .anyopaque_type) { const di_ty = dib.createBasicType("anyopaque", 0, DW.ATE.signed); gop.value_ptr.* = AnnotatedDITypePtr.initFull(di_ty); return di_ty; @@ -2847,25 +2847,23 @@ pub const DeclGen = struct { const llvm_addrspace = toLlvmAddressSpace(ptr_info.@"addrspace", target); return dg.context.pointerType(llvm_addrspace); }, - .Opaque => switch (t.tag()) { - .@"opaque" => { - const gop = try dg.object.type_map.getOrPutContext(gpa, t, .{ .mod = dg.module }); - if (gop.found_existing) return gop.value_ptr.*; + .Opaque => { + if (t.ip_index == .anyopaque_type) return dg.context.intType(8); - // The Type memory is ephemeral; since we want to store a longer-lived - // reference, we need to copy it here. - gop.key_ptr.* = try t.copy(dg.object.type_map_arena.allocator()); + const gop = try dg.object.type_map.getOrPutContext(gpa, t, .{ .mod = dg.module }); + if (gop.found_existing) return gop.value_ptr.*; - const opaque_obj = t.castTag(.@"opaque").?.data; - const name = try opaque_obj.getFullyQualifiedName(dg.module); - defer gpa.free(name); + // The Type memory is ephemeral; since we want to store a longer-lived + // reference, we need to copy it here. + gop.key_ptr.* = try t.copy(dg.object.type_map_arena.allocator()); - const llvm_struct_ty = dg.context.structCreateNamed(name); - gop.value_ptr.* = llvm_struct_ty; // must be done before any recursive calls - return llvm_struct_ty; - }, - .anyopaque => return dg.context.intType(8), - else => unreachable, + const opaque_obj = t.castTag(.@"opaque").?.data; + const name = try opaque_obj.getFullyQualifiedName(dg.module); + defer gpa.free(name); + + const llvm_struct_ty = dg.context.structCreateNamed(name); + gop.value_ptr.* = llvm_struct_ty; // must be done before any recursive calls + return llvm_struct_ty; }, .Array => { const elem_ty = t.childType(); @@ -5531,7 +5529,7 @@ pub const FuncGen = struct { const payload_has_bits = payload_ty.hasRuntimeBitsIgnoreComptime(mod); const err_union_llvm_ty = try fg.dg.lowerType(err_union_ty); - if (!err_union_ty.errorUnionSet().errorSetIsEmpty()) { + if (!err_union_ty.errorUnionSet().errorSetIsEmpty(mod)) { const is_err = err: { const err_set_ty = try fg.dg.lowerType(Type.anyerror); const zero = err_set_ty.constNull(); @@ -6715,7 +6713,7 @@ pub const FuncGen = struct { const err_set_ty = try self.dg.lowerType(Type.anyerror); const zero = err_set_ty.constNull(); - if (err_union_ty.errorUnionSet().errorSetIsEmpty()) { + if (err_union_ty.errorUnionSet().errorSetIsEmpty(mod)) { const llvm_i1 = self.context.intType(1); switch (op) { .EQ => return llvm_i1.constInt(1, .False), // 0 == 0 @@ -6864,7 +6862,7 @@ pub const FuncGen = struct { const operand = try self.resolveInst(ty_op.operand); const operand_ty = self.typeOf(ty_op.operand); const err_union_ty = if (operand_is_ptr) operand_ty.childType() else operand_ty; - if (err_union_ty.errorUnionSet().errorSetIsEmpty()) { + if (err_union_ty.errorUnionSet().errorSetIsEmpty(mod)) { const err_llvm_ty = try self.dg.lowerType(Type.anyerror); if (operand_is_ptr) { return operand; diff --git a/src/codegen/spirv.zig b/src/codegen/spirv.zig index 90c2d93458..3a5f5d6f6a 100644 --- a/src/codegen/spirv.zig +++ b/src/codegen/spirv.zig @@ -2849,6 +2849,7 @@ pub const DeclGen = struct { } fn airTry(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { + const mod = self.module; const pl_op = self.air.instructions.items(.data)[inst].pl_op; const err_union_id = try self.resolve(pl_op.operand); const extra = self.air.extraData(Air.Try, pl_op.payload); @@ -2862,7 +2863,7 @@ pub const DeclGen = struct { const eu_layout = self.errorUnionLayout(payload_ty); - if (!err_union_ty.errorUnionSet().errorSetIsEmpty()) { + if (!err_union_ty.errorUnionSet().errorSetIsEmpty(mod)) { const err_id = if (eu_layout.payload_has_bits) try self.extractField(Type.anyerror, err_union_id, eu_layout.errorFieldIndex()) else @@ -2910,12 +2911,13 @@ pub const DeclGen = struct { fn airErrUnionErr(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { if (self.liveness.isUnused(inst)) return null; + const mod = self.module; const ty_op = self.air.instructions.items(.data)[inst].ty_op; const operand_id = try self.resolve(ty_op.operand); const err_union_ty = self.typeOf(ty_op.operand); const err_ty_ref = try self.resolveType(Type.anyerror, .direct); - if (err_union_ty.errorUnionSet().errorSetIsEmpty()) { + if (err_union_ty.errorUnionSet().errorSetIsEmpty(mod)) { // No error possible, so just return undefined. return try self.spv.constUndef(err_ty_ref); } diff --git a/src/print_air.zig b/src/print_air.zig index 39a244e11f..f4a1aeae32 100644 --- a/src/print_air.zig +++ b/src/print_air.zig @@ -370,7 +370,6 @@ const Writer = struct { switch (t) { .inferred_alloc_const => try s.writeAll("(inferred_alloc_const)"), .inferred_alloc_mut => try s.writeAll("(inferred_alloc_mut)"), - .generic_poison => try s.writeAll("(generic_poison)"), else => try ty.print(s, w.module), } } diff --git a/src/type.zig b/src/type.zig index 4e8d0b9e20..7db7ad316b 100644 --- a/src/type.zig +++ b/src/type.zig @@ -85,9 +85,9 @@ pub const Type = struct { .address_space, .float_mode, .reduce_op, + .call_modifier, => return .Enum, - .call_modifier, .prefetch_options, .export_options, .extern_options, @@ -95,7 +95,7 @@ pub const Type = struct { .type_info => return .Union, - .generic_poison => unreachable, + .generic_poison => return error.GenericPoison, .var_args_param => unreachable, }, @@ -107,8 +107,6 @@ pub const Type = struct { } } switch (ty.tag()) { - .generic_poison => return error.GenericPoison, - .u1, .u8, .i8, @@ -125,19 +123,11 @@ pub const Type = struct { .error_set, .error_set_single, - .anyerror, .error_set_inferred, .error_set_merged, => return .ErrorSet, - .anyopaque, .@"opaque" => return .Opaque, - .bool => return .Bool, - .void => return .Void, - .type => return .Type, - .comptime_int => return .ComptimeInt, - .noreturn => return .NoReturn, - .null => return .Null, - .undefined => return .Undefined, + .@"opaque" => return .Opaque, .function => return .Fn, @@ -172,18 +162,14 @@ pub const Type = struct { .optional_single_const_pointer, .optional_single_mut_pointer, => return .Optional, - .enum_literal => return .EnumLiteral, .anyerror_void_error_union, .error_union => return .ErrorUnion, - .anyframe_T, .@"anyframe" => return .AnyFrame, + .anyframe_T => return .AnyFrame, .empty_struct, .empty_struct_literal, .@"struct", - .prefetch_options, - .export_options, - .extern_options, .tuple, .anon_struct, => return .Struct, @@ -192,19 +178,11 @@ pub const Type = struct { .enum_nonexhaustive, .enum_simple, .enum_numbered, - .atomic_order, - .atomic_rmw_op, - .calling_convention, - .address_space, - .float_mode, - .reduce_op, - .modifier, => return .Enum, .@"union", .union_safety_tagged, .union_tagged, - .type_info, => return .Union, } } @@ -393,7 +371,7 @@ pub const Type = struct { pub fn ptrInfo(self: Type) Payload.Pointer { switch (self.tag()) { .single_const_pointer_to_comptime_int => return .{ .data = .{ - .pointee_type = Type.initTag(.comptime_int), + .pointee_type = Type.comptime_int, .sentinel = null, .@"align" = 0, .@"addrspace" = .generic, @@ -405,7 +383,7 @@ pub const Type = struct { .size = .One, } }, .const_slice_u8 => return .{ .data = .{ - .pointee_type = Type.initTag(.u8), + .pointee_type = Type.u8, .sentinel = null, .@"align" = 0, .@"addrspace" = .generic, @@ -417,7 +395,7 @@ pub const Type = struct { .size = .Slice, } }, .const_slice_u8_sentinel_0 => return .{ .data = .{ - .pointee_type = Type.initTag(.u8), + .pointee_type = Type.u8, .sentinel = Value.zero, .@"align" = 0, .@"addrspace" = .generic, @@ -465,7 +443,7 @@ pub const Type = struct { .size = .Many, } }, .manyptr_const_u8 => return .{ .data = .{ - .pointee_type = Type.initTag(.u8), + .pointee_type = Type.u8, .sentinel = null, .@"align" = 0, .@"addrspace" = .generic, @@ -477,7 +455,7 @@ pub const Type = struct { .size = .Many, } }, .manyptr_const_u8_sentinel_0 => return .{ .data = .{ - .pointee_type = Type.initTag(.u8), + .pointee_type = Type.u8, .sentinel = Value.zero, .@"align" = 0, .@"addrspace" = .generic, @@ -501,7 +479,7 @@ pub const Type = struct { .size = .Many, } }, .manyptr_u8 => return .{ .data = .{ - .pointee_type = Type.initTag(.u8), + .pointee_type = Type.u8, .sentinel = null, .@"align" = 0, .@"addrspace" = .generic, @@ -608,23 +586,6 @@ pub const Type = struct { if (a.legacy.tag_if_small_enough == b.legacy.tag_if_small_enough) return true; switch (a.tag()) { - .generic_poison => unreachable, - - .bool, - .void, - .type, - .comptime_int, - .noreturn, - .null, - .undefined, - .anyopaque, - .@"anyframe", - .enum_literal, - => |a_tag| { - assert(a_tag != b.tag()); // because of the comparison at the top of the function. - return false; - }, - .u1, .u8, .i8, @@ -653,10 +614,6 @@ pub const Type = struct { return a_ies == b_ies; }, - .anyerror => { - return b.tag() == .anyerror; - }, - .error_set, .error_set_single, .error_set_merged, @@ -927,13 +884,6 @@ pub const Type = struct { return true; }, - // we can't compare these based on tags because it wouldn't detect if, - // for example, a was resolved into .@"struct" but b was one of these tags. - .prefetch_options, - .export_options, - .extern_options, - => unreachable, // needed to resolve the type before now - .enum_full, .enum_nonexhaustive => { const a_enum_obj = a.cast(Payload.EnumFull).?.data; const b_enum_obj = (b.cast(Payload.EnumFull) orelse return false).data; @@ -949,26 +899,12 @@ pub const Type = struct { const b_enum_obj = (b.cast(Payload.EnumNumbered) orelse return false).data; return a_enum_obj == b_enum_obj; }, - // we can't compare these based on tags because it wouldn't detect if, - // for example, a was resolved into .enum_simple but b was one of these tags. - .atomic_order, - .atomic_rmw_op, - .calling_convention, - .address_space, - .float_mode, - .reduce_op, - .modifier, - => unreachable, // needed to resolve the type before now .@"union", .union_safety_tagged, .union_tagged => { const a_union_obj = a.cast(Payload.Union).?.data; const b_union_obj = (b.cast(Payload.Union) orelse return false).data; return a_union_obj == b_union_obj; }, - // we can't compare these based on tags because it wouldn't detect if, - // for example, a was resolved into .union_tagged but b was one of these tags. - .type_info => unreachable, // needed to resolve the type before now - } } @@ -987,31 +923,6 @@ pub const Type = struct { return; } switch (ty.tag()) { - .generic_poison => unreachable, - - .bool => std.hash.autoHash(hasher, std.builtin.TypeId.Bool), - .void => std.hash.autoHash(hasher, std.builtin.TypeId.Void), - .type => std.hash.autoHash(hasher, std.builtin.TypeId.Type), - .comptime_int => std.hash.autoHash(hasher, std.builtin.TypeId.ComptimeInt), - .noreturn => std.hash.autoHash(hasher, std.builtin.TypeId.NoReturn), - .null => std.hash.autoHash(hasher, std.builtin.TypeId.Null), - .undefined => std.hash.autoHash(hasher, std.builtin.TypeId.Undefined), - - .anyopaque => { - std.hash.autoHash(hasher, std.builtin.TypeId.Opaque); - std.hash.autoHash(hasher, Tag.anyopaque); - }, - - .@"anyframe" => { - std.hash.autoHash(hasher, std.builtin.TypeId.AnyFrame); - std.hash.autoHash(hasher, Tag.@"anyframe"); - }, - - .enum_literal => { - std.hash.autoHash(hasher, std.builtin.TypeId.EnumLiteral); - std.hash.autoHash(hasher, Tag.enum_literal); - }, - .u1, .u8, .i8, @@ -1046,12 +957,6 @@ pub const Type = struct { for (names) |name| hasher.update(name); }, - .anyerror => { - // anyerror is distinct from other error sets - std.hash.autoHash(hasher, std.builtin.TypeId.ErrorSet); - std.hash.autoHash(hasher, Tag.anyerror); - }, - .error_set_inferred => { // inferred error sets are compared using their data pointer const ies: *Module.Fn.InferredErrorSet = ty.castTag(.error_set_inferred).?.data; @@ -1209,12 +1114,6 @@ pub const Type = struct { } }, - // we can't hash these based on tags because they wouldn't match the expanded version. - .prefetch_options, - .export_options, - .extern_options, - => unreachable, // needed to resolve the type before now - .enum_full, .enum_nonexhaustive => { const enum_obj: *const Module.EnumFull = ty.cast(Payload.EnumFull).?.data; std.hash.autoHash(hasher, std.builtin.TypeId.Enum); @@ -1230,24 +1129,12 @@ pub const Type = struct { std.hash.autoHash(hasher, std.builtin.TypeId.Enum); std.hash.autoHash(hasher, enum_obj); }, - // we can't hash these based on tags because they wouldn't match the expanded version. - .atomic_order, - .atomic_rmw_op, - .calling_convention, - .address_space, - .float_mode, - .reduce_op, - .modifier, - => unreachable, // needed to resolve the type before now .@"union", .union_safety_tagged, .union_tagged => { const union_obj: *const Module.Union = ty.cast(Payload.Union).?.data; std.hash.autoHash(hasher, std.builtin.TypeId.Union); std.hash.autoHash(hasher, union_obj); }, - // we can't hash these based on tags because they wouldn't match the expanded version. - .type_info => unreachable, // needed to resolve the type before now - } } @@ -1305,19 +1192,9 @@ pub const Type = struct { .i64, .u128, .i128, - .anyopaque, - .bool, - .void, - .type, - .anyerror, - .comptime_int, - .noreturn, - .null, - .undefined, .single_const_pointer_to_comptime_int, .const_slice_u8, .const_slice_u8_sentinel_0, - .enum_literal, .anyerror_void_error_union, .inferred_alloc_const, .inferred_alloc_mut, @@ -1325,19 +1202,6 @@ pub const Type = struct { .manyptr_u8, .manyptr_const_u8, .manyptr_const_u8_sentinel_0, - .atomic_order, - .atomic_rmw_op, - .calling_convention, - .address_space, - .float_mode, - .reduce_op, - .modifier, - .prefetch_options, - .export_options, - .extern_options, - .type_info, - .@"anyframe", - .generic_poison, => unreachable, .array_u8, @@ -1580,20 +1444,8 @@ pub const Type = struct { .i64, .u128, .i128, - .anyopaque, - .bool, - .void, - .type, - .anyerror, - .@"anyframe", - .comptime_int, - .noreturn, => return writer.writeAll(@tagName(t)), - .enum_literal => return writer.writeAll("@Type(.EnumLiteral)"), - .null => return writer.writeAll("@Type(.Null)"), - .undefined => return writer.writeAll("@Type(.Undefined)"), - .empty_struct, .empty_struct_literal => return writer.writeAll("struct {}"), .@"struct" => { @@ -1640,17 +1492,6 @@ pub const Type = struct { .manyptr_u8 => return writer.writeAll("[*]u8"), .manyptr_const_u8 => return writer.writeAll("[*]const u8"), .manyptr_const_u8_sentinel_0 => return writer.writeAll("[*:0]const u8"), - .atomic_order => return writer.writeAll("std.builtin.AtomicOrder"), - .atomic_rmw_op => return writer.writeAll("std.builtin.AtomicRmwOp"), - .calling_convention => return writer.writeAll("std.builtin.CallingConvention"), - .address_space => return writer.writeAll("std.builtin.AddressSpace"), - .float_mode => return writer.writeAll("std.builtin.FloatMode"), - .reduce_op => return writer.writeAll("std.builtin.ReduceOp"), - .modifier => return writer.writeAll("std.builtin.CallModifier"), - .prefetch_options => return writer.writeAll("std.builtin.PrefetchOptions"), - .export_options => return writer.writeAll("std.builtin.ExportOptions"), - .extern_options => return writer.writeAll("std.builtin.ExternOptions"), - .type_info => return writer.writeAll("std.builtin.Type"), .function => { const payload = ty.castTag(.function).?.data; try writer.writeAll("fn("); @@ -1889,7 +1730,6 @@ pub const Type = struct { }, .inferred_alloc_const => return writer.writeAll("(inferred_alloc_const)"), .inferred_alloc_mut => return writer.writeAll("(inferred_alloc_mut)"), - .generic_poison => return writer.writeAll("(generic poison)"), } unreachable; } @@ -1931,20 +1771,6 @@ pub const Type = struct { switch (t) { .inferred_alloc_const => unreachable, .inferred_alloc_mut => unreachable, - .generic_poison => unreachable, - - // TODO get rid of these Type.Tag values. - .atomic_order => unreachable, - .atomic_rmw_op => unreachable, - .calling_convention => unreachable, - .address_space => unreachable, - .float_mode => unreachable, - .reduce_op => unreachable, - .modifier => unreachable, - .prefetch_options => unreachable, - .export_options => unreachable, - .extern_options => unreachable, - .type_info => unreachable, .u1, .u8, @@ -1958,19 +1784,8 @@ pub const Type = struct { .i64, .u128, .i128, - .anyopaque, - .bool, - .void, - .type, - .anyerror, - .@"anyframe", - .comptime_int, - .noreturn, => try writer.writeAll(@tagName(t)), - .enum_literal => try writer.writeAll("@TypeOf(.enum_literal)"), - .null => try writer.writeAll("@TypeOf(null)"), - .undefined => try writer.writeAll("@TypeOf(undefined)"), .empty_struct_literal => try writer.writeAll("@TypeOf(.{})"), .empty_struct => { @@ -2249,34 +2064,12 @@ pub const Type = struct { .i32 => return Value.initTag(.i32_type), .u64 => return Value.initTag(.u64_type), .i64 => return Value.initTag(.i64_type), - .anyopaque => return Value.initTag(.anyopaque_type), - .bool => return Value.initTag(.bool_type), - .void => return Value.initTag(.void_type), - .type => return Value.initTag(.type_type), - .anyerror => return Value.initTag(.anyerror_type), - .@"anyframe" => return Value.initTag(.anyframe_type), - .comptime_int => return Value.initTag(.comptime_int_type), - .noreturn => return Value.initTag(.noreturn_type), - .null => return Value.initTag(.null_type), - .undefined => return Value.initTag(.undefined_type), .single_const_pointer_to_comptime_int => return Value.initTag(.single_const_pointer_to_comptime_int_type), .const_slice_u8 => return Value.initTag(.const_slice_u8_type), .const_slice_u8_sentinel_0 => return Value.initTag(.const_slice_u8_sentinel_0_type), - .enum_literal => return Value.initTag(.enum_literal_type), .manyptr_u8 => return Value.initTag(.manyptr_u8_type), .manyptr_const_u8 => return Value.initTag(.manyptr_const_u8_type), .manyptr_const_u8_sentinel_0 => return Value.initTag(.manyptr_const_u8_sentinel_0_type), - .atomic_order => return Value.initTag(.atomic_order_type), - .atomic_rmw_op => return Value.initTag(.atomic_rmw_op_type), - .calling_convention => return Value.initTag(.calling_convention_type), - .address_space => return Value.initTag(.address_space_type), - .float_mode => return Value.initTag(.float_mode_type), - .reduce_op => return Value.initTag(.reduce_op_type), - .modifier => return Value.initTag(.modifier_type), - .prefetch_options => return Value.initTag(.prefetch_options_type), - .export_options => return Value.initTag(.export_options_type), - .extern_options => return Value.initTag(.extern_options_type), - .type_info => return Value.initTag(.type_info_type), .inferred_alloc_const => unreachable, .inferred_alloc_mut => unreachable, else => return Value.Tag.ty.create(allocator, self), @@ -2378,8 +2171,7 @@ pub const Type = struct { .i64, .u128, .i128, - .bool, - .anyerror, + .const_slice_u8, .const_slice_u8_sentinel_0, .array_u8_sentinel_0, @@ -2388,18 +2180,7 @@ pub const Type = struct { .manyptr_u8, .manyptr_const_u8, .manyptr_const_u8_sentinel_0, - .atomic_order, - .atomic_rmw_op, - .calling_convention, - .address_space, - .float_mode, - .reduce_op, - .modifier, - .prefetch_options, - .export_options, - .extern_options, - .@"anyframe", - .anyopaque, + .@"opaque", .error_set_single, .error_union, @@ -2435,16 +2216,8 @@ pub const Type = struct { // These are false because they are comptime-only types. .single_const_pointer_to_comptime_int, - .void, - .type, - .comptime_int, - .noreturn, - .null, - .undefined, - .enum_literal, .empty_struct, .empty_struct_literal, - .type_info, // These are function *bodies*, not pointers. // Special exceptions have to be made when emitting functions due to // this returning false. @@ -2558,7 +2331,6 @@ pub const Type = struct { .inferred_alloc_const => unreachable, .inferred_alloc_mut => unreachable, - .generic_poison => unreachable, } } @@ -2641,8 +2413,7 @@ pub const Type = struct { .i64, .u128, .i128, - .bool, - .void, + .manyptr_u8, .manyptr_const_u8, .manyptr_const_u8_sentinel_0, @@ -2662,32 +2433,11 @@ pub const Type = struct { .optional_single_const_pointer, => true, - .anyopaque, - .anyerror, - .noreturn, - .null, - .@"anyframe", - .undefined, - .atomic_order, - .atomic_rmw_op, - .calling_convention, - .address_space, - .float_mode, - .reduce_op, - .modifier, - .prefetch_options, - .export_options, - .extern_options, .error_set, .error_set_single, .error_set_inferred, .error_set_merged, .@"opaque", - .generic_poison, - .type, - .comptime_int, - .enum_literal, - .type_info, // These are function bodies, not function pointers. .function, .const_slice_u8, @@ -2773,7 +2523,6 @@ pub const Type = struct { else => return false, @enumToInt(InternPool.Index.none) => switch (ty.tag()) { - .noreturn => return true, .error_set => { const err_set_obj = ty.castTag(.error_set).?.data; const names = err_set_obj.names.keys(); @@ -3003,21 +2752,10 @@ pub const Type = struct { .u1, .u8, .i8, - .bool, + .array_u8_sentinel_0, .array_u8, - .atomic_order, - .atomic_rmw_op, - .calling_convention, - .address_space, - .float_mode, - .reduce_op, - .modifier, - .prefetch_options, - .export_options, - .extern_options, .@"opaque", - .anyopaque, => return AbiAlignmentAdvanced{ .scalar = 1 }, // represents machine code; not a pointer @@ -3044,13 +2782,11 @@ pub const Type = struct { .manyptr_u8, .manyptr_const_u8, .manyptr_const_u8_sentinel_0, - .@"anyframe", .anyframe_T, => return AbiAlignmentAdvanced{ .scalar = @divExact(target.ptrBitWidth(), 8) }, // TODO revisit this when we have the concept of the error tag type .anyerror_void_error_union, - .anyerror, .error_set_inferred, .error_set_single, .error_set, @@ -3229,22 +2965,12 @@ pub const Type = struct { }, .empty_struct, - .void, .empty_struct_literal, - .type, - .comptime_int, - .null, - .undefined, - .enum_literal, - .type_info, => return AbiAlignmentAdvanced{ .scalar = 0 }, - .noreturn, .inferred_alloc_const, .inferred_alloc_mut, => unreachable, - - .generic_poison => unreachable, } } @@ -3422,26 +3148,12 @@ pub const Type = struct { switch (ty.tag()) { .function => unreachable, // represents machine code; not a pointer .@"opaque" => unreachable, // no size available - .noreturn => unreachable, .inferred_alloc_const => unreachable, .inferred_alloc_mut => unreachable, - .generic_poison => unreachable, - .modifier => unreachable, // missing call to resolveTypeFields - .prefetch_options => unreachable, // missing call to resolveTypeFields - .export_options => unreachable, // missing call to resolveTypeFields - .extern_options => unreachable, // missing call to resolveTypeFields - .type_info => unreachable, // missing call to resolveTypeFields - .anyopaque, - .type, - .comptime_int, - .null, - .undefined, - .enum_literal, .single_const_pointer_to_comptime_int, .empty_struct_literal, .empty_struct, - .void, => return AbiSizeAdvanced{ .scalar = 0 }, .@"struct", .tuple, .anon_struct => switch (ty.containerLayout()) { @@ -3496,13 +3208,6 @@ pub const Type = struct { .u1, .u8, .i8, - .bool, - .atomic_order, - .atomic_rmw_op, - .calling_convention, - .address_space, - .float_mode, - .reduce_op, => return AbiSizeAdvanced{ .scalar = 1 }, .array_u8 => return AbiSizeAdvanced{ .scalar = ty.castTag(.array_u8).?.data }, @@ -3552,7 +3257,6 @@ pub const Type = struct { return AbiSizeAdvanced{ .scalar = result }; }, - .@"anyframe", .anyframe_T, .optional_single_const_pointer, .optional_single_mut_pointer, @@ -3580,7 +3284,6 @@ pub const Type = struct { // TODO revisit this when we have the concept of the error tag type .anyerror_void_error_union, - .anyerror, .error_set_inferred, .error_set, .error_set_merged, @@ -3758,6 +3461,7 @@ pub const Type = struct { .undefined => unreachable, .enum_literal => unreachable, .generic_poison => unreachable, + .var_args_param => unreachable, .atomic_order => unreachable, // missing call to resolveTypeFields .atomic_rmw_op => unreachable, // missing call to resolveTypeFields @@ -3770,7 +3474,6 @@ pub const Type = struct { .export_options => unreachable, // missing call to resolveTypeFields .extern_options => unreachable, // missing call to resolveTypeFields .type_info => unreachable, // missing call to resolveTypeFields - .var_args_param => unreachable, }, .struct_type => @panic("TODO"), .union_type => @panic("TODO"), @@ -3784,23 +3487,14 @@ pub const Type = struct { switch (ty.tag()) { .function => unreachable, // represents machine code; not a pointer - .anyopaque => unreachable, - .type => unreachable, - .comptime_int => unreachable, - .noreturn => unreachable, - .null => unreachable, - .undefined => unreachable, - .enum_literal => unreachable, .single_const_pointer_to_comptime_int => unreachable, .empty_struct => unreachable, .empty_struct_literal => unreachable, .inferred_alloc_const => unreachable, .inferred_alloc_mut => unreachable, .@"opaque" => unreachable, - .generic_poison => unreachable, - .void => return 0, - .bool, .u1 => return 1, + .u1 => return 1, .u8, .i8 => return 8, .i16, .u16 => return 16, .u29 => return 29, @@ -3875,9 +3569,7 @@ pub const Type = struct { return payload.len * 8 * elem_size + elem_bit_size; }, - .@"anyframe", - .anyframe_T, - => return target.ptrBitWidth(), + .anyframe_T => return target.ptrBitWidth(), .const_slice, .mut_slice, @@ -3916,7 +3608,6 @@ pub const Type = struct { .error_set, .error_set_single, .anyerror_void_error_union, - .anyerror, .error_set_inferred, .error_set_merged, => return 16, // TODO revisit this when we have the concept of the error tag type @@ -3926,19 +3617,6 @@ pub const Type = struct { // includes padding bits. return (try abiSizeAdvanced(ty, mod, strat)).scalar * 8; }, - - .atomic_order, - .atomic_rmw_op, - .calling_convention, - .address_space, - .float_mode, - .reduce_op, - .modifier, - .prefetch_options, - .export_options, - .extern_options, - .type_info, - => @panic("TODO at some point we gotta resolve builtin types"), } } @@ -4326,7 +4004,7 @@ pub const Type = struct { .manyptr_const_u8_sentinel_0, => Type.u8, - .single_const_pointer_to_comptime_int => Type.initTag(.comptime_int), + .single_const_pointer_to_comptime_int => Type.comptime_int, .pointer => ty.castTag(.pointer).?.data.pointee_type, else => unreachable, @@ -4372,7 +4050,7 @@ pub const Type = struct { .manyptr_const_u8_sentinel_0, => Type.u8, - .single_const_pointer_to_comptime_int => Type.initTag(.comptime_int), + .single_const_pointer_to_comptime_int => Type.comptime_int, .pointer => { const info = ty.castTag(.pointer).?.data; const child_ty = info.pointee_type; @@ -4387,7 +4065,6 @@ pub const Type = struct { .optional_single_const_pointer => ty.castPointer().?.data, .anyframe_T => ty.castTag(.anyframe_T).?.data, - .@"anyframe" => Type.void, else => unreachable, }; @@ -4468,19 +4145,6 @@ pub const Type = struct { return union_obj.tag_ty; }, - .atomic_order, - .atomic_rmw_op, - .calling_convention, - .address_space, - .float_mode, - .reduce_op, - .modifier, - .prefetch_options, - .export_options, - .extern_options, - .type_info, - => unreachable, // needed to call resolveTypeFields first - else => null, }; } @@ -4495,19 +4159,6 @@ pub const Type = struct { return union_obj.tag_ty; }, - .atomic_order, - .atomic_rmw_op, - .calling_convention, - .address_space, - .float_mode, - .reduce_op, - .modifier, - .prefetch_options, - .export_options, - .extern_options, - .type_info, - => unreachable, // needed to call resolveTypeFields first - else => null, }; } @@ -4572,7 +4223,7 @@ pub const Type = struct { /// Asserts that the type is an error union. pub fn errorUnionPayload(self: Type) Type { return switch (self.tag()) { - .anyerror_void_error_union => Type.initTag(.void), + .anyerror_void_error_union => Type.void, .error_union => self.castTag(.error_union).?.data.payload, else => unreachable, }; @@ -4580,33 +4231,38 @@ pub const Type = struct { pub fn errorUnionSet(self: Type) Type { return switch (self.tag()) { - .anyerror_void_error_union => Type.initTag(.anyerror), + .anyerror_void_error_union => Type.anyerror, .error_union => self.castTag(.error_union).?.data.error_set, else => unreachable, }; } /// Returns false for unresolved inferred error sets. - pub fn errorSetIsEmpty(ty: Type) bool { - switch (ty.tag()) { - .anyerror => return false, - .error_set_inferred => { - const inferred_error_set = ty.castTag(.error_set_inferred).?.data; - // Can't know for sure. - if (!inferred_error_set.is_resolved) return false; - if (inferred_error_set.is_anyerror) return false; - return inferred_error_set.errors.count() == 0; + pub fn errorSetIsEmpty(ty: Type, mod: *const Module) bool { + switch (ty.ip_index) { + .none => switch (ty.tag()) { + .error_set_inferred => { + const inferred_error_set = ty.castTag(.error_set_inferred).?.data; + // Can't know for sure. + if (!inferred_error_set.is_resolved) return false; + if (inferred_error_set.is_anyerror) return false; + return inferred_error_set.errors.count() == 0; + }, + .error_set_single => return false, + .error_set => { + const err_set_obj = ty.castTag(.error_set).?.data; + return err_set_obj.names.count() == 0; + }, + .error_set_merged => { + const name_map = ty.castTag(.error_set_merged).?.data; + return name_map.count() == 0; + }, + else => unreachable, }, - .error_set_single => return false, - .error_set => { - const err_set_obj = ty.castTag(.error_set).?.data; - return err_set_obj.names.count() == 0; + .anyerror_type => return false, + else => switch (mod.intern_pool.indexToKey(ty.ip_index)) { + else => @panic("TODO"), }, - .error_set_merged => { - const name_map = ty.castTag(.error_set_merged).?.data; - return name_map.count() == 0; - }, - else => unreachable, } } @@ -4614,9 +4270,13 @@ pub const Type = struct { /// Note that the result may be a false negative if the type did not get error set /// resolution prior to this call. pub fn isAnyError(ty: Type) bool { - return switch (ty.tag()) { - .anyerror => true, - .error_set_inferred => ty.castTag(.error_set_inferred).?.data.is_anyerror, + return switch (ty.ip_index) { + .none => switch (ty.tag()) { + .error_set_inferred => ty.castTag(.error_set_inferred).?.data.is_anyerror, + else => false, + }, + .anyerror_type => true, + // TODO handle error_set_inferred here else => false, }; } @@ -4788,72 +4448,75 @@ pub const Type = struct { const target = mod.getTarget(); var ty = starting_ty; - if (ty.ip_index != .none) switch (mod.intern_pool.indexToKey(ty.ip_index)) { - .int_type => |int_type| return int_type, - .ptr_type => unreachable, - .array_type => unreachable, - .vector_type => @panic("TODO"), - .optional_type => unreachable, - .error_union_type => unreachable, - .simple_type => |t| switch (t) { - .usize => return .{ .signedness = .unsigned, .bits = target.ptrBitWidth() }, - .isize => return .{ .signedness = .signed, .bits = target.ptrBitWidth() }, - .c_char => return .{ .signedness = .signed, .bits = target.c_type_bit_size(.char) }, - .c_short => return .{ .signedness = .signed, .bits = target.c_type_bit_size(.short) }, - .c_ushort => return .{ .signedness = .unsigned, .bits = target.c_type_bit_size(.ushort) }, - .c_int => return .{ .signedness = .signed, .bits = target.c_type_bit_size(.int) }, - .c_uint => return .{ .signedness = .unsigned, .bits = target.c_type_bit_size(.uint) }, - .c_long => return .{ .signedness = .signed, .bits = target.c_type_bit_size(.long) }, - .c_ulong => return .{ .signedness = .unsigned, .bits = target.c_type_bit_size(.ulong) }, - .c_longlong => return .{ .signedness = .signed, .bits = target.c_type_bit_size(.longlong) }, - .c_ulonglong => return .{ .signedness = .unsigned, .bits = target.c_type_bit_size(.ulonglong) }, + while (true) switch (ty.ip_index) { + .none => switch (ty.tag()) { + .u1 => return .{ .signedness = .unsigned, .bits = 1 }, + .u8 => return .{ .signedness = .unsigned, .bits = 8 }, + .i8 => return .{ .signedness = .signed, .bits = 8 }, + .u16 => return .{ .signedness = .unsigned, .bits = 16 }, + .i16 => return .{ .signedness = .signed, .bits = 16 }, + .u29 => return .{ .signedness = .unsigned, .bits = 29 }, + .u32 => return .{ .signedness = .unsigned, .bits = 32 }, + .i32 => return .{ .signedness = .signed, .bits = 32 }, + .u64 => return .{ .signedness = .unsigned, .bits = 64 }, + .i64 => return .{ .signedness = .signed, .bits = 64 }, + .u128 => return .{ .signedness = .unsigned, .bits = 128 }, + .i128 => return .{ .signedness = .signed, .bits = 128 }, + + .enum_full, .enum_nonexhaustive => ty = ty.cast(Payload.EnumFull).?.data.tag_ty, + .enum_numbered => ty = ty.castTag(.enum_numbered).?.data.tag_ty, + .enum_simple => { + const enum_obj = ty.castTag(.enum_simple).?.data; + const field_count = enum_obj.fields.count(); + if (field_count == 0) return .{ .signedness = .unsigned, .bits = 0 }; + return .{ .signedness = .unsigned, .bits = smallestUnsignedBits(field_count - 1) }; + }, + + .error_set, .error_set_single, .error_set_inferred, .error_set_merged => { + // TODO revisit this when error sets support custom int types + return .{ .signedness = .unsigned, .bits = 16 }; + }, + + .vector => ty = ty.castTag(.vector).?.data.elem_type, + + .@"struct" => { + const struct_obj = ty.castTag(.@"struct").?.data; + assert(struct_obj.layout == .Packed); + ty = struct_obj.backing_int_ty; + }, + else => unreachable, }, - .struct_type => @panic("TODO"), - .union_type => unreachable, - .simple_value => unreachable, - .extern_func => unreachable, - .int => unreachable, - .enum_tag => unreachable, // it's a value, not a type - }; - - while (true) switch (ty.tag()) { - .u1 => return .{ .signedness = .unsigned, .bits = 1 }, - .u8 => return .{ .signedness = .unsigned, .bits = 8 }, - .i8 => return .{ .signedness = .signed, .bits = 8 }, - .u16 => return .{ .signedness = .unsigned, .bits = 16 }, - .i16 => return .{ .signedness = .signed, .bits = 16 }, - .u29 => return .{ .signedness = .unsigned, .bits = 29 }, - .u32 => return .{ .signedness = .unsigned, .bits = 32 }, - .i32 => return .{ .signedness = .signed, .bits = 32 }, - .u64 => return .{ .signedness = .unsigned, .bits = 64 }, - .i64 => return .{ .signedness = .signed, .bits = 64 }, - .u128 => return .{ .signedness = .unsigned, .bits = 128 }, - .i128 => return .{ .signedness = .signed, .bits = 128 }, - - .enum_full, .enum_nonexhaustive => ty = ty.cast(Payload.EnumFull).?.data.tag_ty, - .enum_numbered => ty = ty.castTag(.enum_numbered).?.data.tag_ty, - .enum_simple => { - const enum_obj = ty.castTag(.enum_simple).?.data; - const field_count = enum_obj.fields.count(); - if (field_count == 0) return .{ .signedness = .unsigned, .bits = 0 }; - return .{ .signedness = .unsigned, .bits = smallestUnsignedBits(field_count - 1) }; - }, - - .error_set, .error_set_single, .anyerror, .error_set_inferred, .error_set_merged => { + .anyerror_type => { // TODO revisit this when error sets support custom int types return .{ .signedness = .unsigned, .bits = 16 }; }, - - .vector => ty = ty.castTag(.vector).?.data.elem_type, - - .@"struct" => { - const struct_obj = ty.castTag(.@"struct").?.data; - assert(struct_obj.layout == .Packed); - ty = struct_obj.backing_int_ty; + .usize_type => return .{ .signedness = .unsigned, .bits = target.ptrBitWidth() }, + .isize_type => return .{ .signedness = .signed, .bits = target.ptrBitWidth() }, + .c_char_type => return .{ .signedness = .signed, .bits = target.c_type_bit_size(.char) }, + .c_short_type => return .{ .signedness = .signed, .bits = target.c_type_bit_size(.short) }, + .c_ushort_type => return .{ .signedness = .unsigned, .bits = target.c_type_bit_size(.ushort) }, + .c_int_type => return .{ .signedness = .signed, .bits = target.c_type_bit_size(.int) }, + .c_uint_type => return .{ .signedness = .unsigned, .bits = target.c_type_bit_size(.uint) }, + .c_long_type => return .{ .signedness = .signed, .bits = target.c_type_bit_size(.long) }, + .c_ulong_type => return .{ .signedness = .unsigned, .bits = target.c_type_bit_size(.ulong) }, + .c_longlong_type => return .{ .signedness = .signed, .bits = target.c_type_bit_size(.longlong) }, + .c_ulonglong_type => return .{ .signedness = .unsigned, .bits = target.c_type_bit_size(.ulonglong) }, + else => switch (mod.intern_pool.indexToKey(ty.ip_index)) { + .int_type => |int_type| return int_type, + .ptr_type => unreachable, + .array_type => unreachable, + .vector_type => @panic("TODO"), + .optional_type => unreachable, + .error_union_type => unreachable, + .simple_type => unreachable, // handled via Index enum tag above + .struct_type => @panic("TODO"), + .union_type => unreachable, + .simple_value => unreachable, + .extern_func => unreachable, + .int => unreachable, + .enum_tag => unreachable, }, - - else => unreachable, }; } @@ -5021,7 +4684,6 @@ pub const Type = struct { else => false, }; return switch (ty.tag()) { - .comptime_int, .u1, .u8, .i8, @@ -5114,7 +4776,6 @@ pub const Type = struct { }; while (true) switch (ty.tag()) { - .comptime_int, .u1, .u8, .i8, @@ -5127,9 +4788,7 @@ pub const Type = struct { .i64, .u128, .i128, - .bool, - .type, - .anyerror, + .error_union, .error_set_single, .error_set, @@ -5142,28 +4801,14 @@ pub const Type = struct { .const_slice_u8_sentinel_0, .const_slice, .mut_slice, - .anyopaque, .optional_single_mut_pointer, .optional_single_const_pointer, - .enum_literal, .anyerror_void_error_union, .error_set_inferred, .@"opaque", .manyptr_u8, .manyptr_const_u8, .manyptr_const_u8_sentinel_0, - .atomic_order, - .atomic_rmw_op, - .calling_convention, - .address_space, - .float_mode, - .reduce_op, - .modifier, - .prefetch_options, - .export_options, - .extern_options, - .type_info, - .@"anyframe", .anyframe_T, .many_const_pointer, .many_mut_pointer, @@ -5258,10 +4903,6 @@ pub const Type = struct { }, .empty_struct, .empty_struct_literal => return Value.initTag(.empty_struct_value), - .void => return Value.initTag(.void_value), - .noreturn => return Value.initTag(.unreachable_value), - .null => return Value.initTag(.null_value), - .undefined => return Value.initTag(.undef), .vector, .array, .array_u8 => { if (ty.arrayLen() == 0) @@ -5273,7 +4914,6 @@ pub const Type = struct { .inferred_alloc_const => unreachable, .inferred_alloc_mut => unreachable, - .generic_poison => unreachable, }; } @@ -5358,22 +4998,7 @@ pub const Type = struct { .i64, .u128, .i128, - .anyopaque, - .bool, - .void, - .anyerror, - .noreturn, - .@"anyframe", - .atomic_order, - .atomic_rmw_op, - .calling_convention, - .address_space, - .float_mode, - .reduce_op, - .modifier, - .prefetch_options, - .export_options, - .extern_options, + .manyptr_u8, .manyptr_const_u8, .manyptr_const_u8_sentinel_0, @@ -5387,21 +5012,14 @@ pub const Type = struct { .error_set_inferred, .error_set_merged, .@"opaque", - .generic_poison, .array_u8, .array_u8_sentinel_0, .enum_simple, => false, .single_const_pointer_to_comptime_int, - .type, - .comptime_int, - .enum_literal, - .type_info, // These are function bodies, not function pointers. .function, - .null, - .undefined, => true, .inferred_alloc_mut => unreachable, @@ -5701,17 +5319,6 @@ pub const Type = struct { .enum_full, .enum_nonexhaustive => ty.cast(Payload.EnumFull).?.data.fields, .enum_simple => ty.castTag(.enum_simple).?.data.fields, .enum_numbered => ty.castTag(.enum_numbered).?.data.fields, - .atomic_order, - .atomic_rmw_op, - .calling_convention, - .address_space, - .float_mode, - .reduce_op, - .modifier, - .prefetch_options, - .export_options, - .extern_options, - => @panic("TODO resolve std.builtin types"), else => unreachable, }; } @@ -5779,17 +5386,6 @@ pub const Type = struct { const tag_ty = mod.intType(.unsigned, bits) catch @panic("TODO: handle OOM here"); return S.fieldWithRange(tag_ty, enum_tag, fields_len, mod); }, - .atomic_order, - .atomic_rmw_op, - .calling_convention, - .address_space, - .float_mode, - .reduce_op, - .modifier, - .prefetch_options, - .export_options, - .extern_options, - => @panic("TODO resolve std.builtin types"), else => unreachable, } } @@ -6102,18 +5698,6 @@ pub const Type = struct { const opaque_obj = ty.cast(Payload.Opaque).?.data; return opaque_obj.srcLoc(mod); }, - .atomic_order, - .atomic_rmw_op, - .calling_convention, - .address_space, - .float_mode, - .reduce_op, - .modifier, - .prefetch_options, - .export_options, - .extern_options, - .type_info, - => unreachable, // needed to call resolveTypeFields first else => return null, } @@ -6150,29 +5734,17 @@ pub const Type = struct { const opaque_obj = ty.cast(Payload.Opaque).?.data; return opaque_obj.owner_decl; }, - .atomic_order, - .atomic_rmw_op, - .calling_convention, - .address_space, - .float_mode, - .reduce_op, - .modifier, - .prefetch_options, - .export_options, - .extern_options, - .type_info, - => unreachable, // These need to be resolved earlier. else => return null, } } pub fn isGenericPoison(ty: Type) bool { - return switch (ty.ip_index) { - .generic_poison_type => true, - .none => ty.tag() == .generic_poison, - else => false, - }; + return ty.ip_index == .generic_poison_type; + } + + pub fn isVarArgsParam(ty: Type) bool { + return ty.ip_index == .none and ty.tag() == .var_args_param; } /// This enum does not directly correspond to `std.builtin.TypeId` because @@ -6195,28 +5767,7 @@ pub const Type = struct { i64, u128, i128, - anyopaque, - bool, - void, - type, - anyerror, - comptime_int, - noreturn, - @"anyframe", - null, - undefined, - enum_literal, - atomic_order, - atomic_rmw_op, - calling_convention, - address_space, - float_mode, - reduce_op, - modifier, - prefetch_options, - export_options, - extern_options, - type_info, + manyptr_u8, manyptr_const_u8, manyptr_const_u8_sentinel_0, @@ -6224,7 +5775,6 @@ pub const Type = struct { const_slice_u8, const_slice_u8_sentinel_0, anyerror_void_error_union, - generic_poison, /// Same as `empty_struct` except it has an empty namespace. empty_struct_literal, /// This is a special value that tracks a set of types that have been stored @@ -6292,39 +5842,17 @@ pub const Type = struct { .i64, .u128, .i128, - .anyopaque, - .bool, - .void, - .type, - .anyerror, - .comptime_int, - .noreturn, - .enum_literal, - .null, - .undefined, + .single_const_pointer_to_comptime_int, .anyerror_void_error_union, .const_slice_u8, .const_slice_u8_sentinel_0, - .generic_poison, .inferred_alloc_const, .inferred_alloc_mut, .empty_struct_literal, .manyptr_u8, .manyptr_const_u8, .manyptr_const_u8_sentinel_0, - .atomic_order, - .atomic_rmw_op, - .calling_convention, - .address_space, - .float_mode, - .reduce_op, - .modifier, - .prefetch_options, - .export_options, - .extern_options, - .type_info, - .@"anyframe", => @compileError("Type Tag " ++ @tagName(t) ++ " has no payload"), .array_u8, @@ -6674,18 +6202,19 @@ pub const Type = struct { pub const @"f80": Type = .{ .ip_index = .f80_type, .legacy = undefined }; pub const @"f128": Type = .{ .ip_index = .f128_type, .legacy = undefined }; - pub const @"bool" = initTag(.bool); + pub const @"bool": Type = .{ .ip_index = .bool_type, .legacy = undefined }; pub const @"usize": Type = .{ .ip_index = .usize_type, .legacy = undefined }; pub const @"isize": Type = .{ .ip_index = .isize_type, .legacy = undefined }; pub const @"comptime_int": Type = .{ .ip_index = .comptime_int_type, .legacy = undefined }; pub const @"comptime_float": Type = .{ .ip_index = .comptime_float_type, .legacy = undefined }; - pub const @"void" = initTag(.void); - pub const @"type" = initTag(.type); - pub const @"anyerror" = initTag(.anyerror); - pub const @"anyopaque" = initTag(.anyopaque); - pub const @"null" = initTag(.null); - pub const @"undefined" = initTag(.undefined); - pub const @"noreturn" = initTag(.noreturn); + pub const @"void": Type = .{ .ip_index = .void_type, .legacy = undefined }; + pub const @"type": Type = .{ .ip_index = .type_type, .legacy = undefined }; + pub const @"anyerror": Type = .{ .ip_index = .anyerror_type, .legacy = undefined }; + pub const @"anyopaque": Type = .{ .ip_index = .anyopaque_type, .legacy = undefined }; + pub const @"anyframe": Type = .{ .ip_index = .anyframe_type, .legacy = undefined }; + pub const @"null": Type = .{ .ip_index = .null_type, .legacy = undefined }; + pub const @"undefined": Type = .{ .ip_index = .undefined_type, .legacy = undefined }; + pub const @"noreturn": Type = .{ .ip_index = .noreturn_type, .legacy = undefined }; pub const @"c_char": Type = .{ .ip_index = .c_char_type, .legacy = undefined }; pub const @"c_short": Type = .{ .ip_index = .c_short_type, .legacy = undefined }; @@ -6698,6 +6227,8 @@ pub const Type = struct { pub const @"c_ulonglong": Type = .{ .ip_index = .c_ulonglong_type, .legacy = undefined }; pub const @"c_longdouble": Type = .{ .ip_index = .c_longdouble_type, .legacy = undefined }; + pub const generic_poison: Type = .{ .ip_index = .generic_poison_type, .legacy = undefined }; + pub const err_int = Type.u16; pub fn ptr(arena: Allocator, mod: *Module, data: Payload.Pointer.Data) !Type { diff --git a/src/value.zig b/src/value.zig index b0484dfc76..2f9f395017 100644 --- a/src/value.zig +++ b/src/value.zig @@ -991,26 +991,26 @@ pub const Value = struct { .null_type => Type.null, .undefined_type => Type.undefined, .single_const_pointer_to_comptime_int_type => Type.initTag(.single_const_pointer_to_comptime_int), - .anyframe_type => Type.initTag(.@"anyframe"), + .anyframe_type => Type.@"anyframe", .const_slice_u8_type => Type.initTag(.const_slice_u8), .const_slice_u8_sentinel_0_type => Type.initTag(.const_slice_u8_sentinel_0), .anyerror_void_error_union_type => Type.initTag(.anyerror_void_error_union), - .generic_poison_type => Type.initTag(.generic_poison), - .enum_literal_type => Type.initTag(.enum_literal), + .generic_poison_type => .{ .ip_index = .generic_poison_type, .legacy = undefined }, + .enum_literal_type => .{ .ip_index = .enum_literal_type, .legacy = undefined }, .manyptr_u8_type => Type.initTag(.manyptr_u8), .manyptr_const_u8_type => Type.initTag(.manyptr_const_u8), .manyptr_const_u8_sentinel_0_type => Type.initTag(.manyptr_const_u8_sentinel_0), - .atomic_order_type => Type.initTag(.atomic_order), - .atomic_rmw_op_type => Type.initTag(.atomic_rmw_op), - .calling_convention_type => Type.initTag(.calling_convention), - .address_space_type => Type.initTag(.address_space), - .float_mode_type => Type.initTag(.float_mode), - .reduce_op_type => Type.initTag(.reduce_op), - .modifier_type => Type.initTag(.modifier), - .prefetch_options_type => Type.initTag(.prefetch_options), - .export_options_type => Type.initTag(.export_options), - .extern_options_type => Type.initTag(.extern_options), - .type_info_type => Type.initTag(.type_info), + .atomic_order_type => .{ .ip_index = .atomic_order_type, .legacy = undefined }, + .atomic_rmw_op_type => .{ .ip_index = .atomic_rmw_op_type, .legacy = undefined }, + .calling_convention_type => .{ .ip_index = .calling_convention_type, .legacy = undefined }, + .address_space_type => .{ .ip_index = .address_space_type, .legacy = undefined }, + .float_mode_type => .{ .ip_index = .float_mode_type, .legacy = undefined }, + .reduce_op_type => .{ .ip_index = .reduce_op_type, .legacy = undefined }, + .modifier_type => .{ .ip_index = .call_modifier_type, .legacy = undefined }, + .prefetch_options_type => .{ .ip_index = .prefetch_options_type, .legacy = undefined }, + .export_options_type => .{ .ip_index = .export_options_type, .legacy = undefined }, + .extern_options_type => .{ .ip_index = .extern_options_type, .legacy = undefined }, + .type_info_type => .{ .ip_index = .type_info_type, .legacy = undefined }, else => unreachable, };