From 93a5bd262defe4c09a617a4ecc68340e20a2b20b Mon Sep 17 00:00:00 2001 From: mlugg Date: Sun, 18 Aug 2024 13:35:35 +0100 Subject: [PATCH 1/4] frontend: removed resolved IES data for outdated functions Without this, incremental updates which would change inferred error sets fail, since they assume the IES is resolved and equals the old set, resulting in false positive compile errors when e.g. coercing to an IES. --- src/InternPool.zig | 8 ++++++++ src/Sema.zig | 5 +++-- src/Zcu.zig | 26 ++++++++++++++++++++++++++ src/Zcu/PerThread.zig | 5 ++++- 4 files changed, 41 insertions(+), 3 deletions(-) diff --git a/src/InternPool.zig b/src/InternPool.zig index d0dc16c47d128db95cbc1965d70fe484aca8aa36..99f937cacfa4d98c4c2b1312e0c47accd3e4a7b0 100644 --- a/src/InternPool.zig +++ b/src/InternPool.zig @@ -2160,6 +2160,14 @@ pub const Key = union(enum) { pub fn resolvedErrorSetUnordered(func: Func, ip: *const InternPool) Index { return @atomicLoad(Index, func.resolvedErrorSetPtr(@constCast(ip)), .unordered); } + + pub fn setResolvedErrorSet(func: Func, ip: *InternPool, ies: Index) void { + const extra_mutex = &ip.getLocal(func.tid).mutate.extra.mutex; + extra_mutex.lock(); + defer extra_mutex.unlock(); + + @atomicStore(Index, func.resolvedErrorSetPtr(ip), ies, .release); + } }; pub const Int = struct { diff --git a/src/Sema.zig b/src/Sema.zig index 7930c8f08002ec35a1fbecbd7de8094e4dde587b..756e0ac9cab590b36518c8116f3495ab866f67fd 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -32527,6 +32527,7 @@ fn analyzeIsNonErrComptimeOnly( // 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. + try mod.maybeUnresolveIes(func_index); switch (ip.funcIesResolvedUnordered(func_index)) { .anyerror_type => break :blk, .none => {}, @@ -33596,6 +33597,7 @@ fn wrapErrorUnionSet( .inferred_error_set_type => |func_index| ok: { // We carefully do this in an order that avoids unnecessarily // resolving the destination error set type. + try mod.maybeUnresolveIes(func_index); switch (ip.funcIesResolvedUnordered(func_index)) { .anyerror_type => break :ok, .none => if (.ok == try sema.coerceInMemoryAllowedErrorSets(block, dest_err_set_ty, inst_ty, inst_src, inst_src)) { @@ -35853,8 +35855,7 @@ fn resolveInferredErrorSet( try sema.declareDependency(.{ .interned = func_index }); // resolved IES - // TODO: during an incremental update this might not be `.none`, but the - // function might be out-of-date! + try zcu.maybeUnresolveIes(func_index); const resolved_ty = func.resolvedErrorSetUnordered(ip); if (resolved_ty != .none) return resolved_ty; diff --git a/src/Zcu.zig b/src/Zcu.zig index a47979bf60e5522369eff94ef4f068fa21cc6310..53ad80444e70660ea4af91828a43fb224e6e367b 100644 --- a/src/Zcu.zig +++ b/src/Zcu.zig @@ -3468,3 +3468,29 @@ fn formatDependee(data: struct { dependee: InternPool.Dependee, zcu: *Zcu }, com }, } } + +/// Given the `InternPool.Index` of a function, set its resolved IES to `.none` if it +/// may be outdated. `Sema` should do this before ever loading a resolved IES. +pub fn maybeUnresolveIes(zcu: *Zcu, func_index: InternPool.Index) !void { + const unit = AnalUnit.wrap(.{ .func = func_index }); + if (zcu.outdated.contains(unit) or zcu.potentially_outdated.contains(unit)) { + // We're consulting the resolved IES now, but the function is outdated, so its + // IES may have changed. We have to assume the IES is outdated and set the resolved + // set back to `.none`. + // + // This will cause `PerThread.analyzeFnBody` to mark the IES as outdated when it's + // eventually hit. + // + // Since the IES needs to be resolved, the function body will now definitely need + // re-analysis (even if the IES turns out to be the same!), so mark it as + // definitely-outdated if it's only PO. + if (zcu.potentially_outdated.fetchSwapRemove(unit)) |kv| { + const gpa = zcu.gpa; + try zcu.outdated.putNoClobber(gpa, unit, kv.value); + if (kv.value == 0) { + try zcu.outdated_ready.put(gpa, unit, {}); + } + } + zcu.intern_pool.funcSetIesResolved(func_index, .none); + } +} diff --git a/src/Zcu/PerThread.zig b/src/Zcu/PerThread.zig index 700d8708b1acbc5b7b36ad4eba01de92a53e4391..88bc318b3cf49ed43762cee8a369f65028a5eda9 100644 --- a/src/Zcu/PerThread.zig +++ b/src/Zcu/PerThread.zig @@ -2072,6 +2072,9 @@ fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index) Zcu.SemaError! errdefer _ = zcu.analysis_in_progress.swapRemove(anal_unit); func.setAnalysisState(ip, .analyzed); + if (func.analysisUnordered(ip).inferred_error_set) { + func.setResolvedErrorSet(ip, .none); + } // This is the `Cau` corresponding to the `declaration` instruction which the function or its generic owner originates from. const decl_cau = ip.getCau(cau: { @@ -2278,7 +2281,7 @@ fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index) Zcu.SemaError! else => |e| return e, }; assert(ies.resolved != .none); - ip.funcSetIesResolved(func_index, ies.resolved); + func.setResolvedErrorSet(ip, ies.resolved); } assert(zcu.analysis_in_progress.swapRemove(anal_unit)); -- 2.54.0 From b745fee1f8dddd92c7d112cd7440e6b540458051 Mon Sep 17 00:00:00 2001 From: mlugg Date: Sun, 18 Aug 2024 15:59:24 +0100 Subject: [PATCH 2/4] frontend: handle incremental updates of replaced runtime functions --- src/InternPool.zig | 6 +----- src/Zcu/PerThread.zig | 40 +++++++++++++++++----------------------- 2 files changed, 18 insertions(+), 28 deletions(-) diff --git a/src/InternPool.zig b/src/InternPool.zig index 99f937cacfa4d98c4c2b1312e0c47accd3e4a7b0..6a620b70fb183e4a3f0d6c3a8baaf68d05292b47 100644 --- a/src/InternPool.zig +++ b/src/InternPool.zig @@ -7108,7 +7108,7 @@ fn getOrPutKeyEnsuringAdditionalCapacity( const index = entry.acquire(); if (index == .none) break; if (entry.hash != hash) continue; - if (ip.isRemoved(index)) continue; + if (index.unwrap(ip).getTag(ip) == .removed) continue; if (ip.indexToKey(index).eql(key, ip)) return .{ .existing = index }; } shard.mutate.map.mutex.lock(); @@ -12311,7 +12311,3 @@ pub fn getErrorValue( pub fn getErrorValueIfExists(ip: *const InternPool, name: NullTerminatedString) ?Zcu.ErrorInt { return @intFromEnum(ip.global_error_set.getErrorValueIfExists(name) orelse return null); } - -pub fn isRemoved(ip: *const InternPool, ty: Index) bool { - return ty.unwrap(ip).getTag(ip) == .removed; -} diff --git a/src/Zcu/PerThread.zig b/src/Zcu/PerThread.zig index 88bc318b3cf49ed43762cee8a369f65028a5eda9..bc6d9457828038eb9b5236b3afca8b13e049aae9 100644 --- a/src/Zcu/PerThread.zig +++ b/src/Zcu/PerThread.zig @@ -734,31 +734,25 @@ fn ensureFuncBodyAnalyzedInner( const func = zcu.funcInfo(func_index); const anal_unit = AnalUnit.wrap(.{ .func = func_index }); - // Here's an interesting question: is this function actually valid? - // Maybe the signature changed, so we'll end up creating a whole different `func` - // in the InternPool, and this one is a waste of time to analyze. Worse, we'd be - // analyzing new ZIR with old data, and get bogus errors. They would be unused, - // but they would still hang around internally! So, let's detect this case. - // For function decls, we must ensure the declaration's `Cau` is up-to-date, and - // check if `func_index` was removed by that update. - // For function instances, we do that process on the generic owner. + // Make sure that this function is still owned by the same `Nav`. Otherwise, analyzing + // it would be a waste of time in the best case, and could cause codegen to give bogus + // results in the worst case. - try pt.ensureCauAnalyzed(cau: { - const func_nav = if (func.generic_owner == .none) - func.owner_nav - else - zcu.funcInfo(func.generic_owner).owner_nav; - - break :cau ip.getNav(func_nav).analysis_owner.unwrap().?; - }); - - if (ip.isRemoved(func_index) or (func.generic_owner != .none and ip.isRemoved(func.generic_owner))) { - if (func_outdated) { - try zcu.markDependeeOutdated(.marked_po, .{ .interned = func_index }); // IES + if (func.generic_owner == .none) { + try pt.ensureCauAnalyzed(ip.getNav(func.owner_nav).analysis_owner.unwrap().?); + if (ip.getNav(func.owner_nav).status.resolved.val != func_index) { + // This function is no longer referenced! There's no point in re-analyzing it. + // Just mark a transitive failure and move on. + return error.AnalysisFail; + } + } else { + const go_nav = zcu.funcInfo(func.generic_owner).owner_nav; + try pt.ensureCauAnalyzed(ip.getNav(go_nav).analysis_owner.unwrap().?); + if (ip.getNav(go_nav).status.resolved.val != func.generic_owner) { + // The generic owner is no longer referenced, so this function is also unreferenced. + // There's no point in re-analyzing it. Just mark a transitive failure and move on. + return error.AnalysisFail; } - ip.removeDependenciesForDepender(gpa, AnalUnit.wrap(.{ .func = func_index })); - ip.remove(pt.tid, func_index); - @panic("TODO: remove orphaned function from binary"); } // We'll want to remember what the IES used to be before the update for -- 2.54.0 From a239d8d4e2c0e5a7f3eb4b9973f869afdb3bbe05 Mon Sep 17 00:00:00 2001 From: mlugg Date: Sun, 18 Aug 2024 16:01:29 +0100 Subject: [PATCH 3/4] test: add incremental case --- test/incremental/type_becomes_comptime_only | 39 +++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 test/incremental/type_becomes_comptime_only diff --git a/test/incremental/type_becomes_comptime_only b/test/incremental/type_becomes_comptime_only new file mode 100644 index 0000000000000000000000000000000000000000..2dfa556e879437a5e42dded793ca45e375f3509f --- /dev/null +++ b/test/incremental/type_becomes_comptime_only @@ -0,0 +1,39 @@ +#target=x86_64-linux +#update=initial version +#file=main.zig +const SomeType = u32; +const S = struct { + x: SomeType, + fn foo(_: S) void {} +}; +pub fn main() void { + const s: S = .{ .x = 456 }; + s.foo(); +} +#expect_stdout="" + +#update=make S comptime-only +#file=main.zig +const SomeType = comptime_int; +const S = struct { + x: SomeType, + fn foo(_: S) void {} +}; +pub fn main() void { + const s: S = .{ .x = 456 }; + s.foo(); +} +#expect_stdout="" + +#update=make S runtime again +#file=main.zig +const SomeType = u16; +const S = struct { + x: SomeType, + fn foo(_: S) void {} +}; +pub fn main() void { + const s: S = .{ .x = 456 }; + s.foo(); +} +#expect_stdout="" -- 2.54.0 From de49a9a17352a36a0888b03905f207b0584fc269 Mon Sep 17 00:00:00 2001 From: mlugg Date: Sun, 18 Aug 2024 17:57:28 +0100 Subject: [PATCH 4/4] Zir: add instructions to fetch std.builtin types This replaces the constant `Zir.Inst.Ref` tags (and the analagous tags in `Air.Inst.Ref`, `InternPool.Index`) referring to types in `std.builtin` with a ZIR instruction `extended(builtin_type(...))` which instructs Sema to fetch such a type, effectively as if it were a shorthand for the ZIR for `@import("std").builtin.xyz`. Previously, this was achieved through constant tags in `Ref`. The analagous `InternPool` indices began as `simple_type` values, and were later rewritten to the correct type information. This system was kind of brittle, and more importantly, isn't compatible with incremental compilation of std, since incremental compilation relies on the ability to recreate types at different indices when they change. Replacing the old system with this instruction slightly increases the size of ZIR, but it simplifies logic and allows incremental compilation to work correctly on the standard library. This shouldn't have a significant impact on ZIR size or compiler performance, but I will take measurements in the PR to confirm this. --- lib/std/zig/AstGen.zig | 103 ++++++++++++++++-------------- lib/std/zig/Zir.zig | 38 ++++++----- src/Air.zig | 13 ---- src/InternPool.zig | 140 +---------------------------------------- src/Sema.zig | 91 +++++++++++++++------------ src/Type.zig | 130 +------------------------------------- src/Zcu/PerThread.zig | 82 +++--------------------- src/codegen/c/Type.zig | 24 +------ src/codegen/llvm.zig | 2 - src/link/Dwarf.zig | 14 +---- src/print_zir.zig | 7 +++ 11 files changed, 152 insertions(+), 492 deletions(-) diff --git a/lib/std/zig/AstGen.zig b/lib/std/zig/AstGen.zig index d73c83bb416684d845300117eaee1c7bdb24cf2b..d0f1c73fc817057daef61dd5067a7afc4fbb9791 100644 --- a/lib/std/zig/AstGen.zig +++ b/lib/std/zig/AstGen.zig @@ -366,7 +366,6 @@ const ResultInfo = struct { }; const coerced_align_ri: ResultInfo = .{ .rl = .{ .coerced_ty = .u29_type } }; -const coerced_addrspace_ri: ResultInfo = .{ .rl = .{ .coerced_ty = .address_space_type } }; const coerced_linksection_ri: ResultInfo = .{ .rl = .{ .coerced_ty = .slice_const_u8_type } }; const coerced_type_ri: ResultInfo = .{ .rl = .{ .coerced_ty = .type_type } }; const coerced_bool_ri: ResultInfo = .{ .rl = .{ .coerced_ty = .bool_type } }; @@ -1387,7 +1386,7 @@ fn fnProtoExpr( try expr( &block_scope, scope, - .{ .rl = .{ .coerced_ty = .calling_convention_type } }, + .{ .rl = .{ .coerced_ty = try block_scope.addBuiltinValue(fn_proto.ast.callconv_expr, .calling_convention) } }, fn_proto.ast.callconv_expr, ) else @@ -3804,7 +3803,8 @@ fn ptrType( gz.astgen.source_line = source_line; gz.astgen.source_column = source_column; - addrspace_ref = try expr(gz, scope, coerced_addrspace_ri, ptr_info.ast.addrspace_node); + const addrspace_ty = try gz.addBuiltinValue(ptr_info.ast.addrspace_node, .address_space); + addrspace_ref = try expr(gz, scope, .{ .rl = .{ .coerced_ty = addrspace_ty } }, ptr_info.ast.addrspace_node); trailing_count += 1; } if (ptr_info.ast.align_node != 0) { @@ -4202,7 +4202,8 @@ fn fnDecl( var addrspace_gz = decl_gz.makeSubBlock(params_scope); defer addrspace_gz.unstack(); const addrspace_ref: Zir.Inst.Ref = if (fn_proto.ast.addrspace_expr == 0) .none else inst: { - const inst = try expr(&decl_gz, params_scope, coerced_addrspace_ri, fn_proto.ast.addrspace_expr); + const addrspace_ty = try decl_gz.addBuiltinValue(fn_proto.ast.addrspace_expr, .address_space); + const inst = try expr(&decl_gz, params_scope, .{ .rl = .{ .coerced_ty = addrspace_ty } }, fn_proto.ast.addrspace_expr); if (addrspace_gz.instructionsSlice().len == 0) { // In this case we will send a len=0 body which can be encoded more efficiently. break :inst inst; @@ -4235,9 +4236,9 @@ fn fnDecl( ); } const inst = try expr( - &decl_gz, + &cc_gz, params_scope, - .{ .rl = .{ .coerced_ty = .calling_convention_type } }, + .{ .rl = .{ .coerced_ty = try cc_gz.addBuiltinValue(fn_proto.ast.callconv_expr, .calling_convention) } }, fn_proto.ast.callconv_expr, ); if (cc_gz.instructionsSlice().len == 0) { @@ -4247,10 +4248,13 @@ fn fnDecl( _ = try cc_gz.addBreak(.break_inline, @enumFromInt(0), inst); break :blk inst; } else if (is_extern) { - // note: https://github.com/ziglang/zig/issues/5269 - break :blk .calling_convention_c; + const inst = try cc_gz.addBuiltinValue(decl_node, .calling_convention_c); + _ = try cc_gz.addBreak(.break_inline, @enumFromInt(0), inst); + break :blk inst; } else if (has_inline_keyword) { - break :blk .calling_convention_inline; + const inst = try cc_gz.addBuiltinValue(decl_node, .calling_convention_inline); + _ = try cc_gz.addBreak(.break_inline, @enumFromInt(0), inst); + break :blk inst; } else { break :blk .none; } @@ -4525,7 +4529,8 @@ fn globalVarDecl( var addrspace_gz = linksection_gz.makeSubBlock(scope); if (var_decl.ast.addrspace_node != 0) { - const addrspace_inst = try fullBodyExpr(&addrspace_gz, &addrspace_gz.base, coerced_addrspace_ri, var_decl.ast.addrspace_node); + const addrspace_ty = try addrspace_gz.addBuiltinValue(var_decl.ast.addrspace_node, .address_space); + const addrspace_inst = try fullBodyExpr(&addrspace_gz, &addrspace_gz.base, .{ .rl = .{ .coerced_ty = addrspace_ty } }, var_decl.ast.addrspace_node); _ = try addrspace_gz.addBreakWithSrcNode(.break_inline, decl_inst, addrspace_inst, node); } @@ -9169,6 +9174,7 @@ fn builtinCall( // zig fmt: on .@"export" => { + const export_options_ty = try gz.addBuiltinValue(node, .export_options); const node_tags = tree.nodes.items(.tag); const node_datas = tree.nodes.items(.data); // This function causes a Decl to be exported. The first parameter is not an expression, @@ -9192,7 +9198,7 @@ fn builtinCall( local_val.used = ident_token; _ = try gz.addPlNode(.export_value, node, Zir.Inst.ExportValue{ .operand = local_val.inst, - .options = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = .export_options_type } }, params[1]), + .options = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = export_options_ty } }, params[1]), }); return rvalue(gz, ri, .void_value, node); } @@ -9207,7 +9213,7 @@ fn builtinCall( const loaded = try gz.addUnNode(.load, local_ptr.ptr, node); _ = try gz.addPlNode(.export_value, node, Zir.Inst.ExportValue{ .operand = loaded, - .options = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = .export_options_type } }, params[1]), + .options = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = export_options_ty } }, params[1]), }); return rvalue(gz, ri, .void_value, node); } @@ -9245,7 +9251,7 @@ fn builtinCall( }, else => return astgen.failNode(params[0], "symbol to export must identify a declaration", .{}), } - const options = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = .export_options_type } }, params[1]); + const options = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = export_options_ty } }, params[1]); _ = try gz.addPlNode(.@"export", node, Zir.Inst.Export{ .namespace = namespace, .decl_name = decl_name, @@ -9255,7 +9261,8 @@ fn builtinCall( }, .@"extern" => { const type_inst = try typeExpr(gz, scope, params[0]); - const options = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = .extern_options_type } }, params[1]); + const extern_options_ty = try gz.addBuiltinValue(node, .extern_options); + const options = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = extern_options_ty } }, params[1]); const result = try gz.addExtendedPayload(.builtin_extern, Zir.Inst.BinNode{ .node = gz.nodeIndexToRelative(node), .lhs = type_inst, @@ -9264,7 +9271,8 @@ fn builtinCall( return rvalue(gz, ri, result, node); }, .fence => { - const order = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .atomic_order_type } }, params[0]); + const atomic_order_ty = try gz.addBuiltinValue(node, .atomic_order); + const order = try expr(gz, scope, .{ .rl = .{ .coerced_ty = atomic_order_ty } }, params[0]); _ = try gz.addExtendedPayload(.fence, Zir.Inst.UnNode{ .node = gz.nodeIndexToRelative(node), .operand = order, @@ -9272,7 +9280,8 @@ fn builtinCall( return rvalue(gz, ri, .void_value, node); }, .set_float_mode => { - const order = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .float_mode_type } }, params[0]); + const float_mode_ty = try gz.addBuiltinValue(node, .float_mode); + const order = try expr(gz, scope, .{ .rl = .{ .coerced_ty = float_mode_ty } }, params[0]); _ = try gz.addExtendedPayload(.set_float_mode, Zir.Inst.UnNode{ .node = gz.nodeIndexToRelative(node), .operand = order, @@ -9365,7 +9374,8 @@ fn builtinCall( }, .Type => { - const operand = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .type_info_type } }, params[0]); + const type_info_ty = try gz.addBuiltinValue(node, .type_info); + const operand = try expr(gz, scope, .{ .rl = .{ .coerced_ty = type_info_ty } }, params[0]); const gpa = gz.astgen.gpa; @@ -9502,7 +9512,8 @@ fn builtinCall( return rvalue(gz, ri, result, node); }, .reduce => { - const op = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .reduce_op_type } }, params[0]); + const reduce_op_ty = try gz.addBuiltinValue(node, .reduce_op); + const op = try expr(gz, scope, .{ .rl = .{ .coerced_ty = reduce_op_ty } }, params[0]); const scalar = try expr(gz, scope, .{ .rl = .none }, params[1]); const result = try gz.addPlNode(.reduce, node, Zir.Inst.Bin{ .lhs = op, @@ -9517,34 +9528,38 @@ fn builtinCall( .shl_with_overflow => return overflowArithmetic(gz, scope, ri, node, params, .shl_with_overflow), .atomic_load => { + const atomic_order_type = try gz.addBuiltinValue(node, .atomic_order); const result = try gz.addPlNode(.atomic_load, node, Zir.Inst.AtomicLoad{ // zig fmt: off - .elem_type = try typeExpr(gz, scope, params[0]), - .ptr = try expr (gz, scope, .{ .rl = .none }, params[1]), - .ordering = try expr (gz, scope, .{ .rl = .{ .coerced_ty = .atomic_order_type } }, params[2]), + .elem_type = try typeExpr(gz, scope, params[0]), + .ptr = try expr (gz, scope, .{ .rl = .none }, params[1]), + .ordering = try expr (gz, scope, .{ .rl = .{ .coerced_ty = atomic_order_type } }, params[2]), // zig fmt: on }); return rvalue(gz, ri, result, node); }, .atomic_rmw => { + const atomic_order_type = try gz.addBuiltinValue(node, .atomic_order); + const atomic_rmw_op_type = try gz.addBuiltinValue(node, .atomic_rmw_op); const int_type = try typeExpr(gz, scope, params[0]); const result = try gz.addPlNode(.atomic_rmw, node, Zir.Inst.AtomicRmw{ // zig fmt: off - .ptr = try expr(gz, scope, .{ .rl = .none }, params[1]), - .operation = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .atomic_rmw_op_type } }, params[2]), - .operand = try expr(gz, scope, .{ .rl = .{ .ty = int_type } }, params[3]), - .ordering = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .atomic_order_type } }, params[4]), + .ptr = try expr(gz, scope, .{ .rl = .none }, params[1]), + .operation = try expr(gz, scope, .{ .rl = .{ .coerced_ty = atomic_rmw_op_type } }, params[2]), + .operand = try expr(gz, scope, .{ .rl = .{ .ty = int_type } }, params[3]), + .ordering = try expr(gz, scope, .{ .rl = .{ .coerced_ty = atomic_order_type } }, params[4]), // zig fmt: on }); return rvalue(gz, ri, result, node); }, .atomic_store => { + const atomic_order_type = try gz.addBuiltinValue(node, .atomic_order); const int_type = try typeExpr(gz, scope, params[0]); _ = try gz.addPlNode(.atomic_store, node, Zir.Inst.AtomicStore{ // zig fmt: off - .ptr = try expr(gz, scope, .{ .rl = .none }, params[1]), - .operand = try expr(gz, scope, .{ .rl = .{ .ty = int_type } }, params[2]), - .ordering = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .atomic_order_type } }, params[3]), + .ptr = try expr(gz, scope, .{ .rl = .none }, params[1]), + .operand = try expr(gz, scope, .{ .rl = .{ .ty = int_type } }, params[2]), + .ordering = try expr(gz, scope, .{ .rl = .{ .coerced_ty = atomic_order_type } }, params[3]), // zig fmt: on }); return rvalue(gz, ri, .void_value, node); @@ -9562,7 +9577,8 @@ fn builtinCall( return rvalue(gz, ri, result, node); }, .call => { - const modifier = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = .call_modifier_type } }, params[0]); + const call_modifier_ty = try gz.addBuiltinValue(node, .call_modifier); + const modifier = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = call_modifier_ty } }, params[0]); const callee = try expr(gz, scope, .{ .rl = .none }, params[1]); const args = try expr(gz, scope, .{ .rl = .none }, params[2]); const result = try gz.addPlNode(.builtin_call, node, Zir.Inst.BuiltinCall{ @@ -9641,8 +9657,9 @@ fn builtinCall( return rvalue(gz, ri, result, node); }, .prefetch => { + const prefetch_options_ty = try gz.addBuiltinValue(node, .prefetch_options); const ptr = try expr(gz, scope, .{ .rl = .none }, params[0]); - const options = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = .prefetch_options_type } }, params[1]); + const options = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = prefetch_options_ty } }, params[1]); _ = try gz.addExtendedPayload(.prefetch, Zir.Inst.BinNode{ .node = gz.nodeIndexToRelative(node), .lhs = ptr, @@ -9812,14 +9829,15 @@ fn cmpxchg( small: u16, ) InnerError!Zir.Inst.Ref { const int_type = try typeExpr(gz, scope, params[0]); + const atomic_order_type = try gz.addBuiltinValue(node, .atomic_order); const result = try gz.addExtendedPayloadSmall(.cmpxchg, small, Zir.Inst.Cmpxchg{ // zig fmt: off .node = gz.nodeIndexToRelative(node), - .ptr = try expr(gz, scope, .{ .rl = .none }, params[1]), - .expected_value = try expr(gz, scope, .{ .rl = .{ .ty = int_type } }, params[2]), - .new_value = try expr(gz, scope, .{ .rl = .{ .coerced_ty = int_type } }, params[3]), - .success_order = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .atomic_order_type } }, params[4]), - .failure_order = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .atomic_order_type } }, params[5]), + .ptr = try expr(gz, scope, .{ .rl = .none }, params[1]), + .expected_value = try expr(gz, scope, .{ .rl = .{ .ty = int_type } }, params[2]), + .new_value = try expr(gz, scope, .{ .rl = .{ .coerced_ty = int_type } }, params[3]), + .success_order = try expr(gz, scope, .{ .rl = .{ .coerced_ty = atomic_order_type } }, params[4]), + .failure_order = try expr(gz, scope, .{ .rl = .{ .coerced_ty = atomic_order_type } }, params[5]), // zig fmt: on }); return rvalue(gz, ri, result, node); @@ -11106,17 +11124,6 @@ fn rvalueInner( as_ty | @intFromEnum(Zir.Inst.Ref.null_type), as_ty | @intFromEnum(Zir.Inst.Ref.undefined_type), as_ty | @intFromEnum(Zir.Inst.Ref.enum_literal_type), - as_ty | @intFromEnum(Zir.Inst.Ref.atomic_order_type), - as_ty | @intFromEnum(Zir.Inst.Ref.atomic_rmw_op_type), - as_ty | @intFromEnum(Zir.Inst.Ref.calling_convention_type), - as_ty | @intFromEnum(Zir.Inst.Ref.address_space_type), - as_ty | @intFromEnum(Zir.Inst.Ref.float_mode_type), - as_ty | @intFromEnum(Zir.Inst.Ref.reduce_op_type), - as_ty | @intFromEnum(Zir.Inst.Ref.call_modifier_type), - as_ty | @intFromEnum(Zir.Inst.Ref.prefetch_options_type), - as_ty | @intFromEnum(Zir.Inst.Ref.export_options_type), - as_ty | @intFromEnum(Zir.Inst.Ref.extern_options_type), - as_ty | @intFromEnum(Zir.Inst.Ref.type_info_type), as_ty | @intFromEnum(Zir.Inst.Ref.manyptr_u8_type), as_ty | @intFromEnum(Zir.Inst.Ref.manyptr_const_u8_type), as_ty | @intFromEnum(Zir.Inst.Ref.manyptr_const_u8_sentinel_0_type), @@ -12572,6 +12579,10 @@ const GenZir = struct { return new_index; } + fn addBuiltinValue(gz: *GenZir, src_node: Ast.Node.Index, val: Zir.Inst.BuiltinValue) !Zir.Inst.Ref { + return addExtendedNodeSmall(gz, .builtin_value, src_node, @intFromEnum(val)); + } + fn addExtendedPayload(gz: *GenZir, opcode: Zir.Inst.Extended, extra: anytype) !Zir.Inst.Ref { return addExtendedPayloadSmall(gz, opcode, undefined, extra); } diff --git a/lib/std/zig/Zir.zig b/lib/std/zig/Zir.zig index 7349677a22aa06315aa88a1d455d155234fd174d..8318a5a345a7c9976ee1a467d69fbf369a239c9e 100644 --- a/lib/std/zig/Zir.zig +++ b/lib/std/zig/Zir.zig @@ -2055,6 +2055,10 @@ pub const Inst = struct { /// Guaranteed to not have the `ptr_cast` flag. /// Uses the `pl_node` union field with payload `FieldParentPtr`. field_parent_ptr, + /// Get a type or value from `std.builtin`. + /// `operand` is `src_node: i32`. + /// `small` is an `Inst.BuiltinValue`. + builtin_value, pub const InstData = struct { opcode: Extended, @@ -2071,7 +2075,7 @@ pub const Inst = struct { ref_start_index = static_len, _, - pub const static_len = 84; + pub const static_len = 71; pub fn toRef(i: Index) Inst.Ref { return @enumFromInt(@intFromEnum(Index.ref_start_index) + @intFromEnum(i)); @@ -2148,17 +2152,6 @@ pub const Inst = struct { null_type, undefined_type, enum_literal_type, - atomic_order_type, - atomic_rmw_op_type, - calling_convention_type, - address_space_type, - float_mode_type, - reduce_op_type, - call_modifier_type, - prefetch_options_type, - export_options_type, - extern_options_type, - type_info_type, manyptr_u8_type, manyptr_const_u8_type, manyptr_const_u8_sentinel_0_type, @@ -2179,8 +2172,6 @@ pub const Inst = struct { one_u8, four_u8, negative_one, - calling_convention_c, - calling_convention_inline, void_value, unreachable_value, null_value, @@ -3146,6 +3137,24 @@ pub const Inst = struct { } }; + pub const BuiltinValue = enum(u16) { + // Types + atomic_order, + atomic_rmw_op, + calling_convention, + address_space, + float_mode, + reduce_op, + call_modifier, + prefetch_options, + export_options, + extern_options, + type_info, + // Values + calling_convention_c, + calling_convention_inline, + }; + /// Trailing: /// 0. tag_type: Ref, // if has_tag_type /// 1. captures_len: u32, // if has_captures_len @@ -3977,6 +3986,7 @@ fn findDeclsInner( .restore_err_ret_index, .closure_get, .field_parent_ptr, + .builtin_value, => return, // `@TypeOf` has a body. diff --git a/src/Air.zig b/src/Air.zig index 2144dd3d61a95171888d7a29e65b535f57abe0cc..aa821dc420bdee7a78f62e64389b82264c65ab6d 100644 --- a/src/Air.zig +++ b/src/Air.zig @@ -938,17 +938,6 @@ pub const Inst = struct { null_type = @intFromEnum(InternPool.Index.null_type), undefined_type = @intFromEnum(InternPool.Index.undefined_type), enum_literal_type = @intFromEnum(InternPool.Index.enum_literal_type), - atomic_order_type = @intFromEnum(InternPool.Index.atomic_order_type), - atomic_rmw_op_type = @intFromEnum(InternPool.Index.atomic_rmw_op_type), - calling_convention_type = @intFromEnum(InternPool.Index.calling_convention_type), - address_space_type = @intFromEnum(InternPool.Index.address_space_type), - float_mode_type = @intFromEnum(InternPool.Index.float_mode_type), - reduce_op_type = @intFromEnum(InternPool.Index.reduce_op_type), - call_modifier_type = @intFromEnum(InternPool.Index.call_modifier_type), - prefetch_options_type = @intFromEnum(InternPool.Index.prefetch_options_type), - export_options_type = @intFromEnum(InternPool.Index.export_options_type), - extern_options_type = @intFromEnum(InternPool.Index.extern_options_type), - type_info_type = @intFromEnum(InternPool.Index.type_info_type), manyptr_u8_type = @intFromEnum(InternPool.Index.manyptr_u8_type), manyptr_const_u8_type = @intFromEnum(InternPool.Index.manyptr_const_u8_type), manyptr_const_u8_sentinel_0_type = @intFromEnum(InternPool.Index.manyptr_const_u8_sentinel_0_type), @@ -969,8 +958,6 @@ pub const Inst = struct { one_u8 = @intFromEnum(InternPool.Index.one_u8), four_u8 = @intFromEnum(InternPool.Index.four_u8), negative_one = @intFromEnum(InternPool.Index.negative_one), - calling_convention_c = @intFromEnum(InternPool.Index.calling_convention_c), - calling_convention_inline = @intFromEnum(InternPool.Index.calling_convention_inline), void_value = @intFromEnum(InternPool.Index.void_value), unreachable_value = @intFromEnum(InternPool.Index.unreachable_value), null_value = @intFromEnum(InternPool.Index.null_value), diff --git a/src/InternPool.zig b/src/InternPool.zig index 6a620b70fb183e4a3f0d6c3a8baaf68d05292b47..d953755987921e80512ae5e59e9c970ccbdcc171 100644 --- a/src/InternPool.zig +++ b/src/InternPool.zig @@ -4411,17 +4411,6 @@ pub const Index = enum(u32) { null_type, undefined_type, enum_literal_type, - atomic_order_type, - atomic_rmw_op_type, - calling_convention_type, - address_space_type, - float_mode_type, - reduce_op_type, - call_modifier_type, - prefetch_options_type, - export_options_type, - extern_options_type, - type_info_type, manyptr_u8_type, manyptr_const_u8_type, manyptr_const_u8_sentinel_0_type, @@ -4454,10 +4443,6 @@ pub const Index = enum(u32) { four_u8, /// `-1` (comptime_int) negative_one, - /// `std.builtin.CallingConvention.C` - calling_convention_c, - /// `std.builtin.CallingConvention.Inline` - calling_convention_inline, /// `{}` void_value, /// `unreachable` (noreturn type) @@ -4837,17 +4822,6 @@ pub const static_keys = [_]Key{ .{ .simple_type = .null }, .{ .simple_type = .undefined }, .{ .simple_type = .enum_literal }, - .{ .simple_type = .atomic_order }, - .{ .simple_type = .atomic_rmw_op }, - .{ .simple_type = .calling_convention }, - .{ .simple_type = .address_space }, - .{ .simple_type = .float_mode }, - .{ .simple_type = .reduce_op }, - .{ .simple_type = .call_modifier }, - .{ .simple_type = .prefetch_options }, - .{ .simple_type = .export_options }, - .{ .simple_type = .extern_options }, - .{ .simple_type = .type_info }, // [*]u8 .{ .ptr_type = .{ @@ -4876,7 +4850,7 @@ pub const static_keys = [_]Key{ }, } }, - // comptime_int + // *const comptime_int .{ .ptr_type = .{ .child = .comptime_int_type, .flags = .{ @@ -4967,16 +4941,6 @@ pub const static_keys = [_]Key{ .ty = .comptime_int_type, .storage = .{ .i64 = -1 }, } }, - // calling_convention_c - .{ .enum_tag = .{ - .ty = .calling_convention_type, - .int = .one_u8, - } }, - // calling_convention_inline - .{ .enum_tag = .{ - .ty = .calling_convention_type, - .int = .four_u8, - } }, .{ .simple_value = .void }, .{ .simple_value = .@"unreachable" }, @@ -5690,18 +5654,6 @@ pub const SimpleType = enum(u32) { undefined = @intFromEnum(Index.undefined_type), enum_literal = @intFromEnum(Index.enum_literal_type), - atomic_order = @intFromEnum(Index.atomic_order_type), - atomic_rmw_op = @intFromEnum(Index.atomic_rmw_op_type), - calling_convention = @intFromEnum(Index.calling_convention_type), - address_space = @intFromEnum(Index.address_space_type), - float_mode = @intFromEnum(Index.float_mode_type), - reduce_op = @intFromEnum(Index.reduce_op_type), - call_modifier = @intFromEnum(Index.call_modifier_type), - prefetch_options = @intFromEnum(Index.prefetch_options_type), - export_options = @intFromEnum(Index.export_options_type), - extern_options = @intFromEnum(Index.extern_options_type), - type_info = @intFromEnum(Index.type_info_type), - adhoc_inferred_error_set = @intFromEnum(Index.adhoc_inferred_error_set_type), generic_poison = @intFromEnum(Index.generic_poison_type), }; @@ -6281,18 +6233,6 @@ pub fn init(ip: *InternPool, gpa: Allocator, available_threads: usize) !void { // Sanity check. assert(ip.indexToKey(.bool_true).simple_value == .true); assert(ip.indexToKey(.bool_false).simple_value == .false); - - const cc_inline = ip.indexToKey(.calling_convention_inline).enum_tag.int; - const cc_c = ip.indexToKey(.calling_convention_c).enum_tag.int; - - assert(ip.indexToKey(cc_inline).int.storage.u64 == - @intFromEnum(std.builtin.CallingConvention.Inline)); - - assert(ip.indexToKey(cc_c).int.storage.u64 == - @intFromEnum(std.builtin.CallingConvention.C)); - - assert(ip.indexToKey(ip.typeOf(cc_inline)).int_type.bits == - @typeInfo(@typeInfo(std.builtin.CallingConvention).Enum.tag_type).Int.bits); } } @@ -9743,14 +9683,6 @@ fn addMap(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, cap: usize) Al /// Invalidates all references to this index. pub fn remove(ip: *InternPool, tid: Zcu.PerThread.Id, index: Index) void { const unwrapped_index = index.unwrap(ip); - if (@intFromEnum(index) < static_keys.len) { - // The item being removed replaced a special index via `InternPool.resolveBuiltinType`. - // Restore the original item at this index. - assert(static_keys[@intFromEnum(index)] == .simple_type); - const items = ip.getLocalShared(unwrapped_index.tid).items.acquire().view(); - @atomicStore(Tag, &items.items(.tag)[unwrapped_index.index], .simple_type, .unordered); - return; - } if (unwrapped_index.tid == tid) { const items_len = &ip.getLocal(unwrapped_index.tid).mutate.items.len; @@ -10390,17 +10322,7 @@ pub fn isIntegerType(ip: *const InternPool, ty: Index) bool { /// does not include .enum_literal_type pub fn isEnumType(ip: *const InternPool, ty: Index) bool { - return switch (ty) { - .atomic_order_type, - .atomic_rmw_op_type, - .calling_convention_type, - .address_space_type, - .float_mode_type, - .reduce_op_type, - .call_modifier_type, - => true, - else => ip.indexToKey(ty) == .enum_type, - }; + return ip.indexToKey(ty) == .enum_type; } pub fn isUnion(ip: *const InternPool, ty: Index) bool { @@ -11401,17 +11323,6 @@ pub fn typeOf(ip: *const InternPool, index: Index) Index { .null_type, .undefined_type, .enum_literal_type, - .atomic_order_type, - .atomic_rmw_op_type, - .calling_convention_type, - .address_space_type, - .float_mode_type, - .reduce_op_type, - .call_modifier_type, - .prefetch_options_type, - .export_options_type, - .extern_options_type, - .type_info_type, .manyptr_u8_type, .manyptr_const_u8_type, .manyptr_const_u8_sentinel_0_type, @@ -11429,7 +11340,6 @@ pub fn typeOf(ip: *const InternPool, index: Index) Index { .zero, .one, .negative_one => .comptime_int_type, .zero_usize, .one_usize => .usize_type, .zero_u8, .one_u8, .four_u8 => .u8_type, - .calling_convention_c, .calling_convention_inline => .calling_convention_type, .void_value => .void_type, .unreachable_value => .noreturn_type, .null_value => .null_type, @@ -11725,22 +11635,6 @@ pub fn zigTypeTagOrPoison(ip: *const InternPool, index: Index) error{GenericPois .undefined_type => .Undefined, .enum_literal_type => .EnumLiteral, - .atomic_order_type, - .atomic_rmw_op_type, - .calling_convention_type, - .address_space_type, - .float_mode_type, - .reduce_op_type, - .call_modifier_type, - => .Enum, - - .prefetch_options_type, - .export_options_type, - .extern_options_type, - => .Struct, - - .type_info_type => .Union, - .manyptr_u8_type, .manyptr_const_u8_type, .manyptr_const_u8_sentinel_0_type, @@ -11765,8 +11659,6 @@ pub fn zigTypeTagOrPoison(ip: *const InternPool, index: Index) error{GenericPois .one_u8 => unreachable, .four_u8 => unreachable, .negative_one => unreachable, - .calling_convention_c => unreachable, - .calling_convention_inline => unreachable, .void_value => unreachable, .unreachable_value => unreachable, .null_value => unreachable, @@ -12085,34 +11977,6 @@ pub fn unwrapCoercedFunc(ip: *const InternPool, index: Index) Index { }; } -/// Having resolved a builtin type to a real struct/union/enum (which is now at `resolverd_index`), -/// make `want_index` refer to this type instead. This invalidates `resolved_index`, so must be -/// called only when it is guaranteed that no reference to `resolved_index` exists. -pub fn resolveBuiltinType( - ip: *InternPool, - tid: Zcu.PerThread.Id, - want_index: Index, - resolved_index: Index, -) void { - assert(@intFromEnum(want_index) >= @intFromEnum(Index.first_type)); - assert(@intFromEnum(want_index) <= @intFromEnum(Index.last_type)); - - // Make sure the type isn't already resolved! - assert(ip.indexToKey(want_index) == .simple_type); - - // Make sure it's the same kind of type - assert((ip.zigTypeTagOrPoison(want_index) catch unreachable) == - (ip.zigTypeTagOrPoison(resolved_index) catch unreachable)); - - // Copy the data - const item = resolved_index.unwrap(ip).getItem(ip); - const unwrapped_index = want_index.unwrap(ip); - var items = ip.getLocalShared(unwrapped_index.tid).items.acquire().view().slice(); - items.items(.data)[unwrapped_index.index] = item.data; - @atomicStore(Tag, &items.items(.tag)[unwrapped_index.index], item.tag, .release); - ip.remove(tid, resolved_index); -} - pub fn anonStructFieldTypes(ip: *const InternPool, i: Index) []const Index { return ip.indexToKey(i).anon_struct_type.types; } diff --git a/src/Sema.zig b/src/Sema.zig index 756e0ac9cab590b36518c8116f3495ab866f67fd..c8e2f2ae154ca70edbe51c1472af177e67a8959b 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -76,10 +76,6 @@ no_partial_func_ty: bool = false, /// here so the values can be dropped without any cleanup. unresolved_inferred_allocs: std.AutoArrayHashMapUnmanaged(Air.Inst.Index, InferredAlloc) = .{}, -/// While analyzing a type which has a special InternPool index, this is set to the index at which -/// the struct/enum/union type created should be placed. Otherwise, it is `.none`. -builtin_type_target_index: InternPool.Index = .none, - /// Links every pointer derived from a base `alloc` back to that `alloc`. Used /// to detect comptime-known `const`s. /// TODO: ZIR liveness analysis would allow us to remove elements from this map. @@ -1327,6 +1323,7 @@ fn analyzeBodyInner( }, .value_placeholder => unreachable, // never appears in a body .field_parent_ptr => try sema.zirFieldParentPtr(block, extended), + .builtin_value => try sema.zirBuiltinValue(extended), }; }, @@ -2712,17 +2709,6 @@ fn getCaptures(sema: *Sema, block: *Block, type_src: LazySrcLoc, extra_index: us return captures; } -/// Given an `InternPool.WipNamespaceType` or `InternPool.WipEnumType`, apply -/// `sema.builtin_type_target_index` to it if necessary. -fn wrapWipTy(sema: *Sema, wip_ty: anytype) @TypeOf(wip_ty) { - const pt = sema.pt; - if (sema.builtin_type_target_index == .none) return wip_ty; - var new = wip_ty; - new.index = sema.builtin_type_target_index; - pt.zcu.intern_pool.resolveBuiltinType(pt.tid, new.index, wip_ty.index); - return new; -} - fn zirStructDecl( sema: *Sema, block: *Block, @@ -2788,7 +2774,7 @@ fn zirStructDecl( .captures = captures, } }, }; - const wip_ty = sema.wrapWipTy(switch (try ip.getStructType(gpa, pt.tid, struct_init, false)) { + const wip_ty = switch (try ip.getStructType(gpa, pt.tid, struct_init, false)) { .existing => |ty| { const new_ty = try pt.ensureTypeUpToDate(ty, false); @@ -2801,7 +2787,7 @@ fn zirStructDecl( return Air.internedToRef(new_ty); }, .wip => |wip| wip, - }); + }; errdefer wip_ty.cancel(ip, pt.tid); wip_ty.setName(ip, try sema.createTypeName( @@ -3017,7 +3003,7 @@ fn zirEnumDecl( .captures = captures, } }, }; - const wip_ty = sema.wrapWipTy(switch (try ip.getEnumType(gpa, pt.tid, enum_init, false)) { + const wip_ty = switch (try ip.getEnumType(gpa, pt.tid, enum_init, false)) { .existing => |ty| { const new_ty = try pt.ensureTypeUpToDate(ty, false); @@ -3030,7 +3016,7 @@ fn zirEnumDecl( return Air.internedToRef(new_ty); }, .wip => |wip| wip, - }); + }; // Once this is `true`, we will not delete the decl or type even upon failure, since we // have finished constructing the type and are in the process of analyzing it. @@ -3161,7 +3147,7 @@ fn zirUnionDecl( .captures = captures, } }, }; - const wip_ty = sema.wrapWipTy(switch (try ip.getUnionType(gpa, pt.tid, union_init, false)) { + const wip_ty = switch (try ip.getUnionType(gpa, pt.tid, union_init, false)) { .existing => |ty| { const new_ty = try pt.ensureTypeUpToDate(ty, false); @@ -3174,7 +3160,7 @@ fn zirUnionDecl( return Air.internedToRef(new_ty); }, .wip => |wip| wip, - }); + }; errdefer wip_ty.cancel(ip, pt.tid); wip_ty.setName(ip, try sema.createTypeName( @@ -3259,7 +3245,6 @@ fn zirOpaqueDecl( .captures = captures, } }, }; - // No `wrapWipTy` needed as no std.builtin types are opaque. const wip_ty = switch (try ip.getOpaqueType(gpa, pt.tid, opaque_init)) { .existing => |ty| { // Make sure we update the namespace if the declaration is re-analyzed, to pick @@ -26179,7 +26164,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A const body = sema.code.bodySlice(extra_index, body_len); extra_index += body.len; - const addrspace_ty = Type.fromInterned(.address_space_type); + const addrspace_ty = try pt.getBuiltinType("AddressSpace"); const val = try sema.resolveGenericBody(block, addrspace_src, body, inst, addrspace_ty, .{ .needed_comptime_reason = "addrspace must be comptime-known", }); @@ -26190,7 +26175,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A } else if (extra.data.bits.has_addrspace_ref) blk: { const addrspace_ref: Zir.Inst.Ref = @enumFromInt(sema.code.extra[extra_index]); extra_index += 1; - const addrspace_ty = Type.fromInterned(.address_space_type); + const addrspace_ty = try pt.getBuiltinType("AddressSpace"); const uncoerced_addrspace = sema.resolveInst(addrspace_ref) catch |err| switch (err) { error.GenericPoison => break :blk null, else => |e| return e, @@ -26255,7 +26240,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A } else if (extra.data.bits.has_cc_ref) blk: { const cc_ref: Zir.Inst.Ref = @enumFromInt(sema.code.extra[extra_index]); extra_index += 1; - const cc_ty = Type.fromInterned(.calling_convention_type); + const cc_ty = try pt.getBuiltinType("CallingConvention"); const uncoerced_cc = sema.resolveInst(cc_ref) catch |err| switch (err) { error.GenericPoison => break :blk null, else => |e| return e, @@ -26713,6 +26698,46 @@ fn zirInComptime( return if (block.is_comptime) .bool_true else .bool_false; } +fn zirBuiltinValue(sema: *Sema, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref { + const pt = sema.pt; + const value: Zir.Inst.BuiltinValue = @enumFromInt(extended.small); + const type_name = switch (value) { + .atomic_order => "AtomicOrder", + .atomic_rmw_op => "AtomicRmwOp", + .calling_convention => "CallingConvention", + .address_space => "AddressSpace", + .float_mode => "FloatMode", + .reduce_op => "ReduceOp", + .call_modifier => "CallModifier", + .prefetch_options => "PrefetchOptions", + .export_options => "ExportOptions", + .extern_options => "ExternOptions", + .type_info => "Type", + + // Values are handled here. + .calling_convention_c => { + const callconv_ty = try pt.getBuiltinType("CallingConvention"); + comptime assert(@intFromEnum(std.builtin.CallingConvention.C) == 1); + const val = try pt.intern(.{ .enum_tag = .{ + .ty = callconv_ty.toIntern(), + .int = .one_u8, + } }); + return Air.internedToRef(val); + }, + .calling_convention_inline => { + const callconv_ty = try pt.getBuiltinType("CallingConvention"); + comptime assert(@intFromEnum(std.builtin.CallingConvention.Inline) == 4); + const val = try pt.intern(.{ .enum_tag = .{ + .ty = callconv_ty.toIntern(), + .int = .four_u8, + } }); + return Air.internedToRef(val); + }, + }; + const ty = try pt.getBuiltinType(type_name); + return Air.internedToRef(ty.toIntern()); +} + fn requireRuntimeBlock(sema: *Sema, block: *Block, src: LazySrcLoc, runtime_src: ?LazySrcLoc) !void { if (block.is_comptime) { const msg = msg: { @@ -36899,17 +36924,6 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value { .comptime_int_type, .comptime_float_type, .enum_literal_type, - .atomic_order_type, - .atomic_rmw_op_type, - .calling_convention_type, - .address_space_type, - .float_mode_type, - .reduce_op_type, - .call_modifier_type, - .prefetch_options_type, - .export_options_type, - .extern_options_type, - .type_info_type, .manyptr_u8_type, .manyptr_const_u8_type, .manyptr_const_u8_sentinel_0_type, @@ -36936,8 +36950,6 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value { .one_u8, .four_u8, .negative_one, - .calling_convention_c, - .calling_convention_inline, .void_value, .unreachable_value, .null_value, @@ -37291,7 +37303,8 @@ pub fn analyzeAsAddressSpace( ) !std.builtin.AddressSpace { const pt = sema.pt; const mod = pt.zcu; - const coerced = try sema.coerce(block, Type.fromInterned(.address_space_type), air_ref, src); + const addrspace_ty = try pt.getBuiltinType("AddressSpace"); + const coerced = try sema.coerce(block, addrspace_ty, air_ref, src); const addrspace_val = try sema.resolveConstDefinedValue(block, src, coerced, .{ .needed_comptime_reason = "address space must be comptime-known", }); diff --git a/src/Type.zig b/src/Type.zig index c113e0734e48e008ac500c0fa8972dc5cfaf51fd..0a37e5a6f57a5aeda4dbfb48e2888a0ea1a45629 100644 --- a/src/Type.zig +++ b/src/Type.zig @@ -316,17 +316,6 @@ pub fn print(ty: Type, writer: anytype, pt: Zcu.PerThread) @TypeOf(writer).Error => try writer.print("@TypeOf({s})", .{@tagName(s)}), .enum_literal => try writer.print("@TypeOf(.{s})", .{@tagName(s)}), - .atomic_order => try writer.writeAll("std.builtin.AtomicOrder"), - .atomic_rmw_op => try writer.writeAll("std.builtin.AtomicRmwOp"), - .calling_convention => try writer.writeAll("std.builtin.CallingConvention"), - .address_space => try writer.writeAll("std.builtin.AddressSpace"), - .float_mode => try writer.writeAll("std.builtin.FloatMode"), - .reduce_op => try writer.writeAll("std.builtin.ReduceOp"), - .call_modifier => try writer.writeAll("std.builtin.CallModifier"), - .prefetch_options => try writer.writeAll("std.builtin.PrefetchOptions"), - .export_options => try writer.writeAll("std.builtin.ExportOptions"), - .extern_options => try writer.writeAll("std.builtin.ExternOptions"), - .type_info => try writer.writeAll("std.builtin.Type"), .generic_poison => unreachable, }, @@ -544,16 +533,6 @@ pub fn hasRuntimeBitsAdvanced( .anyerror, .adhoc_inferred_error_set, .anyopaque, - .atomic_order, - .atomic_rmw_op, - .calling_convention, - .address_space, - .float_mode, - .reduce_op, - .call_modifier, - .prefetch_options, - .export_options, - .extern_options, => true, // These are false because they are comptime-only types. @@ -565,7 +544,6 @@ pub fn hasRuntimeBitsAdvanced( .null, .undefined, .enum_literal, - .type_info, => false, .generic_poison => unreachable, @@ -711,16 +689,6 @@ pub fn hasWellDefinedLayout(ty: Type, mod: *Module) bool { .anyerror, .adhoc_inferred_error_set, .anyopaque, - .atomic_order, - .atomic_rmw_op, - .calling_convention, - .address_space, - .float_mode, - .reduce_op, - .call_modifier, - .prefetch_options, - .export_options, - .extern_options, .type, .comptime_int, .comptime_float, @@ -728,7 +696,6 @@ pub fn hasWellDefinedLayout(ty: Type, mod: *Module) bool { .null, .undefined, .enum_literal, - .type_info, .generic_poison, => false, }, @@ -972,14 +939,6 @@ pub fn abiAlignmentAdvanced( .simple_type => |t| switch (t) { .bool, - .atomic_order, - .atomic_rmw_op, - .calling_convention, - .address_space, - .float_mode, - .reduce_op, - .call_modifier, - .prefetch_options, .anyopaque, => return .{ .scalar = .@"1" }, @@ -987,11 +946,6 @@ pub fn abiAlignmentAdvanced( .isize, => return .{ .scalar = intAbiAlignment(target.ptrBitWidth(), target, use_llvm) }, - .export_options, - .extern_options, - .type_info, - => return .{ .scalar = ptrAbiAlignment(target) }, - .c_char => return .{ .scalar = cTypeAlign(target, .char) }, .c_short => return .{ .scalar = cTypeAlign(target, .short) }, .c_ushort => return .{ .scalar = cTypeAlign(target, .ushort) }, @@ -1352,15 +1306,7 @@ pub fn abiSizeAdvanced( }, .func_type => unreachable, // represents machine code; not a pointer .simple_type => |t| switch (t) { - .bool, - .atomic_order, - .atomic_rmw_op, - .calling_convention, - .address_space, - .float_mode, - .reduce_op, - .call_modifier, - => return .{ .scalar = 1 }, + .bool => return .{ .scalar = 1 }, .f16 => return .{ .scalar = 2 }, .f32 => return .{ .scalar = 4 }, @@ -1402,11 +1348,6 @@ pub fn abiSizeAdvanced( return .{ .scalar = intAbiSize(bits, target, use_llvm) }; }, - .prefetch_options => unreachable, // missing call to resolveTypeFields - .export_options => unreachable, // missing call to resolveTypeFields - .extern_options => unreachable, // missing call to resolveTypeFields - - .type_info => unreachable, .noreturn => unreachable, .generic_poison => unreachable, }, @@ -1751,18 +1692,6 @@ pub fn bitSizeAdvanced( .undefined => unreachable, .enum_literal => unreachable, .generic_poison => unreachable, - - .atomic_order => unreachable, - .atomic_rmw_op => unreachable, - .calling_convention => unreachable, - .address_space => unreachable, - .float_mode => unreachable, - .reduce_op => unreachable, - .call_modifier => unreachable, - .prefetch_options => unreachable, - .export_options => unreachable, - .extern_options => unreachable, - .type_info => unreachable, }, .struct_type => { const struct_type = ip.loadStructType(ty.toIntern()); @@ -2565,17 +2494,6 @@ pub fn onePossibleValue(starting_type: Type, pt: Zcu.PerThread) !?Value { .comptime_int, .comptime_float, .enum_literal, - .atomic_order, - .atomic_rmw_op, - .calling_convention, - .address_space, - .float_mode, - .reduce_op, - .call_modifier, - .prefetch_options, - .export_options, - .extern_options, - .type_info, .adhoc_inferred_error_set, => return null, @@ -2782,16 +2700,6 @@ pub fn comptimeOnlyAdvanced(ty: Type, pt: Zcu.PerThread, comptime strat: Resolve .adhoc_inferred_error_set, .noreturn, .generic_poison, - .atomic_order, - .atomic_rmw_op, - .calling_convention, - .address_space, - .float_mode, - .reduce_op, - .call_modifier, - .prefetch_options, - .export_options, - .extern_options, => false, .type, @@ -2800,7 +2708,6 @@ pub fn comptimeOnlyAdvanced(ty: Type, pt: Zcu.PerThread, comptime strat: Resolve .null, .undefined, .enum_literal, - .type_info, => true, }, .struct_type => { @@ -3534,10 +3441,6 @@ pub fn packedStructFieldPtrInfo(struct_ty: Type, parent_ptr_ty: Type, field_idx: pub fn resolveLayout(ty: Type, pt: Zcu.PerThread) SemaError!void { const zcu = pt.zcu; const ip = &zcu.intern_pool; - switch (ip.indexToKey(ty.toIntern())) { - .simple_type => |simple_type| return resolveSimpleType(simple_type, pt), - else => {}, - } switch (ty.zigTypeTag(zcu)) { .Struct => switch (ip.indexToKey(ty.toIntern())) { .anon_struct_type => |anon_struct_type| for (0..anon_struct_type.types.len) |i| { @@ -3651,8 +3554,6 @@ pub fn resolveFields(ty: Type, pt: Zcu.PerThread) SemaError!void { .one_u8 => unreachable, .four_u8 => unreachable, .negative_one => unreachable, - .calling_convention_c => unreachable, - .calling_convention_inline => unreachable, .void_value => unreachable, .unreachable_value => unreachable, .null_value => unreachable, @@ -3669,8 +3570,6 @@ pub fn resolveFields(ty: Type, pt: Zcu.PerThread) SemaError!void { .type_union => return ty.resolveUnionInner(pt, .fields), - .simple_type => return resolveSimpleType(ip.indexToKey(ty_ip).simple_type, pt), - else => {}, }, } @@ -3680,11 +3579,6 @@ pub fn resolveFully(ty: Type, pt: Zcu.PerThread) SemaError!void { const zcu = pt.zcu; const ip = &zcu.intern_pool; - switch (ip.indexToKey(ty.toIntern())) { - .simple_type => |simple_type| return resolveSimpleType(simple_type, pt), - else => {}, - } - switch (ty.zigTypeTag(zcu)) { .Type, .Void, @@ -3850,28 +3744,6 @@ fn resolveUnionInner( }; } -/// Fully resolves a simple type. This is usually a nop, but for builtin types with -/// special InternPool indices (such as std.builtin.Type) it will analyze and fully -/// resolve the type. -fn resolveSimpleType(simple_type: InternPool.SimpleType, pt: Zcu.PerThread) Allocator.Error!void { - const builtin_type_name: []const u8 = switch (simple_type) { - .atomic_order => "AtomicOrder", - .atomic_rmw_op => "AtomicRmwOp", - .calling_convention => "CallingConvention", - .address_space => "AddressSpace", - .float_mode => "FloatMode", - .reduce_op => "ReduceOp", - .call_modifier => "CallModifer", - .prefetch_options => "PrefetchOptions", - .export_options => "ExportOptions", - .extern_options => "ExternOptions", - .type_info => "Type", - else => return, - }; - // This will fully resolve the type. - _ = try pt.getBuiltinType(builtin_type_name); -} - /// Returns the type of a pointer to an element. /// Asserts that the type is a pointer, and that the element type is indexable. /// If the element index is comptime-known, it must be passed in `offset`. diff --git a/src/Zcu/PerThread.zig b/src/Zcu/PerThread.zig index bc6d9457828038eb9b5236b3afca8b13e049aae9..0db30bfdbd4d5c8cd36e9d7fdb3a6ca8ef51fa59 100644 --- a/src/Zcu/PerThread.zig +++ b/src/Zcu/PerThread.zig @@ -1102,12 +1102,9 @@ fn semaCau(pt: Zcu.PerThread, cau_index: InternPool.Cau.Index) !SemaCauResult { // We are about to re-analyze this `Cau`; drop its depenndencies. zcu.intern_pool.removeDependenciesForDepender(gpa, anal_unit); - const builtin_type_target_index: InternPool.Index = switch (cau.owner.unwrap()) { - .none => ip_index: { - // `comptime` decl -- we will re-analyze its body. - // This declaration has no value so is definitely not a std.builtin type. - break :ip_index .none; - }, + switch (cau.owner.unwrap()) { + .none => {}, // `comptime` decl -- we will re-analyze its body. + .nav => {}, // Other decl -- we will re-analyze its value. .type => |ty| { // This is an incremental update, and this type is being re-analyzed because it is outdated. // Create a new type in its place, and mark the old one as outdated so that use sites will @@ -1119,53 +1116,7 @@ fn semaCau(pt: Zcu.PerThread, cau_index: InternPool.Cau.Index) !SemaCauResult { .invalidate_decl_ref = true, }; }, - .nav => |nav| ip_index: { - // Other decl -- we will re-analyze its value. - // This might be a type in `builtin.zig` -- check. - if (file.mod != zcu.std_mod) break :ip_index .none; - // We're in the std module. - const nav_name = ip.getNav(nav).name; - const std_file_imported = try pt.importPkg(zcu.std_mod); - const std_type = Type.fromInterned(zcu.fileRootType(std_file_imported.file_index)); - const std_namespace = zcu.namespacePtr(std_type.getNamespace(zcu).unwrap().?); - const builtin_str = try ip.getOrPutString(gpa, pt.tid, "builtin", .no_embedded_nulls); - const builtin_nav = ip.getNav(std_namespace.pub_decls.getKeyAdapted(builtin_str, Zcu.Namespace.NameAdapter{ .zcu = zcu }) orelse break :ip_index .none); - const builtin_namespace = switch (builtin_nav.status) { - .unresolved => break :ip_index .none, - .resolved => |r| Type.fromInterned(r.val).getNamespace(zcu).unwrap().?, - }; - if (cau.namespace != builtin_namespace) break :ip_index .none; - // We're in builtin.zig. This could be a builtin we need to add to a specific InternPool index. - for ([_][]const u8{ - "AtomicOrder", - "AtomicRmwOp", - "CallingConvention", - "AddressSpace", - "FloatMode", - "ReduceOp", - "CallModifier", - "PrefetchOptions", - "ExportOptions", - "ExternOptions", - "Type", - }, [_]InternPool.Index{ - .atomic_order_type, - .atomic_rmw_op_type, - .calling_convention_type, - .address_space_type, - .float_mode_type, - .reduce_op_type, - .call_modifier_type, - .prefetch_options_type, - .export_options_type, - .extern_options_type, - .type_info_type, - }) |type_name, type_ip| { - if (nav_name.eqlSlice(type_name, ip)) break :ip_index type_ip; - } - break :ip_index .none; - }, - }; + } const is_usingnamespace = switch (cau.owner.unwrap()) { .nav => |nav| ip.getNav(nav).is_usingnamespace, @@ -1194,7 +1145,6 @@ fn semaCau(pt: Zcu.PerThread, cau_index: InternPool.Cau.Index) !SemaCauResult { .fn_ret_ty = Type.void, .fn_ret_ty_ies = null, .comptime_err_ret_trace = &comptime_err_ret_trace, - .builtin_type_target_index = builtin_type_target_index, }; defer sema.deinit(); @@ -1249,9 +1199,6 @@ fn semaCau(pt: Zcu.PerThread, cau_index: InternPool.Cau.Index) !SemaCauResult { .type => unreachable, // Handled at top of function. }; - // We'll do more work with the Sema. Clear the target type index just in case we analyze any type. - sema.builtin_type_target_index = .none; - const align_src = block.src(.{ .node_offset_var_decl_align = 0 }); const section_src = block.src(.{ .node_offset_var_decl_section = 0 }); const addrspace_src = block.src(.{ .node_offset_var_decl_addrspace = 0 }); @@ -3349,7 +3296,7 @@ pub fn ensureTypeUpToDate(pt: Zcu.PerThread, ty: InternPool.Index, already_updat break :o o; }; if (!outdated) return ty; - return pt.recreateStructType(ty, key, struct_obj); + return pt.recreateStructType(key, struct_obj); }, .union_type => |key| { const union_obj = ip.loadUnionType(ty); @@ -3364,7 +3311,7 @@ pub fn ensureTypeUpToDate(pt: Zcu.PerThread, ty: InternPool.Index, already_updat break :o o; }; if (!outdated) return ty; - return pt.recreateUnionType(ty, key, union_obj); + return pt.recreateUnionType(key, union_obj); }, .enum_type => |key| { const enum_obj = ip.loadEnumType(ty); @@ -3379,7 +3326,7 @@ pub fn ensureTypeUpToDate(pt: Zcu.PerThread, ty: InternPool.Index, already_updat break :o o; }; if (!outdated) return ty; - return pt.recreateEnumType(ty, key, enum_obj); + return pt.recreateEnumType(key, enum_obj); }, .opaque_type => { assert(!already_updating); @@ -3391,7 +3338,6 @@ pub fn ensureTypeUpToDate(pt: Zcu.PerThread, ty: InternPool.Index, already_updat fn recreateStructType( pt: Zcu.PerThread, - ty: InternPool.Index, full_key: InternPool.Key.NamespaceType, struct_obj: InternPool.LoadedStructType, ) Zcu.SemaError!InternPool.Index { @@ -3406,10 +3352,6 @@ fn recreateStructType( .declared => |d| d, }; - if (@intFromEnum(ty) <= InternPool.static_len) { - @panic("TODO: recreate resolved builtin type"); - } - const inst_info = key.zir_index.resolveFull(ip) orelse return error.AnalysisFail; const file = zcu.fileByIndex(inst_info.file); if (file.status != .success_zir) return error.AnalysisFail; @@ -3482,7 +3424,6 @@ fn recreateStructType( fn recreateUnionType( pt: Zcu.PerThread, - ty: InternPool.Index, full_key: InternPool.Key.NamespaceType, union_obj: InternPool.LoadedUnionType, ) Zcu.SemaError!InternPool.Index { @@ -3497,10 +3438,6 @@ fn recreateUnionType( .declared => |d| d, }; - if (@intFromEnum(ty) <= InternPool.static_len) { - @panic("TODO: recreate resolved builtin type"); - } - const inst_info = key.zir_index.resolveFull(ip) orelse return error.AnalysisFail; const file = zcu.fileByIndex(inst_info.file); if (file.status != .success_zir) return error.AnalysisFail; @@ -3581,7 +3518,6 @@ fn recreateUnionType( fn recreateEnumType( pt: Zcu.PerThread, - ty: InternPool.Index, full_key: InternPool.Key.NamespaceType, enum_obj: InternPool.LoadedEnumType, ) Zcu.SemaError!InternPool.Index { @@ -3596,10 +3532,6 @@ fn recreateEnumType( .declared => |d| d, }; - if (@intFromEnum(ty) <= InternPool.static_len) { - @panic("TODO: recreate resolved builtin type"); - } - const inst_info = key.zir_index.resolveFull(ip) orelse return error.AnalysisFail; const file = zcu.fileByIndex(inst_info.file); if (file.status != .success_zir) return error.AnalysisFail; diff --git a/src/codegen/c/Type.zig b/src/codegen/c/Type.zig index c89d9d19f7b0d168855136722fb4bccceb13470d..63b7e4fd52ba53dfecb4e333355d598fb99f1805 100644 --- a/src/codegen/c/Type.zig +++ b/src/codegen/c/Type.zig @@ -1389,21 +1389,6 @@ pub const Pool = struct { .anyframe_type, .generic_poison_type, => unreachable, - .atomic_order_type, - .atomic_rmw_op_type, - .calling_convention_type, - .address_space_type, - .float_mode_type, - .reduce_op_type, - .call_modifier_type, - => |ip_index| return pool.fromType( - allocator, - scratch, - Type.fromInterned(ip.loadEnumType(ip_index).tag_ty), - pt, - mod, - kind, - ), .anyerror_type, .anyerror_void_error_union_type, .adhoc_inferred_error_set_type, @@ -1459,8 +1444,6 @@ pub const Pool = struct { .one_u8, .four_u8, .negative_one, - .calling_convention_c, - .calling_convention_inline, .void_value, .unreachable_value, .null_value, @@ -1471,12 +1454,7 @@ pub const Pool = struct { .none, => unreachable, - //.prefetch_options_type, - //.export_options_type, - //.extern_options_type, - //.type_info_type, - //_, - else => |ip_index| switch (ip.indexToKey(ip_index)) { + _ => |ip_index| switch (ip.indexToKey(ip_index)) { .int_type => |int_info| return pool.fromIntInfo(allocator, int_info, mod, kind), .ptr_type => |ptr_info| switch (ptr_info.flags.size) { .One, .Many, .C => { diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index acceea175a796ab0cac96db0edc94dd5fa8a480a..111cefaa9a7ea00dd4f47bb29a6ee1c5ea98c9c0 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -3194,8 +3194,6 @@ pub const Object = struct { .one_u8, .four_u8, .negative_one, - .calling_convention_c, - .calling_convention_inline, .void_value, .unreachable_value, .null_value, diff --git a/src/link/Dwarf.zig b/src/link/Dwarf.zig index e6cf89a4ce49b1ac98a7010f7d06f338168fb6de..1b5739030bf27ddae3e0681f18a5da7502eb1dff 100644 --- a/src/link/Dwarf.zig +++ b/src/link/Dwarf.zig @@ -2565,19 +2565,7 @@ fn updateType( try wip_nav.strp(if (type_index == .generic_poison_type) "anytype" else name); }, .anyerror => return, // delay until flush - .atomic_order, - .atomic_rmw_op, - .calling_convention, - .address_space, - .float_mode, - .reduce_op, - .call_modifier, - .prefetch_options, - .export_options, - .extern_options, - .type_info, - .adhoc_inferred_error_set, - => unreachable, + .adhoc_inferred_error_set => unreachable, }, .struct_type, .union_type, diff --git a/src/print_zir.zig b/src/print_zir.zig index 20fc115cc7b10a44bd7c50955c2227a19ac8a829..774b222626dd3aceee4dd969e28e7068e0f129ac 100644 --- a/src/print_zir.zig +++ b/src/print_zir.zig @@ -615,6 +615,7 @@ const Writer = struct { .restore_err_ret_index => try self.writeRestoreErrRetIndex(stream, extended), .closure_get => try self.writeClosureGet(stream, extended), .field_parent_ptr => try self.writeFieldParentPtr(stream, extended), + .builtin_value => try self.writeBuiltinValue(stream, extended), } } @@ -2782,6 +2783,12 @@ const Writer = struct { try self.writeSrcNode(stream, @bitCast(extended.operand)); } + fn writeBuiltinValue(self: *Writer, stream: anytype, extended: Zir.Inst.Extended.InstData) !void { + const val: Zir.Inst.BuiltinValue = @enumFromInt(extended.small); + try stream.print("{s})) ", .{@tagName(val)}); + try self.writeSrcNode(stream, @bitCast(extended.operand)); + } + fn writeInstRef(self: *Writer, stream: anytype, ref: Zir.Inst.Ref) !void { if (ref == .none) { return stream.writeAll(".none"); -- 2.54.0