authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-03-26 21:11:18-07:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2024-03-26 21:11:18-07:00
log5140f2726ae6e09381d9d44a72626dfe319f068b
treeb2163e1439be4858c8e11b7d210ab91e262ab761
parent341857e5cd4fd4453cf9c7d1a6679feb66710d84
parent513254956525f8f970e972f6973ab4df0b19d06a
signaturebadge-check Signed by PGP key B5690EEEBB952194

Merge pull request #19437 from mlugg/value-cleanups

Follow-up to #19414

40 files changed, 2016 insertions(+), 2706 deletions(-)

CMakeLists.txt+2-1
......@@ -526,7 +526,6 @@ set(ZIG_STAGE2_SOURCES
526526 "${CMAKE_SOURCE_DIR}/src/Package/Fetch.zig"
527527 "${CMAKE_SOURCE_DIR}/src/RangeSet.zig"
528528 "${CMAKE_SOURCE_DIR}/src/Sema.zig"
529 "${CMAKE_SOURCE_DIR}/src/TypedValue.zig"
530529 "${CMAKE_SOURCE_DIR}/src/Value.zig"
531530 "${CMAKE_SOURCE_DIR}/src/arch/aarch64/CodeGen.zig"
532531 "${CMAKE_SOURCE_DIR}/src/arch/aarch64/Emit.zig"
......@@ -634,9 +633,11 @@ set(ZIG_STAGE2_SOURCES
634633 "${CMAKE_SOURCE_DIR}/src/main.zig"
635634 "${CMAKE_SOURCE_DIR}/src/mingw.zig"
636635 "${CMAKE_SOURCE_DIR}/src/musl.zig"
636 "${CMAKE_SOURCE_DIR}/src/mutable_value.zig"
637637 "${CMAKE_SOURCE_DIR}/src/print_air.zig"
638638 "${CMAKE_SOURCE_DIR}/src/print_env.zig"
639639 "${CMAKE_SOURCE_DIR}/src/print_targets.zig"
640 "${CMAKE_SOURCE_DIR}/src/print_value.zig"
640641 "${CMAKE_SOURCE_DIR}/src/print_zir.zig"
641642 "${CMAKE_SOURCE_DIR}/src/register_manager.zig"
642643 "${CMAKE_SOURCE_DIR}/src/target.zig"
src/Compilation.zig+1-18
......@@ -102,7 +102,6 @@ link_errors: std.ArrayListUnmanaged(link.File.ErrorMsg) = .{},
102102lld_errors: std.ArrayListUnmanaged(LldError) = .{},
103103
104104work_queue: std.fifo.LinearFifo(Job, .Dynamic),
105anon_work_queue: std.fifo.LinearFifo(Job, .Dynamic),
106105
107106/// These jobs are to invoke the Clang compiler to create an object file, which
108107/// gets linked with the Compilation.
......@@ -1417,7 +1416,6 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
14171416 .emit_llvm_ir = options.emit_llvm_ir,
14181417 .emit_llvm_bc = options.emit_llvm_bc,
14191418 .work_queue = std.fifo.LinearFifo(Job, .Dynamic).init(gpa),
1420 .anon_work_queue = std.fifo.LinearFifo(Job, .Dynamic).init(gpa),
14211419 .c_object_work_queue = std.fifo.LinearFifo(*CObject, .Dynamic).init(gpa),
14221420 .win32_resource_work_queue = if (build_options.only_core_functionality) {} else std.fifo.LinearFifo(*Win32Resource, .Dynamic).init(gpa),
14231421 .astgen_work_queue = std.fifo.LinearFifo(*Module.File, .Dynamic).init(gpa),
......@@ -1840,7 +1838,6 @@ pub fn destroy(comp: *Compilation) void {
18401838 if (comp.module) |zcu| zcu.deinit();
18411839 comp.cache_use.deinit();
18421840 comp.work_queue.deinit();
1843 comp.anon_work_queue.deinit();
18441841 comp.c_object_work_queue.deinit();
18451842 if (!build_options.only_core_functionality) {
18461843 comp.win32_resource_work_queue.deinit();
......@@ -3354,18 +3351,11 @@ pub fn performAllTheWork(
33543351 mod.sema_prog_node = undefined;
33553352 };
33563353
3357 // In this main loop we give priority to non-anonymous Decls in the work queue, so
3358 // that they can establish references to anonymous Decls, setting alive=true in the
3359 // backend, preventing anonymous Decls from being prematurely destroyed.
33603354 while (true) {
33613355 if (comp.work_queue.readItem()) |work_item| {
33623356 try processOneJob(comp, work_item, main_progress_node);
33633357 continue;
33643358 }
3365 if (comp.anon_work_queue.readItem()) |work_item| {
3366 try processOneJob(comp, work_item, main_progress_node);
3367 continue;
3368 }
33693359 if (comp.module) |zcu| {
33703360 // If there's no work queued, check if there's anything outdated
33713361 // which we need to work on, and queue it if so.
......@@ -3413,14 +3403,7 @@ fn processOneJob(comp: *Compilation, job: Job, prog_node: *std.Progress.Node) !v
34133403
34143404 assert(decl.has_tv);
34153405
3416 if (decl.alive) {
3417 try module.linkerUpdateDecl(decl_index);
3418 return;
3419 }
3420
3421 // Instead of sending this decl to the linker, we actually will delete it
3422 // because we found out that it in fact was never referenced.
3423 module.deleteUnusedDecl(decl_index);
3406 try module.linkerUpdateDecl(decl_index);
34243407 return;
34253408 },
34263409 }
src/InternPool.zig-5
......@@ -6581,7 +6581,6 @@ pub fn getFuncInstance(ip: *InternPool, gpa: Allocator, arg: GetFuncInstanceKey)
65816581 generic_owner,
65826582 func_index,
65836583 func_extra_index,
6584 func_ty,
65856584 arg.alignment,
65866585 arg.section,
65876586 );
......@@ -6711,7 +6710,6 @@ pub fn getFuncInstanceIes(
67116710 generic_owner,
67126711 func_index,
67136712 func_extra_index,
6714 func_ty,
67156713 arg.alignment,
67166714 arg.section,
67176715 );
......@@ -6723,7 +6721,6 @@ fn finishFuncInstance(
67236721 generic_owner: Index,
67246722 func_index: Index,
67256723 func_extra_index: u32,
6726 func_ty: Index,
67276724 alignment: Alignment,
67286725 section: OptionalNullTerminatedString,
67296726) Allocator.Error!Index {
......@@ -6735,7 +6732,6 @@ fn finishFuncInstance(
67356732 .src_line = fn_owner_decl.src_line,
67366733 .has_tv = true,
67376734 .owns_tv = true,
6738 .ty = @import("type.zig").Type.fromInterned(func_ty),
67396735 .val = @import("Value.zig").fromInterned(func_index),
67406736 .alignment = alignment,
67416737 .@"linksection" = section,
......@@ -6744,7 +6740,6 @@ fn finishFuncInstance(
67446740 .zir_decl_index = fn_owner_decl.zir_decl_index,
67456741 .is_pub = fn_owner_decl.is_pub,
67466742 .is_exported = fn_owner_decl.is_exported,
6747 .alive = true,
67486743 .kind = .anon,
67496744 });
67506745 errdefer ip.destroyDecl(gpa, decl_index);
src/Module.zig+56-209
......@@ -22,7 +22,6 @@ const Compilation = @import("Compilation.zig");
2222const Cache = std.Build.Cache;
2323const Value = @import("Value.zig");
2424const Type = @import("type.zig").Type;
25const TypedValue = @import("TypedValue.zig");
2625const Package = @import("Package.zig");
2726const link = @import("link.zig");
2827const Air = @import("Air.zig");
......@@ -330,9 +329,6 @@ const ValueArena = struct {
330329
331330pub const Decl = struct {
332331 name: InternPool.NullTerminatedString,
333 /// The most recent Type of the Decl after a successful semantic analysis.
334 /// Populated when `has_tv`.
335 ty: Type,
336332 /// The most recent Value of the Decl after a successful semantic analysis.
337333 /// Populated when `has_tv`.
338334 val: Value,
......@@ -397,15 +393,6 @@ pub const Decl = struct {
397393 is_pub: bool,
398394 /// Whether the corresponding AST decl has a `export` keyword.
399395 is_exported: bool,
400 /// Flag used by garbage collection to mark and sweep.
401 /// Decls which correspond to an AST node always have this field set to `true`.
402 /// Anonymous Decls are initialized with this field set to `false` and then it
403 /// is the responsibility of machine code backends to mark it `true` whenever
404 /// a `decl_ref` Value is encountered that points to this Decl.
405 /// When the `codegen_decl` job is encountered in the main work queue, if the
406 /// Decl is marked alive, then it sends the Decl to the linker. Otherwise it
407 /// deletes the Decl on the spot.
408 alive: bool,
409396 /// If true `name` is already fully qualified.
410397 name_fully_qualified: bool = false,
411398 /// What kind of a declaration is this.
......@@ -438,14 +425,6 @@ pub const Decl = struct {
438425 return @as(i32, @bitCast(node_index)) - @as(i32, @bitCast(decl.src_node));
439426 }
440427
441 pub fn tokSrcLoc(decl: Decl, token_index: Ast.TokenIndex) LazySrcLoc {
442 return .{ .token_offset = token_index - decl.srcToken() };
443 }
444
445 pub fn nodeSrcLoc(decl: Decl, node_index: Ast.Node.Index) LazySrcLoc {
446 return LazySrcLoc.nodeOffset(decl.nodeIndexToRelative(node_index));
447 }
448
449428 pub fn srcLoc(decl: Decl, zcu: *Zcu) SrcLoc {
450429 return decl.nodeOffsetSrcLoc(0, zcu);
451430 }
......@@ -458,16 +437,6 @@ pub const Decl = struct {
458437 };
459438 }
460439
461 pub fn srcToken(decl: Decl, zcu: *Zcu) Ast.TokenIndex {
462 const tree = &decl.getFileScope(zcu).tree;
463 return tree.firstToken(decl.src_node);
464 }
465
466 pub fn srcByteOffset(decl: Decl, zcu: *Zcu) u32 {
467 const tree = &decl.getFileScope(zcu).tree;
468 return tree.tokens.items(.start)[decl.srcToken()];
469 }
470
471440 pub fn renderFullyQualifiedName(decl: Decl, zcu: *Zcu, writer: anytype) !void {
472441 if (decl.name_fully_qualified) {
473442 try writer.print("{}", .{decl.name.fmt(&zcu.intern_pool)});
......@@ -487,37 +456,16 @@ pub const Decl = struct {
487456 zcu.namespacePtr(decl.src_namespace).fullyQualifiedName(zcu, decl.name);
488457 }
489458
490 pub fn typedValue(decl: Decl) error{AnalysisFail}!TypedValue {
491 if (!decl.has_tv) return error.AnalysisFail;
492 return TypedValue{ .ty = decl.ty, .val = decl.val };
493 }
494
495 pub fn internValue(decl: *Decl, zcu: *Zcu) Allocator.Error!InternPool.Index {
459 pub fn typeOf(decl: Decl, zcu: *const Zcu) Type {
496460 assert(decl.has_tv);
497 const ip_index = try decl.val.intern(decl.ty, zcu);
498 decl.val = Value.fromInterned(ip_index);
499 return ip_index;
461 return decl.val.typeOf(zcu);
500462 }
501463
502 pub fn isFunction(decl: Decl, zcu: *const Zcu) !bool {
503 const tv = try decl.typedValue();
504 return tv.ty.zigTypeTag(zcu) == .Fn;
505 }
506
507 /// If the Decl owns its value and it is a struct, return it,
508 /// otherwise null.
509 pub fn getOwnedStruct(decl: Decl, zcu: *Zcu) ?InternPool.Key.StructType {
510 if (!decl.owns_tv) return null;
511 if (decl.val.ip_index == .none) return null;
512 return zcu.typeToStruct(decl.val.toType());
513 }
514
515 /// If the Decl owns its value and it is a union, return it,
516 /// otherwise null.
517 pub fn getOwnedUnion(decl: Decl, zcu: *Zcu) ?InternPool.LoadedUnionType {
518 if (!decl.owns_tv) return null;
519 if (decl.val.ip_index == .none) return null;
520 return zcu.typeToUnion(decl.val.toType());
464 /// Small wrapper for Sema to use over direct access to the `val` field.
465 /// If the value is not populated, instead returns `error.AnalysisFail`.
466 pub fn valueOrFail(decl: Decl) error{AnalysisFail}!Value {
467 if (!decl.has_tv) return error.AnalysisFail;
468 return decl.val;
521469 }
522470
523471 pub fn getOwnedFunction(decl: Decl, zcu: *Zcu) ?InternPool.Key.Func {
......@@ -590,7 +538,7 @@ pub const Decl = struct {
590538 @tagName(decl.analysis),
591539 });
592540 if (decl.has_tv) {
593 std.debug.print(" ty={} val={}", .{ decl.ty, decl.val });
541 std.debug.print(" val={}", .{decl.val});
594542 }
595543 std.debug.print("\n", .{});
596544 }
......@@ -615,7 +563,7 @@ pub const Decl = struct {
615563 pub fn getAlignment(decl: Decl, zcu: *Zcu) Alignment {
616564 assert(decl.has_tv);
617565 if (decl.alignment != .none) return decl.alignment;
618 return decl.ty.abiAlignment(zcu);
566 return decl.typeOf(zcu).abiAlignment(zcu);
619567 }
620568
621569 /// Upgrade a `LazySrcLoc` to a `SrcLoc` based on the `Decl` provided.
......@@ -3525,10 +3473,8 @@ fn semaFile(mod: *Module, file: *File) SemaError!void {
35253473 new_decl.src_line = 0;
35263474 new_decl.is_pub = true;
35273475 new_decl.is_exported = false;
3528 new_decl.ty = Type.type;
35293476 new_decl.alignment = .none;
35303477 new_decl.@"linksection" = .none;
3531 new_decl.alive = true; // This Decl corresponds to a File and is therefore always alive.
35323478 new_decl.analysis = .in_progress;
35333479
35343480 if (file.status != .success_zir) {
......@@ -3594,7 +3540,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !SemaDeclResult {
35943540
35953541 const old_has_tv = decl.has_tv;
35963542 // The following values are ignored if `!old_has_tv`
3597 const old_ty = decl.ty;
3543 const old_ty = if (old_has_tv) decl.typeOf(mod) else undefined;
35983544 const old_val = decl.val;
35993545 const old_align = decl.alignment;
36003546 const old_linksection = decl.@"linksection";
......@@ -3698,25 +3644,25 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !SemaDeclResult {
36983644 const address_space_src: LazySrcLoc = .{ .node_offset_var_decl_addrspace = 0 };
36993645 const ty_src: LazySrcLoc = .{ .node_offset_var_decl_ty = 0 };
37003646 const init_src: LazySrcLoc = .{ .node_offset_var_decl_init = 0 };
3701 const decl_tv = try sema.resolveFinalDeclValue(&block_scope, init_src, result_ref);
3647 const decl_val = try sema.resolveFinalDeclValue(&block_scope, init_src, result_ref);
3648 const decl_ty = decl_val.typeOf(mod);
37023649
37033650 // Note this resolves the type of the Decl, not the value; if this Decl
37043651 // is a struct, for example, this resolves `type` (which needs no resolution),
37053652 // not the struct itself.
3706 try sema.resolveTypeLayout(decl_tv.ty);
3653 try sema.resolveTypeLayout(decl_ty);
37073654
37083655 if (decl.kind == .@"usingnamespace") {
3709 if (!decl_tv.ty.eql(Type.type, mod)) {
3656 if (!decl_ty.eql(Type.type, mod)) {
37103657 return sema.fail(&block_scope, ty_src, "expected type, found {}", .{
3711 decl_tv.ty.fmt(mod),
3658 decl_ty.fmt(mod),
37123659 });
37133660 }
3714 const ty = decl_tv.val.toType();
3661 const ty = decl_val.toType();
37153662 if (ty.getNamespace(mod) == null) {
37163663 return sema.fail(&block_scope, ty_src, "type {} has no namespace", .{ty.fmt(mod)});
37173664 }
37183665
3719 decl.ty = Type.fromInterned(InternPool.Index.type_type);
37203666 decl.val = ty.toValue();
37213667 decl.alignment = .none;
37223668 decl.@"linksection" = .none;
......@@ -3734,10 +3680,10 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !SemaDeclResult {
37343680 var queue_linker_work = true;
37353681 var is_func = false;
37363682 var is_inline = false;
3737 switch (decl_tv.val.toIntern()) {
3683 switch (decl_val.toIntern()) {
37383684 .generic_poison => unreachable,
37393685 .unreachable_value => unreachable,
3740 else => switch (ip.indexToKey(decl_tv.val.toIntern())) {
3686 else => switch (ip.indexToKey(decl_val.toIntern())) {
37413687 .variable => |variable| {
37423688 decl.owns_tv = variable.decl == decl_index;
37433689 queue_linker_work = decl.owns_tv;
......@@ -3752,7 +3698,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !SemaDeclResult {
37523698 .func => |func| {
37533699 decl.owns_tv = func.owner_decl == decl_index;
37543700 queue_linker_work = false;
3755 is_inline = decl.owns_tv and decl_tv.ty.fnCallingConvention(mod) == .Inline;
3701 is_inline = decl.owns_tv and decl_ty.fnCallingConvention(mod) == .Inline;
37563702 is_func = decl.owns_tv;
37573703 },
37583704
......@@ -3760,8 +3706,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !SemaDeclResult {
37603706 },
37613707 }
37623708
3763 decl.ty = decl_tv.ty;
3764 decl.val = Value.fromInterned((try decl_tv.val.intern(decl_tv.ty, mod)));
3709 decl.val = decl_val;
37653710 // Function linksection, align, and addrspace were already set by Sema
37663711 if (!is_func) {
37673712 decl.alignment = blk: {
......@@ -3784,7 +3729,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !SemaDeclResult {
37843729 break :blk section.toOptional();
37853730 };
37863731 decl.@"addrspace" = blk: {
3787 const addrspace_ctx: Sema.AddressSpaceContext = switch (ip.indexToKey(decl_tv.val.toIntern())) {
3732 const addrspace_ctx: Sema.AddressSpaceContext = switch (ip.indexToKey(decl_val.toIntern())) {
37883733 .variable => .variable,
37893734 .extern_func, .func => .function,
37903735 else => .constant,
......@@ -3806,10 +3751,10 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !SemaDeclResult {
38063751 decl.analysis = .complete;
38073752
38083753 const result: SemaDeclResult = if (old_has_tv) .{
3809 .invalidate_decl_val = !decl.ty.eql(old_ty, mod) or
3810 !decl.val.eql(old_val, decl.ty, mod) or
3754 .invalidate_decl_val = !decl_ty.eql(old_ty, mod) or
3755 !decl.val.eql(old_val, decl_ty, mod) or
38113756 is_inline != old_is_inline,
3812 .invalidate_decl_ref = !decl.ty.eql(old_ty, mod) or
3757 .invalidate_decl_ref = !decl_ty.eql(old_ty, mod) or
38133758 decl.alignment != old_align or
38143759 decl.@"linksection" != old_linksection or
38153760 decl.@"addrspace" != old_addrspace or
......@@ -3819,11 +3764,11 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !SemaDeclResult {
38193764 .invalidate_decl_ref = true,
38203765 };
38213766
3822 const has_runtime_bits = queue_linker_work and (is_func or try sema.typeHasRuntimeBits(decl.ty));
3767 const has_runtime_bits = queue_linker_work and (is_func or try sema.typeHasRuntimeBits(decl_ty));
38233768 if (has_runtime_bits) {
38243769 // Needed for codegen_decl which will call updateDecl and then the
38253770 // codegen backend wants full access to the Decl Type.
3826 try sema.resolveTypeFully(decl.ty);
3771 try sema.resolveTypeFully(decl_ty);
38273772
38283773 try mod.comp.work_queue.writeItem(.{ .codegen_decl = decl_index });
38293774
......@@ -3850,7 +3795,7 @@ fn semaAnonOwnerDecl(zcu: *Zcu, decl_index: Decl.Index) !SemaDeclResult {
38503795
38513796 log.debug("semaAnonOwnerDecl '{d}'", .{@intFromEnum(decl_index)});
38523797
3853 switch (decl.ty.zigTypeTag(zcu)) {
3798 switch (decl.typeOf(zcu).zigTypeTag(zcu)) {
38543799 .Fn => @panic("TODO: update fn instance"),
38553800 .Type => {},
38563801 else => unreachable,
......@@ -4380,7 +4325,6 @@ fn scanDecl(iter: *ScanDeclIter, decl_inst: Zir.Inst.Index) Allocator.Error!void
43804325 const decl = zcu.declPtr(decl_index);
43814326 const was_exported = decl.is_exported;
43824327 assert(decl.kind == kind); // ZIR tracking should preserve this
4383 assert(decl.alive);
43844328 decl.name = decl_name;
43854329 decl.src_node = decl_node;
43864330 decl.src_line = line;
......@@ -4397,7 +4341,6 @@ fn scanDecl(iter: *ScanDeclIter, decl_inst: Zir.Inst.Index) Allocator.Error!void
43974341 new_decl.is_pub = declaration.flags.is_pub;
43984342 new_decl.is_exported = declaration.flags.is_export;
43994343 new_decl.zir_decl_index = tracked_inst.toOptional();
4400 new_decl.alive = true; // This Decl corresponds to an AST node and is therefore always alive.
44014344 break :decl_index .{ false, new_decl_index };
44024345 };
44034346
......@@ -4450,22 +4393,6 @@ fn scanDecl(iter: *ScanDeclIter, decl_inst: Zir.Inst.Index) Allocator.Error!void
44504393 }
44514394}
44524395
4453/// This function is exclusively called for anonymous decls.
4454/// All resources referenced by anonymous decls are owned by InternPool
4455/// so there is no cleanup to do here.
4456pub fn deleteUnusedDecl(mod: *Module, decl_index: Decl.Index) void {
4457 const gpa = mod.gpa;
4458 const ip = &mod.intern_pool;
4459
4460 ip.destroyDecl(gpa, decl_index);
4461
4462 if (mod.emit_h) |mod_emit_h| {
4463 const decl_emit_h = mod_emit_h.declPtr(decl_index);
4464 decl_emit_h.fwd_decl.deinit(gpa);
4465 decl_emit_h.* = undefined;
4466 }
4467}
4468
44694396/// Cancel the creation of an anon decl and delete any references to it.
44704397/// If other decls depend on this decl, they must be aborted first.
44714398pub fn abortAnonDecl(mod: *Module, decl_index: Decl.Index) void {
......@@ -4475,12 +4402,8 @@ pub fn abortAnonDecl(mod: *Module, decl_index: Decl.Index) void {
44754402
44764403/// Finalize the creation of an anon decl.
44774404pub fn finalizeAnonDecl(mod: *Module, decl_index: Decl.Index) Allocator.Error!void {
4478 // The Decl starts off with alive=false and the codegen backend will set alive=true
4479 // if the Decl is referenced by an instruction or another constant. Otherwise,
4480 // the Decl will be garbage collected by the `codegen_decl` task instead of sent
4481 // to the linker.
4482 if (mod.declPtr(decl_index).ty.isFnOrHasRuntimeBits(mod)) {
4483 try mod.comp.anon_work_queue.writeItem(.{ .codegen_decl = decl_index });
4405 if (mod.declPtr(decl_index).typeOf(mod).isFnOrHasRuntimeBits(mod)) {
4406 try mod.comp.work_queue.writeItem(.{ .codegen_decl = decl_index });
44844407 }
44854408}
44864409
......@@ -4563,7 +4486,7 @@ pub fn analyzeFnBody(mod: *Module, func_index: InternPool.Index, arena: Allocato
45634486 // the runtime-known parameters only, not to be confused with the
45644487 // generic_owner function type, which potentially has more parameters,
45654488 // including comptime parameters.
4566 const fn_ty = decl.ty;
4489 const fn_ty = decl.typeOf(mod);
45674490 const fn_ty_info = mod.typeToFunc(fn_ty).?;
45684491
45694492 var sema: Sema = .{
......@@ -4812,7 +4735,6 @@ pub fn allocateNewDecl(
48124735 .src_line = undefined,
48134736 .has_tv = false,
48144737 .owns_tv = false,
4815 .ty = undefined,
48164738 .val = undefined,
48174739 .alignment = undefined,
48184740 .@"linksection" = .none,
......@@ -4821,7 +4743,6 @@ pub fn allocateNewDecl(
48214743 .zir_decl_index = .none,
48224744 .is_pub = false,
48234745 .is_exported = false,
4824 .alive = false,
48254746 .kind = .anon,
48264747 });
48274748
......@@ -4856,41 +4777,18 @@ pub fn errorSetBits(mod: *Module) u16 {
48564777 return std.math.log2_int_ceil(ErrorInt, mod.error_limit + 1); // +1 for no error
48574778}
48584779
4859pub fn createAnonymousDecl(mod: *Module, block: *Sema.Block, typed_value: TypedValue) !Decl.Index {
4860 const src_decl = mod.declPtr(block.src_decl);
4861 return mod.createAnonymousDeclFromDecl(src_decl, block.namespace, typed_value);
4862}
4863
4864pub fn createAnonymousDeclFromDecl(
4865 mod: *Module,
4866 src_decl: *Decl,
4867 namespace: Namespace.Index,
4868 tv: TypedValue,
4869) !Decl.Index {
4870 const new_decl_index = try mod.allocateNewDecl(namespace, src_decl.src_node);
4871 errdefer mod.destroyDecl(new_decl_index);
4872 const name = try mod.intern_pool.getOrPutStringFmt(mod.gpa, "{}__anon_{d}", .{
4873 src_decl.name.fmt(&mod.intern_pool), @intFromEnum(new_decl_index),
4874 });
4875 try mod.initNewAnonDecl(new_decl_index, src_decl.src_line, tv, name);
4876 return new_decl_index;
4877}
4878
48794780pub fn initNewAnonDecl(
48804781 mod: *Module,
48814782 new_decl_index: Decl.Index,
48824783 src_line: u32,
4883 typed_value: TypedValue,
4784 val: Value,
48844785 name: InternPool.NullTerminatedString,
48854786) Allocator.Error!void {
4886 assert(typed_value.ty.toIntern() == mod.intern_pool.typeOf(typed_value.val.toIntern()));
4887
48884787 const new_decl = mod.declPtr(new_decl_index);
48894788
48904789 new_decl.name = name;
48914790 new_decl.src_line = src_line;
4892 new_decl.ty = typed_value.ty;
4893 new_decl.val = typed_value.val;
4791 new_decl.val = val;
48944792 new_decl.alignment = .none;
48954793 new_decl.@"linksection" = .none;
48964794 new_decl.has_tv = true;
......@@ -5419,9 +5317,9 @@ pub fn populateTestFunctions(
54195317 try mod.ensureDeclAnalyzed(decl_index);
54205318 }
54215319 const decl = mod.declPtr(decl_index);
5422 const test_fn_ty = decl.ty.slicePtrFieldType(mod).childType(mod);
5320 const test_fn_ty = decl.typeOf(mod).slicePtrFieldType(mod).childType(mod);
54235321
5424 const array_decl_index = d: {
5322 const array_anon_decl: InternPool.Key.Ptr.Addr.AnonDecl = array: {
54255323 // Add mod.test_functions to an array decl then make the test_functions
54265324 // decl reference it as a slice.
54275325 const test_fn_vals = try gpa.alloc(InternPool.Index, mod.test_functions.count());
......@@ -5431,21 +5329,20 @@ pub fn populateTestFunctions(
54315329 const test_decl = mod.declPtr(test_decl_index);
54325330 const test_decl_name = try gpa.dupe(u8, ip.stringToSlice(try test_decl.fullyQualifiedName(mod)));
54335331 defer gpa.free(test_decl_name);
5434 const test_name_decl_index = n: {
5435 const test_name_decl_ty = try mod.arrayType(.{
5332 const test_name_anon_decl: InternPool.Key.Ptr.Addr.AnonDecl = n: {
5333 const test_name_ty = try mod.arrayType(.{
54365334 .len = test_decl_name.len,
54375335 .child = .u8_type,
54385336 });
5439 const test_name_decl_index = try mod.createAnonymousDeclFromDecl(decl, decl.src_namespace, .{
5440 .ty = test_name_decl_ty,
5441 .val = Value.fromInterned((try mod.intern(.{ .aggregate = .{
5442 .ty = test_name_decl_ty.toIntern(),
5443 .storage = .{ .bytes = test_decl_name },
5444 } }))),
5445 });
5446 break :n test_name_decl_index;
5337 const test_name_val = try mod.intern(.{ .aggregate = .{
5338 .ty = test_name_ty.toIntern(),
5339 .storage = .{ .bytes = test_decl_name },
5340 } });
5341 break :n .{
5342 .orig_ty = (try mod.singleConstPtrType(test_name_ty)).toIntern(),
5343 .val = test_name_val,
5344 };
54475345 };
5448 try mod.linkerUpdateDecl(test_name_decl_index);
54495346
54505347 const test_fn_fields = .{
54515348 // name
......@@ -5453,7 +5350,7 @@ pub fn populateTestFunctions(
54535350 .ty = .slice_const_u8_type,
54545351 .ptr = try mod.intern(.{ .ptr = .{
54555352 .ty = .manyptr_const_u8_type,
5456 .addr = .{ .decl = test_name_decl_index },
5353 .addr = .{ .anon_decl = test_name_anon_decl },
54575354 } }),
54585355 .len = try mod.intern(.{ .int = .{
54595356 .ty = .usize_type,
......@@ -5463,7 +5360,7 @@ pub fn populateTestFunctions(
54635360 // func
54645361 try mod.intern(.{ .ptr = .{
54655362 .ty = try mod.intern(.{ .ptr_type = .{
5466 .child = test_decl.ty.toIntern(),
5363 .child = test_decl.typeOf(mod).toIntern(),
54675364 .flags = .{
54685365 .is_const = true,
54695366 },
......@@ -5477,22 +5374,20 @@ pub fn populateTestFunctions(
54775374 } });
54785375 }
54795376
5480 const array_decl_ty = try mod.arrayType(.{
5377 const array_ty = try mod.arrayType(.{
54815378 .len = test_fn_vals.len,
54825379 .child = test_fn_ty.toIntern(),
54835380 .sentinel = .none,
54845381 });
5485 const array_decl_index = try mod.createAnonymousDeclFromDecl(decl, decl.src_namespace, .{
5486 .ty = array_decl_ty,
5487 .val = Value.fromInterned((try mod.intern(.{ .aggregate = .{
5488 .ty = array_decl_ty.toIntern(),
5489 .storage = .{ .elems = test_fn_vals },
5490 } }))),
5491 });
5492
5493 break :d array_decl_index;
5382 const array_val = try mod.intern(.{ .aggregate = .{
5383 .ty = array_ty.toIntern(),
5384 .storage = .{ .elems = test_fn_vals },
5385 } });
5386 break :array .{
5387 .orig_ty = (try mod.singleConstPtrType(array_ty)).toIntern(),
5388 .val = array_val,
5389 };
54945390 };
5495 try mod.linkerUpdateDecl(array_decl_index);
54965391
54975392 {
54985393 const new_ty = try mod.ptrType(.{
......@@ -5507,7 +5402,7 @@ pub fn populateTestFunctions(
55075402 .ty = new_ty.toIntern(),
55085403 .ptr = try mod.intern(.{ .ptr = .{
55095404 .ty = new_ty.slicePtrFieldType(mod).toIntern(),
5510 .addr = .{ .decl = array_decl_index },
5405 .addr = .{ .anon_decl = array_anon_decl },
55115406 } }),
55125407 .len = (try mod.intValue(Type.usize, mod.test_functions.count())).toIntern(),
55135408 } });
......@@ -5515,7 +5410,6 @@ pub fn populateTestFunctions(
55155410
55165411 // Since we are replacing the Decl's value we must perform cleanup on the
55175412 // previous value.
5518 decl.ty = new_ty;
55195413 decl.val = new_val;
55205414 decl.has_tv = true;
55215415 }
......@@ -5590,53 +5484,6 @@ fn reportRetryableFileError(
55905484 gop.value_ptr.* = err_msg;
55915485}
55925486
5593pub fn markReferencedDeclsAlive(mod: *Module, val: Value) Allocator.Error!void {
5594 switch (mod.intern_pool.indexToKey(val.toIntern())) {
5595 .variable => |variable| try mod.markDeclIndexAlive(variable.decl),
5596 .extern_func => |extern_func| try mod.markDeclIndexAlive(extern_func.decl),
5597 .func => |func| try mod.markDeclIndexAlive(func.owner_decl),
5598 .error_union => |error_union| switch (error_union.val) {
5599 .err_name => {},
5600 .payload => |payload| try mod.markReferencedDeclsAlive(Value.fromInterned(payload)),
5601 },
5602 .slice => |slice| {
5603 try mod.markReferencedDeclsAlive(Value.fromInterned(slice.ptr));
5604 try mod.markReferencedDeclsAlive(Value.fromInterned(slice.len));
5605 },
5606 .ptr => |ptr| switch (ptr.addr) {
5607 .decl => |decl| try mod.markDeclIndexAlive(decl),
5608 .anon_decl => {},
5609 .int, .comptime_field, .comptime_alloc => {},
5610 .eu_payload, .opt_payload => |parent| try mod.markReferencedDeclsAlive(Value.fromInterned(parent)),
5611 .elem, .field => |base_index| try mod.markReferencedDeclsAlive(Value.fromInterned(base_index.base)),
5612 },
5613 .opt => |opt| if (opt.val != .none) try mod.markReferencedDeclsAlive(Value.fromInterned(opt.val)),
5614 .aggregate => |aggregate| for (aggregate.storage.values()) |elem|
5615 try mod.markReferencedDeclsAlive(Value.fromInterned(elem)),
5616 .un => |un| {
5617 if (un.tag != .none) try mod.markReferencedDeclsAlive(Value.fromInterned(un.tag));
5618 try mod.markReferencedDeclsAlive(Value.fromInterned(un.val));
5619 },
5620 else => {},
5621 }
5622}
5623
5624pub fn markDeclAlive(mod: *Module, decl: *Decl) Allocator.Error!void {
5625 if (decl.alive) return;
5626 decl.alive = true;
5627
5628 _ = try decl.internValue(mod);
5629
5630 // This is the first time we are marking this Decl alive. We must
5631 // therefore recurse into its value and mark any Decl it references
5632 // as also alive, so that any Decl referenced does not get garbage collected.
5633 try mod.markReferencedDeclsAlive(decl.val);
5634}
5635
5636fn markDeclIndexAlive(mod: *Module, decl_index: Decl.Index) Allocator.Error!void {
5637 return mod.markDeclAlive(mod.declPtr(decl_index));
5638}
5639
56405487pub fn addGlobalAssembly(mod: *Module, decl_index: Decl.Index, source: []const u8) !void {
56415488 const gop = try mod.global_assembly.getOrPut(mod.gpa, decl_index);
56425489 if (gop.found_existing) {
src/Sema.zig+559-754
......@@ -139,8 +139,7 @@ const MaybeComptimeAlloc = struct {
139139};
140140
141141const ComptimeAlloc = struct {
142 ty: Type,
143 val: Value,
142 val: MutableValue,
144143 is_const: bool,
145144 /// `.none` indicates that the alignment is the natural alignment of `val`.
146145 alignment: Alignment,
......@@ -153,8 +152,7 @@ const ComptimeAlloc = struct {
153152fn newComptimeAlloc(sema: *Sema, block: *Block, ty: Type, alignment: Alignment) !ComptimeAllocIndex {
154153 const idx = sema.comptime_allocs.items.len;
155154 try sema.comptime_allocs.append(sema.gpa, .{
156 .ty = ty,
157 .val = Value.fromInterned(try sema.mod.intern(.{ .undef = ty.toIntern() })),
155 .val = .{ .interned = try sema.mod.intern(.{ .undef = ty.toIntern() }) },
158156 .is_const = false,
159157 .alignment = alignment,
160158 .runtime_index = block.runtime_index,
......@@ -175,8 +173,8 @@ const log = std.log.scoped(.sema);
175173
176174const Sema = @This();
177175const Value = @import("Value.zig");
176const MutableValue = @import("mutable_value.zig").MutableValue;
178177const Type = @import("type.zig").Type;
179const TypedValue = @import("TypedValue.zig");
180178const Air = @import("Air.zig");
181179const Zir = std.zig.Zir;
182180const Module = @import("Module.zig");
......@@ -1709,7 +1707,7 @@ fn analyzeBodyInner(
17091707 .needed_comptime_reason = "condition in comptime branch must be comptime-known",
17101708 .block_comptime_reason = block.comptime_reason,
17111709 });
1712 const inline_body = if (cond.val.toBool()) then_body else else_body;
1710 const inline_body = if (cond.toBool()) then_body else else_body;
17131711
17141712 try sema.maybeErrorUnwrapCondbr(block, inline_body, extra.data.condition, cond_src);
17151713
......@@ -1729,7 +1727,7 @@ fn analyzeBodyInner(
17291727 .needed_comptime_reason = "condition in comptime branch must be comptime-known",
17301728 .block_comptime_reason = block.comptime_reason,
17311729 });
1732 const inline_body = if (cond.val.toBool()) then_body else else_body;
1730 const inline_body = if (cond.toBool()) then_body else else_body;
17331731
17341732 try sema.maybeErrorUnwrapCondbr(block, inline_body, extra.data.condition, cond_src);
17351733 const old_runtime_index = block.runtime_index;
......@@ -1882,10 +1880,10 @@ pub fn toConstString(
18821880 air_inst: Air.Inst.Ref,
18831881 reason: NeededComptimeReason,
18841882) ![]u8 {
1885 const wanted_type = Type.slice_const_u8;
1886 const coerced_inst = try sema.coerce(block, wanted_type, air_inst, src);
1887 const val = try sema.resolveConstDefinedValue(block, src, coerced_inst, reason);
1888 return val.toAllocatedBytes(wanted_type, sema.arena, sema.mod);
1883 const coerced_inst = try sema.coerce(block, Type.slice_const_u8, air_inst, src);
1884 const slice_val = try sema.resolveConstDefinedValue(block, src, coerced_inst, reason);
1885 const arr_val = try sema.derefSliceAsArray(block, src, slice_val, reason);
1886 return arr_val.toAllocatedBytes(arr_val.typeOf(sema.mod), sema.arena, sema.mod);
18891887}
18901888
18911889pub fn resolveConstStringIntern(
......@@ -2180,13 +2178,9 @@ fn resolveInstConst(
21802178 src: LazySrcLoc,
21812179 zir_ref: Zir.Inst.Ref,
21822180 reason: NeededComptimeReason,
2183) CompileError!TypedValue {
2181) CompileError!Value {
21842182 const air_ref = try sema.resolveInst(zir_ref);
2185 const val = try sema.resolveConstDefinedValue(block, src, air_ref, reason);
2186 return .{
2187 .ty = sema.typeOf(air_ref),
2188 .val = val,
2189 };
2183 return sema.resolveConstDefinedValue(block, src, air_ref, reason);
21902184}
21912185
21922186/// Value Tag may be `undef` or `variable`.
......@@ -2195,7 +2189,7 @@ pub fn resolveFinalDeclValue(
21952189 block: *Block,
21962190 src: LazySrcLoc,
21972191 air_ref: Air.Inst.Ref,
2198) CompileError!TypedValue {
2192) CompileError!Value {
21992193 const val = try sema.resolveValueAllowVariables(air_ref) orelse {
22002194 return sema.failWithNeededComptime(block, src, .{
22012195 .needed_comptime_reason = "global variable initializer must be comptime-known",
......@@ -2205,10 +2199,7 @@ pub fn resolveFinalDeclValue(
22052199 if (val.canMutateComptimeVarState(sema.mod)) {
22062200 return sema.fail(block, src, "global variable contains reference to comptime var", .{});
22072201 }
2208 return .{
2209 .ty = sema.typeOf(air_ref),
2210 .val = val,
2211 };
2202 return val;
22122203}
22132204
22142205fn failWithNeededComptime(sema: *Sema, block: *Block, src: LazySrcLoc, reason: NeededComptimeReason) CompileError {
......@@ -2281,7 +2272,7 @@ fn failWithIntegerOverflow(sema: *Sema, block: *Block, src: LazySrcLoc, int_ty:
22812272 if (int_ty.zigTypeTag(mod) == .Vector) {
22822273 const msg = msg: {
22832274 const msg = try sema.errMsg(block, src, "overflow of vector type '{}' with value '{}'", .{
2284 int_ty.fmt(sema.mod), val.fmtValue(int_ty, sema.mod),
2275 int_ty.fmt(sema.mod), val.fmtValue(sema.mod),
22852276 });
22862277 errdefer msg.destroy(sema.gpa);
22872278 try sema.errNote(block, src, msg, "when computing vector element at index '{d}'", .{vector_index});
......@@ -2290,7 +2281,7 @@ fn failWithIntegerOverflow(sema: *Sema, block: *Block, src: LazySrcLoc, int_ty:
22902281 return sema.failWithOwnedErrorMsg(block, msg);
22912282 }
22922283 return sema.fail(block, src, "overflow of integer type '{}' with value '{}'", .{
2293 int_ty.fmt(sema.mod), val.fmtValue(int_ty, sema.mod),
2284 int_ty.fmt(sema.mod), val.fmtValue(sema.mod),
22942285 });
22952286}
22962287
......@@ -2826,10 +2817,14 @@ fn zirStructDecl(
28262817 });
28272818 errdefer wip_ty.cancel(ip);
28282819
2829 const new_decl_index = try sema.createAnonymousDeclTypeNamed(block, src, .{
2830 .ty = Type.type,
2831 .val = Value.fromInterned(wip_ty.index),
2832 }, small.name_strategy, "struct", inst);
2820 const new_decl_index = try sema.createAnonymousDeclTypeNamed(
2821 block,
2822 src,
2823 Value.fromInterned(wip_ty.index),
2824 small.name_strategy,
2825 "struct",
2826 inst,
2827 );
28332828 mod.declPtr(new_decl_index).owns_tv = true;
28342829 errdefer mod.abortAnonDecl(new_decl_index);
28352830
......@@ -2862,7 +2857,7 @@ fn createAnonymousDeclTypeNamed(
28622857 sema: *Sema,
28632858 block: *Block,
28642859 src: LazySrcLoc,
2865 typed_value: TypedValue,
2860 val: Value,
28662861 name_strategy: Zir.Inst.NameStrategy,
28672862 anon_prefix: []const u8,
28682863 inst: ?Zir.Inst.Index,
......@@ -2888,12 +2883,12 @@ fn createAnonymousDeclTypeNamed(
28882883 const name = mod.intern_pool.getOrPutStringFmt(gpa, "{}__{s}_{d}", .{
28892884 src_decl.name.fmt(&mod.intern_pool), anon_prefix, @intFromEnum(new_decl_index),
28902885 }) catch unreachable;
2891 try mod.initNewAnonDecl(new_decl_index, src_decl.src_line, typed_value, name);
2886 try mod.initNewAnonDecl(new_decl_index, src_decl.src_line, val, name);
28922887 return new_decl_index;
28932888 },
28942889 .parent => {
28952890 const name = mod.declPtr(block.src_decl).name;
2896 try mod.initNewAnonDecl(new_decl_index, src_decl.src_line, typed_value, name);
2891 try mod.initNewAnonDecl(new_decl_index, src_decl.src_line, val, name);
28972892 return new_decl_index;
28982893 },
28992894 .func => {
......@@ -2916,10 +2911,10 @@ fn createAnonymousDeclTypeNamed(
29162911 // function and the name doesn't matter since it will later
29172912 // result in a compile error.
29182913 const arg_val = sema.resolveConstValue(block, .unneeded, arg, undefined) catch
2919 return sema.createAnonymousDeclTypeNamed(block, src, typed_value, .anon, anon_prefix, null);
2914 return sema.createAnonymousDeclTypeNamed(block, src, val, .anon, anon_prefix, null);
29202915
29212916 if (arg_i != 0) try writer.writeByte(',');
2922 try writer.print("{}", .{arg_val.fmtValue(sema.typeOf(arg), sema.mod)});
2917 try writer.print("{}", .{arg_val.fmtValue(sema.mod)});
29232918
29242919 arg_i += 1;
29252920 continue;
......@@ -2929,7 +2924,7 @@ fn createAnonymousDeclTypeNamed(
29292924
29302925 try writer.writeByte(')');
29312926 const name = try mod.intern_pool.getOrPutString(gpa, buf.items);
2932 try mod.initNewAnonDecl(new_decl_index, src_decl.src_line, typed_value, name);
2927 try mod.initNewAnonDecl(new_decl_index, src_decl.src_line, val, name);
29332928 return new_decl_index;
29342929 },
29352930 .dbg_var => {
......@@ -2944,12 +2939,12 @@ fn createAnonymousDeclTypeNamed(
29442939 src_decl.name.fmt(&mod.intern_pool), zir_data[i].str_op.getStr(sema.code),
29452940 });
29462941
2947 try mod.initNewAnonDecl(new_decl_index, src_decl.src_line, typed_value, name);
2942 try mod.initNewAnonDecl(new_decl_index, src_decl.src_line, val, name);
29482943 return new_decl_index;
29492944 },
29502945 else => {},
29512946 };
2952 return sema.createAnonymousDeclTypeNamed(block, src, typed_value, .anon, anon_prefix, null);
2947 return sema.createAnonymousDeclTypeNamed(block, src, val, .anon, anon_prefix, null);
29532948 },
29542949 }
29552950}
......@@ -3049,10 +3044,14 @@ fn zirEnumDecl(
30493044
30503045 errdefer if (!done) wip_ty.cancel(ip);
30513046
3052 const new_decl_index = try sema.createAnonymousDeclTypeNamed(block, src, .{
3053 .ty = Type.type,
3054 .val = Value.fromInterned(wip_ty.index),
3055 }, small.name_strategy, "enum", inst);
3047 const new_decl_index = try sema.createAnonymousDeclTypeNamed(
3048 block,
3049 src,
3050 Value.fromInterned(wip_ty.index),
3051 small.name_strategy,
3052 "enum",
3053 inst,
3054 );
30563055 const new_decl = mod.declPtr(new_decl_index);
30573056 new_decl.owns_tv = true;
30583057 errdefer if (!done) mod.abortAnonDecl(new_decl_index);
......@@ -3187,7 +3186,7 @@ fn zirEnumDecl(
31873186 }).lazy;
31883187 const other_field_src = mod.fieldSrcLoc(new_decl_index, .{ .index = conflict.prev_field_idx }).lazy;
31893188 const msg = msg: {
3190 const msg = try sema.errMsg(block, value_src, "enum tag value {} already taken", .{last_tag_val.?.fmtValue(int_tag_ty, sema.mod)});
3189 const msg = try sema.errMsg(block, value_src, "enum tag value {} already taken", .{last_tag_val.?.fmtValue(sema.mod)});
31913190 errdefer msg.destroy(gpa);
31923191 try sema.errNote(block, other_field_src, msg, "other occurrence here", .{});
31933192 break :msg msg;
......@@ -3207,7 +3206,7 @@ fn zirEnumDecl(
32073206 const field_src = mod.fieldSrcLoc(new_decl_index, .{ .index = field_i }).lazy;
32083207 const other_field_src = mod.fieldSrcLoc(new_decl_index, .{ .index = conflict.prev_field_idx }).lazy;
32093208 const msg = msg: {
3210 const msg = try sema.errMsg(block, field_src, "enum tag value {} already taken", .{last_tag_val.?.fmtValue(int_tag_ty, sema.mod)});
3209 const msg = try sema.errMsg(block, field_src, "enum tag value {} already taken", .{last_tag_val.?.fmtValue(sema.mod)});
32113210 errdefer msg.destroy(gpa);
32123211 try sema.errNote(block, other_field_src, msg, "other occurrence here", .{});
32133212 break :msg msg;
......@@ -3229,7 +3228,7 @@ fn zirEnumDecl(
32293228 .range = if (has_tag_value) .value else .name,
32303229 }).lazy;
32313230 const msg = try sema.errMsg(block, value_src, "enumeration value '{}' too large for type '{}'", .{
3232 last_tag_val.?.fmtValue(int_tag_ty, mod), int_tag_ty.fmt(mod),
3231 last_tag_val.?.fmtValue(mod), int_tag_ty.fmt(mod),
32333232 });
32343233 return sema.failWithOwnedErrorMsg(block, msg);
32353234 }
......@@ -3316,10 +3315,14 @@ fn zirUnionDecl(
33163315 });
33173316 errdefer wip_ty.cancel(ip);
33183317
3319 const new_decl_index = try sema.createAnonymousDeclTypeNamed(block, src, .{
3320 .ty = Type.type,
3321 .val = Value.fromInterned(wip_ty.index),
3322 }, small.name_strategy, "union", inst);
3318 const new_decl_index = try sema.createAnonymousDeclTypeNamed(
3319 block,
3320 src,
3321 Value.fromInterned(wip_ty.index),
3322 small.name_strategy,
3323 "union",
3324 inst,
3325 );
33233326 mod.declPtr(new_decl_index).owns_tv = true;
33243327 errdefer mod.abortAnonDecl(new_decl_index);
33253328
......@@ -3400,10 +3403,14 @@ fn zirOpaqueDecl(
34003403 };
34013404 errdefer wip_ty.cancel(ip);
34023405
3403 const new_decl_index = try sema.createAnonymousDeclTypeNamed(block, src, .{
3404 .ty = Type.type,
3405 .val = Value.fromInterned(wip_ty.index),
3406 }, small.name_strategy, "opaque", inst);
3406 const new_decl_index = try sema.createAnonymousDeclTypeNamed(
3407 block,
3408 src,
3409 Value.fromInterned(wip_ty.index),
3410 small.name_strategy,
3411 "opaque",
3412 inst,
3413 );
34073414 mod.declPtr(new_decl_index).owns_tv = true;
34083415 errdefer mod.abortAnonDecl(new_decl_index);
34093416
......@@ -3463,10 +3470,14 @@ fn zirErrorSetDecl(
34633470
34643471 const error_set_ty = try mod.errorSetFromUnsortedNames(names.keys());
34653472
3466 const new_decl_index = try sema.createAnonymousDeclTypeNamed(block, src, .{
3467 .ty = Type.type,
3468 .val = error_set_ty.toValue(),
3469 }, name_strategy, "error", inst);
3473 const new_decl_index = try sema.createAnonymousDeclTypeNamed(
3474 block,
3475 src,
3476 error_set_ty.toValue(),
3477 name_strategy,
3478 "error",
3479 inst,
3480 );
34703481 const new_decl = mod.declPtr(new_decl_index);
34713482 new_decl.owns_tv = true;
34723483 errdefer mod.abortAnonDecl(new_decl_index);
......@@ -3762,10 +3773,10 @@ fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
37623773 if (!sema.isComptimeMutablePtr(ptr_val)) break :already_ct;
37633774 const alloc_index = mod.intern_pool.indexToKey(ptr_val.toIntern()).ptr.addr.comptime_alloc;
37643775 const ct_alloc = sema.getComptimeAlloc(alloc_index);
3765 const interned = try ct_alloc.val.intern(ct_alloc.ty, mod);
3776 const interned = try ct_alloc.val.intern(mod, sema.arena);
37663777 if (Value.fromInterned(interned).canMutateComptimeVarState(mod)) {
37673778 // Preserve the comptime alloc, just make the pointer const.
3768 ct_alloc.val = Value.fromInterned(interned);
3779 ct_alloc.val = .{ .interned = interned };
37693780 ct_alloc.is_const = true;
37703781 return sema.makePtrConst(block, alloc);
37713782 } else {
......@@ -4030,7 +4041,7 @@ fn finishResolveComptimeKnownAllocPtr(
40304041 const alloc_index = existing_comptime_alloc orelse a: {
40314042 const idx = try sema.newComptimeAlloc(block, alloc_ty.childType(zcu), alloc_ty.ptrAlignment(zcu));
40324043 const alloc = sema.getComptimeAlloc(idx);
4033 alloc.val = Value.fromInterned(result_val);
4044 alloc.val = .{ .interned = result_val };
40344045 break :a idx;
40354046 };
40364047 sema.getComptimeAlloc(alloc_index).is_const = true;
......@@ -4193,7 +4204,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com
41934204 .anon_decl => |a| a.val,
41944205 .comptime_alloc => |i| val: {
41954206 const alloc = sema.getComptimeAlloc(i);
4196 break :val try alloc.val.intern(alloc.ty, mod);
4207 break :val try alloc.val.intern(mod, sema.arena);
41974208 },
41984209 else => unreachable,
41994210 };
......@@ -4370,10 +4381,10 @@ fn zirForLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
43704381 .input_index = len_idx,
43714382 } };
43724383 try sema.errNote(block, a_src, msg, "length {} here", .{
4373 v.fmtValue(Type.usize, sema.mod),
4384 v.fmtValue(sema.mod),
43744385 });
43754386 try sema.errNote(block, arg_src, msg, "length {} here", .{
4376 arg_val.fmtValue(Type.usize, sema.mod),
4387 arg_val.fmtValue(sema.mod),
43774388 });
43784389 break :msg msg;
43794390 };
......@@ -5597,7 +5608,7 @@ fn storeToInferredAllocComptime(
55975608 } });
55985609 } else {
55995610 const alloc_index = try sema.newComptimeAlloc(block, operand_ty, iac.alignment);
5600 sema.getComptimeAlloc(alloc_index).val = operand_val;
5611 sema.getComptimeAlloc(alloc_index).val = .{ .interned = operand_val.toIntern() };
56015612 iac.ptr = try zcu.intern(.{ .ptr = .{
56025613 .ty = alloc_ty.toIntern(),
56035614 .addr = .{ .comptime_alloc = alloc_index },
......@@ -5783,7 +5794,7 @@ fn zirCompileLog(
57835794 const arg_ty = sema.typeOf(arg);
57845795 if (try sema.resolveValueResolveLazy(arg)) |val| {
57855796 try writer.print("@as({}, {})", .{
5786 arg_ty.fmt(mod), val.fmtValue(arg_ty, mod),
5797 arg_ty.fmt(mod), val.fmtValue(mod),
57875798 });
57885799 } else {
57895800 try writer.print("@as({}, [runtime value])", .{arg_ty.fmt(mod)});
......@@ -6395,7 +6406,7 @@ fn zirExportValue(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
63956406 const options = try sema.resolveExportOptions(block, options_src, extra.options);
63966407 if (options.linkage == .internal)
63976408 return;
6398 if (operand.val.getFunction(mod)) |function| {
6409 if (operand.getFunction(mod)) |function| {
63996410 const decl_index = function.owner_decl;
64006411 return sema.analyzeExport(block, src, options, decl_index);
64016412 }
......@@ -6405,7 +6416,7 @@ fn zirExportValue(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
64056416 .src = src,
64066417 .owner_decl = sema.owner_decl_index,
64076418 .src_decl = block.src_decl,
6408 .exported = .{ .value = operand.val.toIntern() },
6419 .exported = .{ .value = operand.toIntern() },
64096420 .status = .in_progress,
64106421 });
64116422}
......@@ -6425,16 +6436,17 @@ pub fn analyzeExport(
64256436
64266437 try mod.ensureDeclAnalyzed(exported_decl_index);
64276438 const exported_decl = mod.declPtr(exported_decl_index);
6439 const export_ty = exported_decl.typeOf(mod);
64286440
6429 if (!try sema.validateExternType(exported_decl.ty, .other)) {
6441 if (!try sema.validateExternType(export_ty, .other)) {
64306442 const msg = msg: {
6431 const msg = try sema.errMsg(block, src, "unable to export type '{}'", .{exported_decl.ty.fmt(mod)});
6443 const msg = try sema.errMsg(block, src, "unable to export type '{}'", .{export_ty.fmt(mod)});
64326444 errdefer msg.destroy(gpa);
64336445
64346446 const src_decl = mod.declPtr(block.src_decl);
6435 try sema.explainWhyTypeIsNotExtern(msg, src_decl.toSrcLoc(src, mod), exported_decl.ty, .other);
6447 try sema.explainWhyTypeIsNotExtern(msg, src_decl.toSrcLoc(src, mod), export_ty, .other);
64366448
6437 try sema.addDeclaredHereNote(msg, exported_decl.ty);
6449 try sema.addDeclaredHereNote(msg, export_ty);
64386450 break :msg msg;
64396451 };
64406452 return sema.failWithOwnedErrorMsg(block, msg);
......@@ -6445,8 +6457,6 @@ pub fn analyzeExport(
64456457 return sema.fail(block, src, "export target cannot be extern", .{});
64466458 }
64476459
6448 // This decl is alive no matter what, since it's being exported
6449 try mod.markDeclAlive(exported_decl);
64506460 try sema.maybeQueueFuncBodyAnalysis(exported_decl_index);
64516461
64526462 try addExport(mod, .{
......@@ -6503,7 +6513,7 @@ fn zirSetAlignStack(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Inst
65036513 }
65046514
65056515 const fn_owner_decl = mod.funcOwnerDeclPtr(sema.func_index);
6506 switch (fn_owner_decl.ty.fnCallingConvention(mod)) {
6516 switch (fn_owner_decl.typeOf(mod).fnCallingConvention(mod)) {
65076517 .Naked => return sema.fail(block, src, "@setAlignStack in naked function", .{}),
65086518 .Inline => return sema.fail(block, src, "@setAlignStack in inline function", .{}),
65096519 else => if (block.inlining != null) {
......@@ -7692,7 +7702,7 @@ fn analyzeCall(
76927702 // comptime memory is mutated.
76937703 const memoized_arg_values = try sema.arena.alloc(InternPool.Index, func_ty_info.param_types.len);
76947704
7695 const owner_info = mod.typeToFunc(fn_owner_decl.ty).?;
7705 const owner_info = mod.typeToFunc(fn_owner_decl.typeOf(mod)).?;
76967706 const new_param_types = try sema.arena.alloc(InternPool.Index, owner_info.param_types.len);
76977707 var new_fn_info: InternPool.GetFuncTypeKey = .{
76987708 .param_types = new_param_types,
......@@ -7835,7 +7845,7 @@ fn analyzeCall(
78357845
78367846 if (is_comptime_call) {
78377847 const result_val = try sema.resolveConstValue(block, .unneeded, result, undefined);
7838 const result_interned = try result_val.intern2(sema.fn_ret_ty, mod);
7848 const result_interned = result_val.toIntern();
78397849
78407850 // Transform ad-hoc inferred error set types into concrete error sets.
78417851 const result_transformed = try sema.resolveAdHocInferredErrorSet(block, call_src, result_interned);
......@@ -7856,8 +7866,7 @@ fn analyzeCall(
78567866 }
78577867
78587868 if (try sema.resolveValue(result)) |result_val| {
7859 const result_interned = try result_val.intern2(sema.fn_ret_ty, mod);
7860 const result_transformed = try sema.resolveAdHocInferredErrorSet(block, call_src, result_interned);
7869 const result_transformed = try sema.resolveAdHocInferredErrorSet(block, call_src, result_val.toIntern());
78617870 break :res2 Air.internedToRef(result_transformed);
78627871 }
78637872
......@@ -7960,9 +7969,9 @@ fn handleTailCall(sema: *Sema, block: *Block, call_src: LazySrcLoc, func_ty: Typ
79607969 });
79617970 }
79627971 const func_decl = mod.funcOwnerDeclPtr(sema.owner_func_index);
7963 if (!func_ty.eql(func_decl.ty, mod)) {
7972 if (!func_ty.eql(func_decl.typeOf(mod), mod)) {
79647973 return sema.fail(block, call_src, "unable to perform tail call: type of function being called '{}' does not match type of calling function '{}'", .{
7965 func_ty.fmt(mod), func_decl.ty.fmt(mod),
7974 func_ty.fmt(mod), func_decl.typeOf(mod).fmt(mod),
79667975 });
79677976 }
79687977 _ = try block.addUnOp(.ret, result);
......@@ -8042,7 +8051,7 @@ fn analyzeInlineCallArg(
80428051 // when the hash function is called.
80438052 const resolved_arg_val = try ics.caller().resolveLazyValue(arg_val);
80448053 should_memoize.* = should_memoize.* and !resolved_arg_val.canMutateComptimeVarState(mod);
8045 memoized_arg_values[arg_i.*] = try resolved_arg_val.intern(Type.fromInterned(param_ty), mod);
8054 memoized_arg_values[arg_i.*] = resolved_arg_val.toIntern();
80468055 } else {
80478056 ics.callee().inst_map.putAssumeCapacityNoClobber(inst, casted_arg);
80488057 }
......@@ -8081,7 +8090,7 @@ fn analyzeInlineCallArg(
80818090 // when the hash function is called.
80828091 const resolved_arg_val = try ics.caller().resolveLazyValue(arg_val);
80838092 should_memoize.* = should_memoize.* and !resolved_arg_val.canMutateComptimeVarState(mod);
8084 memoized_arg_values[arg_i.*] = try resolved_arg_val.intern(ics.caller().typeOf(uncasted_arg), mod);
8093 memoized_arg_values[arg_i.*] = resolved_arg_val.toIntern();
80858094 } else {
80868095 if (zir_tags[@intFromEnum(inst)] == .param_anytype_comptime) {
80878096 _ = try ics.caller().resolveConstValue(arg_block, arg_src, uncasted_arg, .{
......@@ -8871,7 +8880,7 @@ fn zirEnumFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
88718880 return Air.internedToRef((try mod.getCoerced(int_val, dest_ty)).toIntern());
88728881 }
88738882 return sema.fail(block, src, "int value '{}' out of range of non-exhaustive enum '{}'", .{
8874 int_val.fmtValue(sema.typeOf(operand), mod), dest_ty.fmt(mod),
8883 int_val.fmtValue(mod), dest_ty.fmt(mod),
88758884 });
88768885 }
88778886 if (int_val.isUndef(mod)) {
......@@ -8879,7 +8888,7 @@ fn zirEnumFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
88798888 }
88808889 if (!(try sema.enumHasInt(dest_ty, int_val))) {
88818890 return sema.fail(block, src, "enum '{}' has no tag with value '{}'", .{
8882 dest_ty.fmt(mod), int_val.fmtValue(sema.typeOf(operand), mod),
8891 dest_ty.fmt(mod), int_val.fmtValue(mod),
88838892 });
88848893 }
88858894 return Air.internedToRef((try mod.getCoerced(int_val, dest_ty)).toIntern());
......@@ -13925,7 +13934,7 @@ fn zirShl(
1392513934 const rhs_elem = try rhs_val.elemValue(mod, i);
1392613935 if (rhs_elem.compareHetero(.gte, bit_value, mod)) {
1392713936 return sema.fail(block, rhs_src, "shift amount '{}' at index '{d}' is too large for operand type '{}'", .{
13928 rhs_elem.fmtValue(scalar_ty, mod),
13937 rhs_elem.fmtValue(mod),
1392913938 i,
1393013939 scalar_ty.fmt(mod),
1393113940 });
......@@ -13933,7 +13942,7 @@ fn zirShl(
1393313942 }
1393413943 } else if (rhs_val.compareHetero(.gte, bit_value, mod)) {
1393513944 return sema.fail(block, rhs_src, "shift amount '{}' is too large for operand type '{}'", .{
13936 rhs_val.fmtValue(scalar_ty, mod),
13945 rhs_val.fmtValue(mod),
1393713946 scalar_ty.fmt(mod),
1393813947 });
1393913948 }
......@@ -13944,14 +13953,14 @@ fn zirShl(
1394413953 const rhs_elem = try rhs_val.elemValue(mod, i);
1394513954 if (rhs_elem.compareHetero(.lt, try mod.intValue(scalar_rhs_ty, 0), mod)) {
1394613955 return sema.fail(block, rhs_src, "shift by negative amount '{}' at index '{d}'", .{
13947 rhs_elem.fmtValue(scalar_ty, mod),
13956 rhs_elem.fmtValue(mod),
1394813957 i,
1394913958 });
1395013959 }
1395113960 }
1395213961 } else if (rhs_val.compareHetero(.lt, try mod.intValue(rhs_ty, 0), mod)) {
1395313962 return sema.fail(block, rhs_src, "shift by negative amount '{}'", .{
13954 rhs_val.fmtValue(scalar_ty, mod),
13963 rhs_val.fmtValue(mod),
1395513964 });
1395613965 }
1395713966 }
......@@ -14090,7 +14099,7 @@ fn zirShr(
1409014099 const rhs_elem = try rhs_val.elemValue(mod, i);
1409114100 if (rhs_elem.compareHetero(.gte, bit_value, mod)) {
1409214101 return sema.fail(block, rhs_src, "shift amount '{}' at index '{d}' is too large for operand type '{}'", .{
14093 rhs_elem.fmtValue(scalar_ty, mod),
14102 rhs_elem.fmtValue(mod),
1409414103 i,
1409514104 scalar_ty.fmt(mod),
1409614105 });
......@@ -14098,7 +14107,7 @@ fn zirShr(
1409814107 }
1409914108 } else if (rhs_val.compareHetero(.gte, bit_value, mod)) {
1410014109 return sema.fail(block, rhs_src, "shift amount '{}' is too large for operand type '{}'", .{
14101 rhs_val.fmtValue(scalar_ty, mod),
14110 rhs_val.fmtValue(mod),
1410214111 scalar_ty.fmt(mod),
1410314112 });
1410414113 }
......@@ -14109,14 +14118,14 @@ fn zirShr(
1410914118 const rhs_elem = try rhs_val.elemValue(mod, i);
1411014119 if (rhs_elem.compareHetero(.lt, try mod.intValue(rhs_ty.childType(mod), 0), mod)) {
1411114120 return sema.fail(block, rhs_src, "shift by negative amount '{}' at index '{d}'", .{
14112 rhs_elem.fmtValue(scalar_ty, mod),
14121 rhs_elem.fmtValue(mod),
1411314122 i,
1411414123 });
1411514124 }
1411614125 }
1411714126 } else if (rhs_val.compareHetero(.lt, try mod.intValue(rhs_ty, 0), mod)) {
1411814127 return sema.fail(block, rhs_src, "shift by negative amount '{}'", .{
14119 rhs_val.fmtValue(scalar_ty, mod),
14128 rhs_val.fmtValue(mod),
1412014129 });
1412114130 }
1412214131 if (maybe_lhs_val) |lhs_val| {
......@@ -14270,7 +14279,7 @@ fn zirBitNot(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
1427014279 const elems = try sema.arena.alloc(InternPool.Index, vec_len);
1427114280 for (elems, 0..) |*elem, i| {
1427214281 const elem_val = try val.elemValue(mod, i);
14273 elem.* = try (try elem_val.bitwiseNot(scalar_type, sema.arena, mod)).intern(scalar_type, mod);
14282 elem.* = (try elem_val.bitwiseNot(scalar_type, sema.arena, mod)).toIntern();
1427414283 }
1427514284 return Air.internedToRef((try mod.intern(.{ .aggregate = .{
1427614285 .ty = operand_type.toIntern(),
......@@ -14499,12 +14508,16 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1449914508 else => unreachable,
1450014509 }) |rhs_val| {
1450114510 const lhs_sub_val = if (lhs_ty.isSinglePointer(mod))
14502 (try sema.pointerDeref(block, lhs_src, lhs_val, lhs_ty)).?
14511 try sema.pointerDeref(block, lhs_src, lhs_val, lhs_ty) orelse break :rs lhs_src
14512 else if (lhs_ty.isSlice(mod))
14513 try sema.maybeDerefSliceAsArray(block, lhs_src, lhs_val) orelse break :rs lhs_src
1450314514 else
1450414515 lhs_val;
1450514516
1450614517 const rhs_sub_val = if (rhs_ty.isSinglePointer(mod))
14507 (try sema.pointerDeref(block, rhs_src, rhs_val, rhs_ty)).?
14518 try sema.pointerDeref(block, rhs_src, rhs_val, rhs_ty) orelse break :rs rhs_src
14519 else if (rhs_ty.isSlice(mod))
14520 try sema.maybeDerefSliceAsArray(block, rhs_src, rhs_val) orelse break :rs rhs_src
1450814521 else
1450914522 rhs_val;
1451014523
......@@ -14521,7 +14534,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1452114534 } };
1452214535 const coerced_elem_val_inst = try sema.coerce(block, resolved_elem_ty, elem_val_inst, operand_src);
1452314536 const coerced_elem_val = try sema.resolveConstValue(block, operand_src, coerced_elem_val_inst, undefined);
14524 element_vals[elem_i] = try coerced_elem_val.intern(resolved_elem_ty, mod);
14537 element_vals[elem_i] = coerced_elem_val.toIntern();
1452514538 }
1452614539 while (elem_i < result_len) : (elem_i += 1) {
1452714540 const rhs_elem_i = elem_i - lhs_len;
......@@ -14534,7 +14547,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1453414547 } };
1453514548 const coerced_elem_val_inst = try sema.coerce(block, resolved_elem_ty, elem_val_inst, operand_src);
1453614549 const coerced_elem_val = try sema.resolveConstValue(block, operand_src, coerced_elem_val_inst, undefined);
14537 element_vals[elem_i] = try coerced_elem_val.intern(resolved_elem_ty, mod);
14550 element_vals[elem_i] = coerced_elem_val.toIntern();
1453814551 }
1453914552 return sema.addConstantMaybeRef(try mod.intern(.{ .aggregate = .{
1454014553 .ty = result_ty.toIntern(),
......@@ -14624,10 +14637,7 @@ fn getArrayCatInfo(sema: *Sema, block: *Block, src: LazySrcLoc, operand: Air.Ins
1462414637 .Pointer => {
1462514638 const ptr_info = operand_ty.ptrInfo(mod);
1462614639 switch (ptr_info.flags.size) {
14627 // TODO: in the Many case here this should only work if the type
14628 // has a sentinel, and this code should compute the length based
14629 // on the sentinel value.
14630 .Slice, .Many => {
14640 .Slice => {
1463114641 const val = try sema.resolveConstDefinedValue(block, src, operand, .{
1463214642 .needed_comptime_reason = "slice value being concatenated must be comptime-known",
1463314643 });
......@@ -14637,7 +14647,7 @@ fn getArrayCatInfo(sema: *Sema, block: *Block, src: LazySrcLoc, operand: Air.Ins
1463714647 .none => null,
1463814648 else => Value.fromInterned(ptr_info.sentinel),
1463914649 },
14640 .len = val.sliceLen(mod),
14650 .len = try val.sliceLen(sema),
1464114651 };
1464214652 },
1464314653 .One => {
......@@ -14645,7 +14655,7 @@ fn getArrayCatInfo(sema: *Sema, block: *Block, src: LazySrcLoc, operand: Air.Ins
1464514655 return Type.fromInterned(ptr_info.child).arrayInfo(mod);
1464614656 }
1464714657 },
14648 .C => {},
14658 .C, .Many => {},
1464914659 }
1465014660 },
1465114661 .Struct => {
......@@ -14831,9 +14841,11 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1483114841 const ptr_addrspace = if (lhs_ty.zigTypeTag(mod) == .Pointer) lhs_ty.ptrAddressSpace(mod) else null;
1483214842 const lhs_len = try sema.usizeCast(block, lhs_src, lhs_info.len);
1483314843
14834 if (try sema.resolveDefinedValue(block, lhs_src, lhs)) |lhs_val| {
14844 if (try sema.resolveDefinedValue(block, lhs_src, lhs)) |lhs_val| ct: {
1483514845 const lhs_sub_val = if (lhs_ty.isSinglePointer(mod))
14836 (try sema.pointerDeref(block, lhs_src, lhs_val, lhs_ty)).?
14846 try sema.pointerDeref(block, lhs_src, lhs_val, lhs_ty) orelse break :ct
14847 else if (lhs_ty.isSlice(mod))
14848 try sema.maybeDerefSliceAsArray(block, lhs_src, lhs_val) orelse break :ct
1483714849 else
1483814850 lhs_val;
1483914851
......@@ -14841,7 +14853,7 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1484114853 // Optimization for the common pattern of a single element repeated N times, such
1484214854 // as zero-filling a byte array.
1484314855 if (lhs_len == 1 and lhs_info.sentinel == null) {
14844 const elem_val = (try lhs_sub_val.maybeElemValueFull(sema, mod, 0)).?;
14856 const elem_val = try lhs_sub_val.elemValue(mod, 0);
1484514857 break :v try mod.intern(.{ .aggregate = .{
1484614858 .ty = result_ty.toIntern(),
1484714859 .storage = .{ .repeated_elem = elem_val.toIntern() },
......@@ -14853,7 +14865,7 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1485314865 while (elem_i < result_len) {
1485414866 var lhs_i: usize = 0;
1485514867 while (lhs_i < lhs_len) : (lhs_i += 1) {
14856 const elem_val = (try lhs_sub_val.maybeElemValueFull(sema, mod, lhs_i)).?;
14868 const elem_val = try lhs_sub_val.elemValue(mod, lhs_i);
1485714869 element_vals[elem_i] = elem_val.toIntern();
1485814870 elem_i += 1;
1485914871 }
......@@ -15034,7 +15046,7 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
1503415046 block,
1503515047 src,
1503615048 "ambiguous coercion of division operands '{}' and '{}'; non-zero remainder '{}'",
15037 .{ lhs_ty.fmt(mod), rhs_ty.fmt(mod), rem.fmtValue(resolved_type, mod) },
15049 .{ lhs_ty.fmt(mod), rhs_ty.fmt(mod), rem.fmtValue(mod) },
1503815050 );
1503915051 }
1504015052 }
......@@ -15813,7 +15825,7 @@ fn intRem(
1581315825 for (result_data, 0..) |*scalar, i| {
1581415826 const lhs_elem = try lhs.elemValue(mod, i);
1581515827 const rhs_elem = try rhs.elemValue(mod, i);
15816 scalar.* = try (try sema.intRemScalar(lhs_elem, rhs_elem, scalar_ty)).intern(scalar_ty, mod);
15828 scalar.* = (try sema.intRemScalar(lhs_elem, rhs_elem, scalar_ty)).toIntern();
1581715829 }
1581815830 return Value.fromInterned((try mod.intern(.{ .aggregate = .{
1581915831 .ty = ty.toIntern(),
......@@ -17753,7 +17765,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1775317765 const info = ty.intInfo(mod);
1775417766 const field_values = .{
1775517767 // signedness: Signedness,
17756 try (try mod.enumValueFieldIndex(signedness_ty, @intFromEnum(info.signedness))).intern(signedness_ty, mod),
17768 (try mod.enumValueFieldIndex(signedness_ty, @intFromEnum(info.signedness))).toIntern(),
1775717769 // bits: u16,
1775817770 (try mod.intValue(Type.u16, info.bits)).toIntern(),
1775917771 };
......@@ -17823,7 +17835,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1782317835
1782417836 const field_values = .{
1782517837 // size: Size,
17826 try (try mod.enumValueFieldIndex(ptr_size_ty, @intFromEnum(info.flags.size))).intern(ptr_size_ty, mod),
17838 (try mod.enumValueFieldIndex(ptr_size_ty, @intFromEnum(info.flags.size))).toIntern(),
1782717839 // is_const: bool,
1782817840 Value.makeBool(info.flags.is_const).toIntern(),
1782917841 // is_volatile: bool,
......@@ -17831,7 +17843,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1783117843 // alignment: comptime_int,
1783217844 alignment.toIntern(),
1783317845 // address_space: AddressSpace
17834 try (try mod.enumValueFieldIndex(addrspace_ty, @intFromEnum(info.flags.address_space))).intern(addrspace_ty, mod),
17846 (try mod.enumValueFieldIndex(addrspace_ty, @intFromEnum(info.flags.address_space))).toIntern(),
1783517847 // child: type,
1783617848 info.child,
1783717849 // is_allowzero: bool,
......@@ -19975,8 +19987,8 @@ fn unionInit(
1997519987 const tag_val = try mod.enumValueFieldIndex(tag_ty, field_index);
1997619988 return Air.internedToRef((try mod.intern(.{ .un = .{
1997719989 .ty = union_ty.toIntern(),
19978 .tag = try tag_val.intern(tag_ty, mod),
19979 .val = try init_val.intern(field_ty, mod),
19990 .tag = tag_val.toIntern(),
19991 .val = init_val.toIntern(),
1998019992 } })));
1998119993 }
1998219994
......@@ -20099,8 +20111,8 @@ fn zirStructInit(
2009920111 if (try sema.resolveValue(init_inst)) |val| {
2010020112 const struct_val = Value.fromInterned((try mod.intern(.{ .un = .{
2010120113 .ty = resolved_ty.toIntern(),
20102 .tag = try tag_val.intern(tag_ty, mod),
20103 .val = try val.intern(field_ty, mod),
20114 .tag = tag_val.toIntern(),
20115 .val = val.toIntern(),
2010420116 } })));
2010520117 const final_val_inst = try sema.coerce(block, result_ty, Air.internedToRef(struct_val.toIntern()), src);
2010620118 const final_val = (try sema.resolveValue(final_val_inst)).?;
......@@ -20400,7 +20412,7 @@ fn structInitAnon(
2040020412 return sema.failWithOwnedErrorMsg(block, msg);
2040120413 }
2040220414 if (try sema.resolveValue(init)) |init_val| {
20403 field_val.* = try init_val.intern(Type.fromInterned(field_ty.*), mod);
20415 field_val.* = init_val.toIntern();
2040420416 } else {
2040520417 field_val.* = .none;
2040620418 runtime_index = @intCast(i_usize);
......@@ -20577,13 +20589,9 @@ fn zirArrayInit(
2057720589
2057820590 const runtime_index = opt_runtime_index orelse {
2057920591 const elem_vals = try sema.arena.alloc(InternPool.Index, resolved_args.len);
20580 for (elem_vals, resolved_args, 0..) |*val, arg, i| {
20581 const elem_ty = if (is_tuple)
20582 array_ty.structFieldType(i, mod)
20583 else
20584 array_ty.elemType2(mod);
20592 for (elem_vals, resolved_args) |*val, arg| {
2058520593 // We checked that all args are comptime above.
20586 val.* = try ((sema.resolveValue(arg) catch unreachable).?).intern(elem_ty, mod);
20594 val.* = (sema.resolveValue(arg) catch unreachable).?.toIntern();
2058720595 }
2058820596 const arr_val = try mod.intern(.{ .aggregate = .{
2058920597 .ty = array_ty.toIntern(),
......@@ -20998,7 +21006,7 @@ fn maybeConstantUnaryMath(
2099821006 const elems = try sema.arena.alloc(InternPool.Index, vec_len);
2099921007 for (elems, 0..) |*elem, i| {
2100021008 const elem_val = try val.elemValue(sema.mod, i);
21001 elem.* = try (try eval(elem_val, scalar_ty, sema.arena, sema.mod)).intern(scalar_ty, mod);
21009 elem.* = (try eval(elem_val, scalar_ty, sema.arena, sema.mod)).toIntern();
2100221010 }
2100321011 return Air.internedToRef((try mod.intern(.{ .aggregate = .{
2100421012 .ty = result_ty.toIntern(),
......@@ -21086,7 +21094,7 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
2108621094 const enum_decl = mod.declPtr(enum_decl_index);
2108721095 const msg = msg: {
2108821096 const msg = try sema.errMsg(block, src, "no field with value '{}' in enum '{}'", .{
21089 val.fmtValue(enum_ty, sema.mod), enum_decl.name.fmt(ip),
21097 val.fmtValue(sema.mod), enum_decl.name.fmt(ip),
2109021098 });
2109121099 errdefer msg.destroy(sema.gpa);
2109221100 try mod.errNoteNonLazy(enum_decl.srcLoc(mod), msg, "declared here", .{});
......@@ -21129,7 +21137,9 @@ fn zirReify(
2112921137 .needed_comptime_reason = "operand to @Type must be comptime-known",
2113021138 });
2113121139 const union_val = ip.indexToKey(val.toIntern()).un;
21132 if (try sema.anyUndef(Value.fromInterned(union_val.val))) return sema.failWithUseOfUndef(block, src);
21140 if (try sema.anyUndef(block, operand_src, Value.fromInterned(union_val.val))) {
21141 return sema.failWithUseOfUndef(block, operand_src);
21142 }
2113321143 const tag_index = type_info_ty.unionTagFieldIndex(Value.fromInterned(union_val.tag), mod).?;
2113421144 switch (@as(std.builtin.TypeId, @enumFromInt(tag_index))) {
2113521145 .Type => return .type_type,
......@@ -21370,11 +21380,15 @@ fn zirReify(
2137021380 const payload_val = Value.fromInterned(union_val.val).optionalValue(mod) orelse
2137121381 return Air.internedToRef(Type.anyerror.toIntern());
2137221382
21373 const len = try sema.usizeCast(block, src, payload_val.sliceLen(mod));
21383 const names_val = try sema.derefSliceAsArray(block, src, payload_val, .{
21384 .needed_comptime_reason = "error set contents must be comptime-known",
21385 });
21386
21387 const len = try sema.usizeCast(block, src, names_val.typeOf(mod).arrayLen(mod));
2137421388 var names: InferredErrorSet.NameMap = .{};
2137521389 try names.ensureUnusedCapacity(sema.arena, len);
2137621390 for (0..len) |i| {
21377 const elem_val = (try payload_val.maybeElemValueFull(sema, mod, i)).?;
21391 const elem_val = try names_val.elemValue(mod, i);
2137821392 const elem_struct_type = ip.loadStructType(ip.typeOf(elem_val.toIntern()));
2137921393 const name_val = try elem_val.fieldValue(mod, elem_struct_type.nameIndex(
2138021394 ip,
......@@ -21422,7 +21436,7 @@ fn zirReify(
2142221436 const layout = mod.toEnum(std.builtin.Type.ContainerLayout, layout_val);
2142321437
2142421438 // Decls
21425 if (decls_val.sliceLen(mod) > 0) {
21439 if (try decls_val.sliceLen(sema) > 0) {
2142621440 return sema.fail(block, src, "reified structs must have no decls", .{});
2142721441 }
2142821442
......@@ -21430,7 +21444,11 @@ fn zirReify(
2143021444 return sema.fail(block, src, "non-packed struct does not support backing integer type", .{});
2143121445 }
2143221446
21433 return try sema.reifyStruct(block, inst, src, layout, backing_integer_val, fields_val, name_strategy, is_tuple_val.toBool());
21447 const fields_arr = try sema.derefSliceAsArray(block, operand_src, fields_val, .{
21448 .needed_comptime_reason = "struct fields must be comptime-known",
21449 });
21450
21451 return try sema.reifyStruct(block, inst, src, layout, backing_integer_val, fields_arr, name_strategy, is_tuple_val.toBool());
2143421452 },
2143521453 .Enum => {
2143621454 const struct_type = ip.loadStructType(ip.typeOf(union_val.val));
......@@ -21451,11 +21469,15 @@ fn zirReify(
2145121469 try ip.getOrPutString(gpa, "is_exhaustive"),
2145221470 ).?);
2145321471
21454 if (decls_val.sliceLen(mod) > 0) {
21472 if (try decls_val.sliceLen(sema) > 0) {
2145521473 return sema.fail(block, src, "reified enums must have no decls", .{});
2145621474 }
2145721475
21458 return sema.reifyEnum(block, inst, src, tag_type_val.toType(), is_exhaustive_val.toBool(), fields_val, name_strategy);
21476 const fields_arr = try sema.derefSliceAsArray(block, operand_src, fields_val, .{
21477 .needed_comptime_reason = "enum fields must be comptime-known",
21478 });
21479
21480 return sema.reifyEnum(block, inst, src, tag_type_val.toType(), is_exhaustive_val.toBool(), fields_arr, name_strategy);
2145921481 },
2146021482 .Opaque => {
2146121483 const struct_type = ip.loadStructType(ip.typeOf(union_val.val));
......@@ -21465,7 +21487,7 @@ fn zirReify(
2146521487 ).?);
2146621488
2146721489 // Decls
21468 if (decls_val.sliceLen(mod) > 0) {
21490 if (try decls_val.sliceLen(sema) > 0) {
2146921491 return sema.fail(block, src, "reified opaque must have no decls", .{});
2147021492 }
2147121493
......@@ -21480,10 +21502,14 @@ fn zirReify(
2148021502 };
2148121503 errdefer wip_ty.cancel(ip);
2148221504
21483 const new_decl_index = try sema.createAnonymousDeclTypeNamed(block, src, .{
21484 .ty = Type.type,
21485 .val = Value.fromInterned(wip_ty.index),
21486 }, name_strategy, "opaque", inst);
21505 const new_decl_index = try sema.createAnonymousDeclTypeNamed(
21506 block,
21507 src,
21508 Value.fromInterned(wip_ty.index),
21509 name_strategy,
21510 "opaque",
21511 inst,
21512 );
2148721513 mod.declPtr(new_decl_index).owns_tv = true;
2148821514 errdefer mod.abortAnonDecl(new_decl_index);
2148921515
......@@ -21510,12 +21536,16 @@ fn zirReify(
2151021536 try ip.getOrPutString(gpa, "decls"),
2151121537 ).?);
2151221538
21513 if (decls_val.sliceLen(mod) > 0) {
21539 if (try decls_val.sliceLen(sema) > 0) {
2151421540 return sema.fail(block, src, "reified unions must have no decls", .{});
2151521541 }
2151621542 const layout = mod.toEnum(std.builtin.Type.ContainerLayout, layout_val);
2151721543
21518 return sema.reifyUnion(block, inst, src, layout, tag_type_val, fields_val, name_strategy);
21544 const fields_arr = try sema.derefSliceAsArray(block, operand_src, fields_val, .{
21545 .needed_comptime_reason = "union fields must be comptime-known",
21546 });
21547
21548 return sema.reifyUnion(block, inst, src, layout, tag_type_val, fields_arr, name_strategy);
2151921549 },
2152021550 .Fn => {
2152121551 const struct_type = ip.loadStructType(ip.typeOf(union_val.val));
......@@ -21535,7 +21565,7 @@ fn zirReify(
2153521565 ip,
2153621566 try ip.getOrPutString(gpa, "return_type"),
2153721567 ).?);
21538 const params_val = try Value.fromInterned(union_val.val).fieldValue(mod, struct_type.nameIndex(
21568 const params_slice_val = try Value.fromInterned(union_val.val).fieldValue(mod, struct_type.nameIndex(
2153921569 ip,
2154021570 try ip.getOrPutString(gpa, "params"),
2154121571 ).?);
......@@ -21554,12 +21584,16 @@ fn zirReify(
2155421584 const return_type = return_type_val.optionalValue(mod) orelse
2155521585 return sema.fail(block, src, "Type.Fn.return_type must be non-null for @Type", .{});
2155621586
21557 const args_len = try sema.usizeCast(block, src, params_val.sliceLen(mod));
21587 const params_val = try sema.derefSliceAsArray(block, operand_src, params_slice_val, .{
21588 .needed_comptime_reason = "function parameters must be comptime-known",
21589 });
21590
21591 const args_len = try sema.usizeCast(block, src, params_val.typeOf(mod).arrayLen(mod));
2155821592 const param_types = try sema.arena.alloc(InternPool.Index, args_len);
2155921593
2156021594 var noalias_bits: u32 = 0;
2156121595 for (param_types, 0..) |*param_type, i| {
21562 const elem_val = (try params_val.maybeElemValueFull(sema, mod, i)).?;
21596 const elem_val = try params_val.elemValue(mod, i);
2156321597 const elem_struct_type = ip.loadStructType(ip.typeOf(elem_val.toIntern()));
2156421598 const param_is_generic_val = try elem_val.fieldValue(mod, elem_struct_type.nameIndex(
2156521599 ip,
......@@ -21620,7 +21654,7 @@ fn reifyEnum(
2162021654
2162121655 // This logic must stay in sync with the structure of `std.builtin.Type.Enum` - search for `fieldValue`.
2162221656
21623 const fields_len: u32 = @intCast(fields_val.sliceLen(mod));
21657 const fields_len: u32 = @intCast(fields_val.typeOf(mod).arrayLen(mod));
2162421658
2162521659 // The validation work here is non-trivial, and it's possible the type already exists.
2162621660 // So in this first pass, let's just construct a hash to optimize for this case. If the
......@@ -21634,7 +21668,7 @@ fn reifyEnum(
2163421668 std.hash.autoHash(&hasher, fields_len);
2163521669
2163621670 for (0..fields_len) |field_idx| {
21637 const field_info = (try fields_val.maybeElemValueFull(sema, mod, field_idx)).?;
21671 const field_info = try fields_val.elemValue(mod, field_idx);
2163821672
2163921673 const field_name_val = try field_info.fieldValue(mod, 0);
2164021674 const field_value_val = try sema.resolveLazyValue(try field_info.fieldValue(mod, 1));
......@@ -21668,10 +21702,14 @@ fn reifyEnum(
2166821702 return sema.fail(block, src, "Type.Enum.tag_type must be an integer type", .{});
2166921703 }
2167021704
21671 const new_decl_index = try sema.createAnonymousDeclTypeNamed(block, src, .{
21672 .ty = Type.type,
21673 .val = Value.fromInterned(wip_ty.index),
21674 }, name_strategy, "enum", inst);
21705 const new_decl_index = try sema.createAnonymousDeclTypeNamed(
21706 block,
21707 src,
21708 Value.fromInterned(wip_ty.index),
21709 name_strategy,
21710 "enum",
21711 inst,
21712 );
2167521713 mod.declPtr(new_decl_index).owns_tv = true;
2167621714 errdefer mod.abortAnonDecl(new_decl_index);
2167721715
......@@ -21679,7 +21717,7 @@ fn reifyEnum(
2167921717 wip_ty.setTagTy(ip, tag_ty.toIntern());
2168021718
2168121719 for (0..fields_len) |field_idx| {
21682 const field_info = (try fields_val.maybeElemValueFull(sema, mod, field_idx)).?;
21720 const field_info = try fields_val.elemValue(mod, field_idx);
2168321721
2168421722 const field_name_val = try field_info.fieldValue(mod, 0);
2168521723 const field_value_val = try sema.resolveLazyValue(try field_info.fieldValue(mod, 1));
......@@ -21691,7 +21729,7 @@ fn reifyEnum(
2169121729 // TODO: better source location
2169221730 return sema.fail(block, src, "field '{}' with enumeration value '{}' is too large for backing int type '{}'", .{
2169321731 field_name.fmt(ip),
21694 field_value_val.fmtValue(Type.comptime_int, mod),
21732 field_value_val.fmtValue(mod),
2169521733 tag_ty.fmt(mod),
2169621734 });
2169721735 }
......@@ -21707,7 +21745,7 @@ fn reifyEnum(
2170721745 break :msg msg;
2170821746 },
2170921747 .value => msg: {
21710 const msg = try sema.errMsg(block, src, "enum tag value {} already taken", .{field_value_val.fmtValue(Type.comptime_int, mod)});
21748 const msg = try sema.errMsg(block, src, "enum tag value {} already taken", .{field_value_val.fmtValue(mod)});
2171121749 errdefer msg.destroy(gpa);
2171221750 _ = conflict.prev_field_idx; // TODO: this note is incorrect
2171321751 try sema.errNote(block, src, msg, "other enum tag value here", .{});
......@@ -21741,7 +21779,7 @@ fn reifyUnion(
2174121779
2174221780 // This logic must stay in sync with the structure of `std.builtin.Type.Union` - search for `fieldValue`.
2174321781
21744 const fields_len: u32 = @intCast(fields_val.sliceLen(mod));
21782 const fields_len: u32 = @intCast(fields_val.typeOf(mod).arrayLen(mod));
2174521783
2174621784 // The validation work here is non-trivial, and it's possible the type already exists.
2174721785 // So in this first pass, let's just construct a hash to optimize for this case. If the
......@@ -21757,7 +21795,7 @@ fn reifyUnion(
2175721795 var any_aligns = false;
2175821796
2175921797 for (0..fields_len) |field_idx| {
21760 const field_info = (try fields_val.maybeElemValueFull(sema, mod, field_idx)).?;
21798 const field_info = try fields_val.elemValue(mod, field_idx);
2176121799
2176221800 const field_name_val = try field_info.fieldValue(mod, 0);
2176321801 const field_type_val = try field_info.fieldValue(mod, 1);
......@@ -21811,10 +21849,14 @@ fn reifyUnion(
2181121849 };
2181221850 errdefer wip_ty.cancel(ip);
2181321851
21814 const new_decl_index = try sema.createAnonymousDeclTypeNamed(block, src, .{
21815 .ty = Type.type,
21816 .val = Value.fromInterned(wip_ty.index),
21817 }, name_strategy, "union", inst);
21852 const new_decl_index = try sema.createAnonymousDeclTypeNamed(
21853 block,
21854 src,
21855 Value.fromInterned(wip_ty.index),
21856 name_strategy,
21857 "union",
21858 inst,
21859 );
2181821860 mod.declPtr(new_decl_index).owns_tv = true;
2181921861 errdefer mod.abortAnonDecl(new_decl_index);
2182021862
......@@ -21833,7 +21875,7 @@ fn reifyUnion(
2183321875 var seen_tags = try std.DynamicBitSetUnmanaged.initEmpty(sema.arena, tag_ty_fields_len);
2183421876
2183521877 for (field_types, 0..) |*field_ty, field_idx| {
21836 const field_info = (try fields_val.maybeElemValueFull(sema, mod, field_idx)).?;
21878 const field_info = try fields_val.elemValue(mod, field_idx);
2183721879
2183821880 const field_name_val = try field_info.fieldValue(mod, 0);
2183921881 const field_type_val = try field_info.fieldValue(mod, 1);
......@@ -21885,7 +21927,7 @@ fn reifyUnion(
2188521927 try field_names.ensureTotalCapacity(sema.arena, fields_len);
2188621928
2188721929 for (field_types, 0..) |*field_ty, field_idx| {
21888 const field_info = (try fields_val.maybeElemValueFull(sema, mod, field_idx)).?;
21930 const field_info = try fields_val.elemValue(mod, field_idx);
2188921931
2189021932 const field_name_val = try field_info.fieldValue(mod, 0);
2189121933 const field_type_val = try field_info.fieldValue(mod, 1);
......@@ -21979,7 +22021,7 @@ fn reifyStruct(
2197922021
2198022022 // This logic must stay in sync with the structure of `std.builtin.Type.Struct` - search for `fieldValue`.
2198122023
21982 const fields_len: u32 = @intCast(fields_val.sliceLen(mod));
22024 const fields_len: u32 = @intCast(fields_val.typeOf(mod).arrayLen(mod));
2198322025
2198422026 // The validation work here is non-trivial, and it's possible the type already exists.
2198522027 // So in this first pass, let's just construct a hash to optimize for this case. If the
......@@ -21998,7 +22040,7 @@ fn reifyStruct(
2199822040 var any_aligned_fields = false;
2199922041
2200022042 for (0..fields_len) |field_idx| {
22001 const field_info = (try fields_val.maybeElemValueFull(sema, mod, field_idx)).?;
22043 const field_info = try fields_val.elemValue(mod, field_idx);
2200222044
2200322045 const field_name_val = try field_info.fieldValue(mod, 0);
2200422046 const field_type_val = try field_info.fieldValue(mod, 1);
......@@ -22066,17 +22108,21 @@ fn reifyStruct(
2206622108 .auto => {},
2206722109 };
2206822110
22069 const new_decl_index = try sema.createAnonymousDeclTypeNamed(block, src, .{
22070 .ty = Type.type,
22071 .val = Value.fromInterned(wip_ty.index),
22072 }, name_strategy, "struct", inst);
22111 const new_decl_index = try sema.createAnonymousDeclTypeNamed(
22112 block,
22113 src,
22114 Value.fromInterned(wip_ty.index),
22115 name_strategy,
22116 "struct",
22117 inst,
22118 );
2207322119 mod.declPtr(new_decl_index).owns_tv = true;
2207422120 errdefer mod.abortAnonDecl(new_decl_index);
2207522121
2207622122 const struct_type = ip.loadStructType(wip_ty.index);
2207722123
2207822124 for (0..fields_len) |field_idx| {
22079 const field_info = (try fields_val.maybeElemValueFull(sema, mod, field_idx)).?;
22125 const field_info = try fields_val.elemValue(mod, field_idx);
2208022126
2208122127 const field_name_val = try field_info.fieldValue(mod, 0);
2208222128 const field_type_val = try field_info.fieldValue(mod, 1);
......@@ -22837,12 +22883,12 @@ fn ptrCastFull(
2283722883 return sema.failWithOwnedErrorMsg(block, msg: {
2283822884 const msg = if (src_info.sentinel == .none) blk: {
2283922885 break :blk try sema.errMsg(block, src, "destination pointer requires '{}' sentinel", .{
22840 Value.fromInterned(dest_info.sentinel).fmtValue(Type.fromInterned(dest_info.child), mod),
22886 Value.fromInterned(dest_info.sentinel).fmtValue(mod),
2284122887 });
2284222888 } else blk: {
2284322889 break :blk try sema.errMsg(block, src, "pointer sentinel '{}' cannot coerce into pointer sentinel '{}'", .{
22844 Value.fromInterned(src_info.sentinel).fmtValue(Type.fromInterned(src_info.child), mod),
22845 Value.fromInterned(dest_info.sentinel).fmtValue(Type.fromInterned(dest_info.child), mod),
22890 Value.fromInterned(src_info.sentinel).fmtValue(mod),
22891 Value.fromInterned(dest_info.sentinel).fmtValue(mod),
2284622892 });
2284722893 };
2284822894 errdefer msg.destroy(sema.gpa);
......@@ -23216,7 +23262,8 @@ fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
2321623262 const elems = try sema.arena.alloc(InternPool.Index, operand_ty.vectorLen(mod));
2321723263 for (elems, 0..) |*elem, i| {
2321823264 const elem_val = try val.elemValue(mod, i);
23219 elem.* = try (try elem_val.intTrunc(operand_scalar_ty, sema.arena, dest_info.signedness, dest_info.bits, mod)).intern(dest_scalar_ty, mod);
23265 const uncoerced_elem = try elem_val.intTrunc(operand_scalar_ty, sema.arena, dest_info.signedness, dest_info.bits, mod);
23266 elem.* = (try mod.getCoerced(uncoerced_elem, dest_scalar_ty)).toIntern();
2322023267 }
2322123268 return Air.internedToRef((try mod.intern(.{ .aggregate = .{
2322223269 .ty = dest_ty.toIntern(),
......@@ -23330,7 +23377,7 @@ fn zirByteSwap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
2333023377 const elems = try sema.arena.alloc(InternPool.Index, vec_len);
2333123378 for (elems, 0..) |*elem, i| {
2333223379 const elem_val = try val.elemValue(mod, i);
23333 elem.* = try (try elem_val.byteSwap(scalar_ty, mod, sema.arena)).intern(scalar_ty, mod);
23380 elem.* = (try elem_val.byteSwap(scalar_ty, mod, sema.arena)).toIntern();
2333423381 }
2333523382 return Air.internedToRef((try mod.intern(.{ .aggregate = .{
2333623383 .ty = operand_ty.toIntern(),
......@@ -23378,7 +23425,7 @@ fn zirBitReverse(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
2337823425 const elems = try sema.arena.alloc(InternPool.Index, vec_len);
2337923426 for (elems, 0..) |*elem, i| {
2338023427 const elem_val = try val.elemValue(mod, i);
23381 elem.* = try (try elem_val.bitReverse(scalar_ty, mod, sema.arena)).intern(scalar_ty, mod);
23428 elem.* = (try elem_val.bitReverse(scalar_ty, mod, sema.arena)).toIntern();
2338223429 }
2338323430 return Air.internedToRef((try mod.intern(.{ .aggregate = .{
2338423431 .ty = operand_ty.toIntern(),
......@@ -23896,11 +23943,9 @@ fn resolveExportOptions(
2389623943 const visibility_src = sema.maybeOptionsSrc(block, src, "visibility");
2389723944
2389823945 const name_operand = try sema.fieldVal(block, src, options, try ip.getOrPutString(gpa, "name"), name_src);
23899 const name_val = try sema.resolveConstDefinedValue(block, name_src, name_operand, .{
23946 const name = try sema.toConstString(block, name_src, name_operand, .{
2390023947 .needed_comptime_reason = "name of exported value must be comptime-known",
2390123948 });
23902 const name_ty = Type.slice_const_u8;
23903 const name = try name_val.toAllocatedBytes(name_ty, sema.arena, mod);
2390423949
2390523950 const linkage_operand = try sema.fieldVal(block, src, options, try ip.getOrPutString(gpa, "linkage"), linkage_src);
2390623951 const linkage_val = try sema.resolveConstDefinedValue(block, linkage_src, linkage_operand, .{
......@@ -23912,9 +23957,10 @@ fn resolveExportOptions(
2391223957 const section_opt_val = try sema.resolveConstDefinedValue(block, section_src, section_operand, .{
2391323958 .needed_comptime_reason = "linksection of exported value must be comptime-known",
2391423959 });
23915 const section_ty = Type.slice_const_u8;
2391623960 const section = if (section_opt_val.optionalValue(mod)) |section_val|
23917 try section_val.toAllocatedBytes(section_ty, sema.arena, mod)
23961 try sema.toConstString(block, section_src, Air.internedToRef(section_val.toIntern()), .{
23962 .needed_comptime_reason = "linksection of exported value must be comptime-known",
23963 })
2391823964 else
2391923965 null;
2392023966
......@@ -24311,7 +24357,7 @@ fn analyzeShuffle(
2431124357 }
2431224358 const int = mask_elem_val.toSignedInt(mod);
2431324359 const unsigned: u32 = @intCast(if (int >= 0) int else ~int);
24314 values[i] = try (try (if (int >= 0) a_val else b_val).elemValue(mod, unsigned)).intern(elem_ty, mod);
24360 values[i] = (try (if (int >= 0) a_val else b_val).elemValue(mod, unsigned)).toIntern();
2431524361 }
2431624362 return Air.internedToRef((try mod.intern(.{ .aggregate = .{
2431724363 .ty = res_ty.toIntern(),
......@@ -24417,7 +24463,7 @@ fn zirSelect(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) C
2441724463 for (elems, 0..) |*elem, i| {
2441824464 const pred_elem_val = try pred_val.elemValue(mod, i);
2441924465 const should_choose_a = pred_elem_val.toBool();
24420 elem.* = try (try (if (should_choose_a) a_val else b_val).elemValue(mod, i)).intern(elem_ty, mod);
24466 elem.* = (try (if (should_choose_a) a_val else b_val).elemValue(mod, i)).toIntern();
2442124467 }
2442224468
2442324469 return Air.internedToRef((try mod.intern(.{ .aggregate = .{
......@@ -25239,10 +25285,10 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
2523925285 const msg = try sema.errMsg(block, src, "non-matching @memcpy lengths", .{});
2524025286 errdefer msg.destroy(sema.gpa);
2524125287 try sema.errNote(block, dest_src, msg, "length {} here", .{
25242 dest_len_val.fmtValue(Type.usize, sema.mod),
25288 dest_len_val.fmtValue(sema.mod),
2524325289 });
2524425290 try sema.errNote(block, src_src, msg, "length {} here", .{
25245 src_len_val.fmtValue(Type.usize, sema.mod),
25291 src_len_val.fmtValue(sema.mod),
2524625292 });
2524725293 break :msg msg;
2524825294 };
......@@ -25777,7 +25823,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
2577725823 } else if (extra.data.bits.has_ret_ty_ref) blk: {
2577825824 const ret_ty_ref: Zir.Inst.Ref = @enumFromInt(sema.code.extra[extra_index]);
2577925825 extra_index += 1;
25780 const ret_ty_tv = sema.resolveInstConst(block, ret_src, ret_ty_ref, .{
25826 const ret_ty_val = sema.resolveInstConst(block, ret_src, ret_ty_ref, .{
2578125827 .needed_comptime_reason = "return type must be comptime-known",
2578225828 }) catch |err| switch (err) {
2578325829 error.GenericPoison => {
......@@ -25785,8 +25831,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
2578525831 },
2578625832 else => |e| return e,
2578725833 };
25788 const ty = ret_ty_tv.val.toType();
25789 break :blk ty;
25834 break :blk ret_ty_val.toType();
2579025835 } else Type.void;
2579125836
2579225837 const noalias_bits: u32 = if (extra.data.bits.has_any_noalias) blk: {
......@@ -26032,10 +26077,9 @@ fn resolveExternOptions(
2603226077 const thread_local_src = sema.maybeOptionsSrc(block, src, "thread_local");
2603326078
2603426079 const name_ref = try sema.fieldVal(block, src, options, try ip.getOrPutString(gpa, "name"), name_src);
26035 const name_val = try sema.resolveConstDefinedValue(block, name_src, name_ref, .{
26080 const name = try sema.toConstString(block, name_src, name_ref, .{
2603626081 .needed_comptime_reason = "name of the extern symbol must be comptime-known",
2603726082 });
26038 const name = try name_val.toAllocatedBytes(Type.slice_const_u8, sema.arena, mod);
2603926083
2604026084 const library_name_inst = try sema.fieldVal(block, src, options, try ip.getOrPutString(gpa, "library_name"), library_src);
2604126085 const library_name_val = try sema.resolveConstDefinedValue(block, library_src, library_name_inst, .{
......@@ -26054,7 +26098,9 @@ fn resolveExternOptions(
2605426098 });
2605526099
2605626100 const library_name = if (library_name_val.optionalValue(mod)) |library_name_payload| library_name: {
26057 const library_name = try library_name_payload.toAllocatedBytes(Type.slice_const_u8, sema.arena, mod);
26101 const library_name = try sema.toConstString(block, library_src, Air.internedToRef(library_name_payload.toIntern()), .{
26102 .needed_comptime_reason = "library in which extern symbol is must be comptime-known",
26103 });
2605826104 if (library_name.len == 0) {
2605926105 return sema.fail(block, library_src, "library name cannot be empty", .{});
2606026106 }
......@@ -26120,9 +26166,10 @@ fn zirBuiltinExtern(
2612026166 const new_decl_index = try mod.allocateNewDecl(sema.owner_decl.src_namespace, sema.owner_decl.src_node);
2612126167 errdefer mod.destroyDecl(new_decl_index);
2612226168 const new_decl = mod.declPtr(new_decl_index);
26123 try mod.initNewAnonDecl(new_decl_index, sema.owner_decl.src_line, .{
26124 .ty = Type.fromInterned(ptr_info.child),
26125 .val = Value.fromInterned(
26169 try mod.initNewAnonDecl(
26170 new_decl_index,
26171 sema.owner_decl.src_line,
26172 Value.fromInterned(
2612626173 if (Type.fromInterned(ptr_info.child).zigTypeTag(mod) == .Fn)
2612726174 try ip.getExternFunc(sema.gpa, .{
2612826175 .ty = ptr_info.child,
......@@ -26141,7 +26188,8 @@ fn zirBuiltinExtern(
2614126188 .is_weak_linkage = options.linkage == .weak,
2614226189 } }),
2614326190 ),
26144 }, options.name);
26191 options.name,
26192 );
2614526193 new_decl.owns_tv = true;
2614626194 // Note that this will queue the anon decl for codegen, so that the backend can
2614726195 // correctly handle the extern, including duplicate detection.
......@@ -26641,13 +26689,12 @@ fn prepareSimplePanic(sema: *Sema, block: *Block) !void {
2664126689 // decl_index may be an alias; we must find the decl that actually
2664226690 // owns the function.
2664326691 try sema.ensureDeclAnalyzed(decl_index);
26644 const tv = try mod.declPtr(decl_index).typedValue();
26692 const fn_val = try mod.declPtr(decl_index).valueOrFail();
2664526693 try sema.declareDependency(.{ .decl_val = decl_index });
26646 assert(tv.ty.zigTypeTag(mod) == .Fn);
26647 assert(try sema.fnHasRuntimeBits(tv.ty));
26648 const func_index = tv.val.toIntern();
26649 try mod.ensureFuncBodyAnalysisQueued(func_index);
26650 mod.panic_func_index = func_index;
26694 assert(fn_val.typeOf(mod).zigTypeTag(mod) == .Fn);
26695 assert(try sema.fnHasRuntimeBits(fn_val.typeOf(mod)));
26696 try mod.ensureFuncBodyAnalysisQueued(fn_val.toIntern());
26697 mod.panic_func_index = fn_val.toIntern();
2665126698 }
2665226699
2665326700 if (mod.null_stack_trace == .none) {
......@@ -27789,7 +27836,7 @@ fn structFieldPtrByIndex(
2778927836 const val = try mod.intern(.{ .ptr = .{
2779027837 .ty = ptr_field_ty.toIntern(),
2779127838 .addr = .{ .field = .{
27792 .base = try struct_ptr_val.intern(struct_ptr_ty, mod),
27839 .base = struct_ptr_val.toIntern(),
2779327840 .index = field_index,
2779427841 } },
2779527842 } });
......@@ -28568,7 +28615,7 @@ fn elemValSlice(
2856828615
2856928616 if (maybe_slice_val) |slice_val| {
2857028617 runtime_src = elem_index_src;
28571 const slice_len = slice_val.sliceLen(mod);
28618 const slice_len = try slice_val.sliceLen(sema);
2857228619 const slice_len_s = slice_len + @intFromBool(slice_sent);
2857328620 if (slice_len_s == 0) {
2857428621 return sema.fail(block, slice_src, "indexing into empty slice is not allowed", .{});
......@@ -28593,7 +28640,7 @@ fn elemValSlice(
2859328640 try sema.requireRuntimeBlock(block, src, runtime_src);
2859428641 if (oob_safety and block.wantSafety()) {
2859528642 const len_inst = if (maybe_slice_val) |slice_val|
28596 try mod.intRef(Type.usize, slice_val.sliceLen(mod))
28643 try mod.intRef(Type.usize, try slice_val.sliceLen(sema))
2859728644 else
2859828645 try block.addTyOp(.slice_len, Type.usize, slice);
2859928646 const cmp_op: Air.Inst.Tag = if (slice_sent) .cmp_lte else .cmp_lt;
......@@ -28630,7 +28677,7 @@ fn elemPtrSlice(
2863028677 if (slice_val.isUndef(mod)) {
2863128678 return mod.undefRef(elem_ptr_ty);
2863228679 }
28633 const slice_len = slice_val.sliceLen(mod);
28680 const slice_len = try slice_val.sliceLen(sema);
2863428681 const slice_len_s = slice_len + @intFromBool(slice_sent);
2863528682 if (slice_len_s == 0) {
2863628683 return sema.fail(block, slice_src, "indexing into empty slice is not allowed", .{});
......@@ -28653,7 +28700,7 @@ fn elemPtrSlice(
2865328700 const len_inst = len: {
2865428701 if (maybe_undef_slice_val) |slice_val|
2865528702 if (!slice_val.isUndef(mod))
28656 break :len try mod.intRef(Type.usize, slice_val.sliceLen(mod));
28703 break :len try mod.intRef(Type.usize, try slice_val.sliceLen(sema));
2865728704 break :len try block.addTyOp(.slice_len, Type.usize, slice);
2865828705 };
2865928706 const cmp_op: Air.Inst.Tag = if (slice_sent) .cmp_lte else .cmp_lt;
......@@ -29115,7 +29162,7 @@ fn coerceExtra(
2911529162 // comptime-known integer to other number
2911629163 if (!(try sema.intFitsInType(val, dest_ty, null))) {
2911729164 if (!opts.report_err) return error.NotCoercible;
29118 return sema.fail(block, inst_src, "type '{}' cannot represent integer value '{}'", .{ dest_ty.fmt(mod), val.fmtValue(inst_ty, mod) });
29165 return sema.fail(block, inst_src, "type '{}' cannot represent integer value '{}'", .{ dest_ty.fmt(mod), val.fmtValue(mod) });
2911929166 }
2912029167 return switch (mod.intern_pool.indexToKey(val.toIntern())) {
2912129168 .undef => try mod.undefRef(dest_ty),
......@@ -29160,7 +29207,7 @@ fn coerceExtra(
2916029207 block,
2916129208 inst_src,
2916229209 "type '{}' cannot represent float value '{}'",
29163 .{ dest_ty.fmt(mod), val.fmtValue(inst_ty, mod) },
29210 .{ dest_ty.fmt(mod), val.fmtValue(mod) },
2916429211 );
2916529212 }
2916629213 return Air.internedToRef(result_val.toIntern());
......@@ -29531,11 +29578,11 @@ const InMemoryCoercionResult = union(enum) {
2953129578 .array_sentinel => |sentinel| {
2953229579 if (sentinel.actual.toIntern() != .unreachable_value) {
2953329580 try sema.errNote(block, src, msg, "array sentinel '{}' cannot cast into array sentinel '{}'", .{
29534 sentinel.actual.fmtValue(sentinel.ty, mod), sentinel.wanted.fmtValue(sentinel.ty, mod),
29581 sentinel.actual.fmtValue(mod), sentinel.wanted.fmtValue(mod),
2953529582 });
2953629583 } else {
2953729584 try sema.errNote(block, src, msg, "destination array requires '{}' sentinel", .{
29538 sentinel.wanted.fmtValue(sentinel.ty, mod),
29585 sentinel.wanted.fmtValue(mod),
2953929586 });
2954029587 }
2954129588 break;
......@@ -29657,11 +29704,11 @@ const InMemoryCoercionResult = union(enum) {
2965729704 .ptr_sentinel => |sentinel| {
2965829705 if (sentinel.actual.toIntern() != .unreachable_value) {
2965929706 try sema.errNote(block, src, msg, "pointer sentinel '{}' cannot cast into pointer sentinel '{}'", .{
29660 sentinel.actual.fmtValue(sentinel.ty, mod), sentinel.wanted.fmtValue(sentinel.ty, mod),
29707 sentinel.actual.fmtValue(mod), sentinel.wanted.fmtValue(mod),
2966129708 });
2966229709 } else {
2966329710 try sema.errNote(block, src, msg, "destination pointer requires '{}' sentinel", .{
29664 sentinel.wanted.fmtValue(sentinel.ty, mod),
29711 sentinel.wanted.fmtValue(mod),
2966529712 });
2966629713 }
2966729714 break;
......@@ -30654,21 +30701,22 @@ fn storePtrVal(
3065430701 .opv => {},
3065530702 .direct => |val_ptr| {
3065630703 if (mut_kit.root == .comptime_field) {
30657 val_ptr.* = Value.fromInterned((try val_ptr.intern(operand_ty, mod)));
30658 if (!operand_val.eql(val_ptr.*, operand_ty, mod)) {
30704 val_ptr.* = .{ .interned = try val_ptr.intern(mod, sema.arena) };
30705 if (operand_val.toIntern() != val_ptr.interned) {
3065930706 // TODO use failWithInvalidComptimeFieldStore
3066030707 return sema.fail(block, src, "value stored in comptime field does not match the default value of the field", .{});
3066130708 }
3066230709 return;
3066330710 }
30664 val_ptr.* = Value.fromInterned((try operand_val.intern(operand_ty, mod)));
30711 val_ptr.* = .{ .interned = operand_val.toIntern() };
3066530712 },
3066630713 .reinterpret => |reinterpret| {
3066730714 try sema.resolveTypeLayout(mut_kit.ty);
3066830715 const abi_size = try sema.usizeCast(block, src, mut_kit.ty.abiSize(mod));
3066930716 const buffer = try sema.gpa.alloc(u8, abi_size);
3067030717 defer sema.gpa.free(buffer);
30671 reinterpret.val_ptr.*.writeToMemory(mut_kit.ty, mod, buffer) catch |err| switch (err) {
30718 const interned_old = Value.fromInterned(try reinterpret.val_ptr.intern(mod, sema.arena));
30719 interned_old.writeToMemory(mut_kit.ty, mod, buffer) catch |err| switch (err) {
3067230720 error.OutOfMemory => return error.OutOfMemory,
3067330721 error.ReinterpretDeclRef => unreachable,
3067430722 error.IllDefinedMemoryLayout => unreachable, // Sema was supposed to emit a compile error already
......@@ -30692,7 +30740,7 @@ fn storePtrVal(
3069230740 error.IllDefinedMemoryLayout => unreachable,
3069330741 error.Unimplemented => return sema.fail(block, src, "TODO: implement readFromMemory for type '{}'", .{mut_kit.ty.fmt(mod)}),
3069430742 };
30695 reinterpret.val_ptr.* = Value.fromInterned((try val.intern(mut_kit.ty, mod)));
30743 reinterpret.val_ptr.* = .{ .interned = val.toIntern() };
3069630744 },
3069730745 .bad_decl_ty, .bad_ptr_ty => {
3069830746 // TODO show the decl declaration site in a note and explain whether the decl
......@@ -30717,11 +30765,11 @@ const ComptimePtrMutationKit = struct {
3071730765 opv,
3071830766 /// The pointer type matches the actual comptime Value so a direct
3071930767 /// modification is possible.
30720 direct: *Value,
30768 direct: *MutableValue,
3072130769 /// The largest parent Value containing pointee and having a well-defined memory layout.
3072230770 /// This is used for bitcasting, if direct dereferencing failed.
3072330771 reinterpret: struct {
30724 val_ptr: *Value,
30772 val_ptr: *MutableValue,
3072530773 byte_offset: usize,
3072630774 /// If set, write the operand to packed memory
3072730775 write_packed: bool = false,
......@@ -30753,15 +30801,15 @@ fn beginComptimePtrMutation(
3075330801 .decl, .anon_decl, .int => unreachable, // isComptimeMutablePtr has been checked already
3075430802 .comptime_alloc => |alloc_index| {
3075530803 const alloc = sema.getComptimeAlloc(alloc_index);
30756 return sema.beginComptimePtrMutationInner(block, src, alloc.ty, &alloc.val, ptr_elem_ty, .{ .alloc = alloc_index });
30804 return sema.beginComptimePtrMutationInner(block, src, alloc.val.typeOf(mod), &alloc.val, ptr_elem_ty, .{ .alloc = alloc_index });
3075730805 },
3075830806 .comptime_field => |comptime_field| {
30759 const duped = try sema.arena.create(Value);
30760 duped.* = Value.fromInterned(comptime_field);
30807 const duped = try sema.arena.create(MutableValue);
30808 duped.* = .{ .interned = comptime_field };
3076130809 return sema.beginComptimePtrMutationInner(
3076230810 block,
3076330811 src,
30764 Type.fromInterned(mod.intern_pool.typeOf(comptime_field)),
30812 duped.typeOf(mod),
3076530813 duped,
3076630814 ptr_elem_ty,
3076730815 .comptime_field,
......@@ -30774,36 +30822,28 @@ fn beginComptimePtrMutation(
3077430822 .opv => unreachable,
3077530823 .direct => |val_ptr| {
3077630824 const payload_ty = parent.ty.errorUnionPayload(mod);
30777 if (val_ptr.ip_index == .none and val_ptr.tag() == .eu_payload) {
30778 return ComptimePtrMutationKit{
30779 .root = parent.root,
30780 .pointee = .{ .direct = &val_ptr.castTag(.eu_payload).?.data },
30781 .ty = payload_ty,
30782 };
30783 } else {
30825 try val_ptr.unintern(mod, sema.arena, false, false);
30826 if (val_ptr.* == .interned) {
3078430827 // An error union has been initialized to undefined at comptime and now we
3078530828 // are for the first time setting the payload. We must change the
30786 // representation of the error union from `undef` to `opt_payload`.
30787
30788 const payload = try sema.arena.create(Value.Payload.SubValue);
30789 payload.* = .{
30790 .base = .{ .tag = .eu_payload },
30791 .data = Value.fromInterned((try mod.intern(.{ .undef = payload_ty.toIntern() }))),
30792 };
30793
30794 val_ptr.* = Value.initPayload(&payload.base);
30795
30796 return ComptimePtrMutationKit{
30797 .root = parent.root,
30798 .pointee = .{ .direct = &payload.data },
30799 .ty = payload_ty,
30800 };
30829 // representation of the error union to `eu_payload`.
30830 const child = try sema.arena.create(MutableValue);
30831 child.* = .{ .interned = try mod.intern(.{ .undef = payload_ty.toIntern() }) };
30832 val_ptr.* = .{ .eu_payload = .{
30833 .ty = parent.ty.toIntern(),
30834 .child = child,
30835 } };
3080130836 }
30837 return .{
30838 .root = parent.root,
30839 .pointee = .{ .direct = val_ptr.eu_payload.child },
30840 .ty = payload_ty,
30841 };
3080230842 },
3080330843 .bad_decl_ty, .bad_ptr_ty => return parent,
3080430844 // Even though the parent value type has well-defined memory layout, our
3080530845 // pointer type does not.
30806 .reinterpret => return ComptimePtrMutationKit{
30846 .reinterpret => return .{
3080730847 .root = parent.root,
3080830848 .pointee = .bad_ptr_ty,
3080930849 .ty = eu_ty,
......@@ -30817,46 +30857,28 @@ fn beginComptimePtrMutation(
3081730857 .opv => unreachable,
3081830858 .direct => |val_ptr| {
3081930859 const payload_ty = parent.ty.optionalChild(mod);
30820 switch (val_ptr.ip_index) {
30821 .none => return ComptimePtrMutationKit{
30822 .root = parent.root,
30823 .pointee = .{ .direct = &val_ptr.castTag(.opt_payload).?.data },
30824 .ty = payload_ty,
30825 },
30826 else => {
30827 const payload_val = switch (mod.intern_pool.indexToKey(val_ptr.ip_index)) {
30828 .undef => try mod.intern(.{ .undef = payload_ty.toIntern() }),
30829 .opt => |opt| switch (opt.val) {
30830 .none => try mod.intern(.{ .undef = payload_ty.toIntern() }),
30831 else => |payload| payload,
30832 },
30833 else => unreachable,
30834 };
30835
30836 // An optional has been initialized to undefined at comptime and now we
30837 // are for the first time setting the payload. We must change the
30838 // representation of the optional from `undef` to `opt_payload`.
30839
30840 const payload = try sema.arena.create(Value.Payload.SubValue);
30841 payload.* = .{
30842 .base = .{ .tag = .opt_payload },
30843 .data = Value.fromInterned(payload_val),
30844 };
30845
30846 val_ptr.* = Value.initPayload(&payload.base);
30847
30848 return ComptimePtrMutationKit{
30849 .root = parent.root,
30850 .pointee = .{ .direct = &payload.data },
30851 .ty = payload_ty,
30852 };
30853 },
30860 try val_ptr.unintern(mod, sema.arena, false, false);
30861 if (val_ptr.* == .interned) {
30862 // An optional has been initialized to undefined at comptime and now we
30863 // are for the first time setting the payload. We must change the
30864 // representation of the optional to `opt_payload`.
30865 const child = try sema.arena.create(MutableValue);
30866 child.* = .{ .interned = try mod.intern(.{ .undef = payload_ty.toIntern() }) };
30867 val_ptr.* = .{ .opt_payload = .{
30868 .ty = parent.ty.toIntern(),
30869 .child = child,
30870 } };
3085430871 }
30872 return .{
30873 .root = parent.root,
30874 .pointee = .{ .direct = val_ptr.opt_payload.child },
30875 .ty = payload_ty,
30876 };
3085530877 },
3085630878 .bad_decl_ty, .bad_ptr_ty => return parent,
3085730879 // Even though the parent value type has well-defined memory layout, our
3085830880 // pointer type does not.
30859 .reinterpret => return ComptimePtrMutationKit{
30881 .reinterpret => return .{
3086030882 .root = parent.root,
3086130883 .pointee = .bad_ptr_ty,
3086230884 .ty = opt_ty,
......@@ -30915,106 +30937,28 @@ fn beginComptimePtrMutation(
3091530937 };
3091630938 }
3091730939
30918 switch (val_ptr.ip_index) {
30919 .none => switch (val_ptr.tag()) {
30920 .bytes => {
30921 // An array is memory-optimized to store a slice of bytes, but we are about
30922 // to modify an individual field and the representation has to change.
30923 // If we wanted to avoid this, there would need to be special detection
30924 // elsewhere to identify when writing a value to an array element that is stored
30925 // using the `bytes` tag, and handle it without making a call to this function.
30926 const arena = sema.arena;
30927
30928 const bytes = val_ptr.castTag(.bytes).?.data;
30929 const dest_len = parent.ty.arrayLenIncludingSentinel(mod);
30930 // bytes.len may be one greater than dest_len because of the case when
30931 // assigning `[N:S]T` to `[N]T`. This is allowed; the sentinel is omitted.
30932 assert(bytes.len >= dest_len);
30933 const elems = try arena.alloc(Value, @intCast(dest_len));
30934 for (elems, 0..) |*elem, i| {
30935 elem.* = try mod.intValue(elem_ty, bytes[i]);
30936 }
30937
30938 val_ptr.* = try Value.Tag.aggregate.create(arena, elems);
30939
30940 return beginComptimePtrMutationInner(
30941 sema,
30942 block,
30943 src,
30944 elem_ty,
30945 &elems[@intCast(elem_ptr.index)],
30946 ptr_elem_ty,
30947 parent.root,
30948 );
30949 },
30950 .repeated => {
30951 // An array is memory-optimized to store only a single element value, and
30952 // that value is understood to be the same for the entire length of the array.
30953 // However, now we want to modify an individual field and so the
30954 // representation has to change. If we wanted to avoid this, there would
30955 // need to be special detection elsewhere to identify when writing a value to an
30956 // array element that is stored using the `repeated` tag, and handle it
30957 // without making a call to this function.
30958 const arena = sema.arena;
30959
30960 const repeated_val = try val_ptr.castTag(.repeated).?.data.intern(parent.ty.childType(mod), mod);
30961 const array_len_including_sentinel =
30962 try sema.usizeCast(block, src, parent.ty.arrayLenIncludingSentinel(mod));
30963 const elems = try arena.alloc(Value, array_len_including_sentinel);
30964 @memset(elems, Value.fromInterned(repeated_val));
30965
30966 val_ptr.* = try Value.Tag.aggregate.create(arena, elems);
30967
30968 return beginComptimePtrMutationInner(
30969 sema,
30970 block,
30971 src,
30972 elem_ty,
30973 &elems[@intCast(elem_ptr.index)],
30974 ptr_elem_ty,
30975 parent.root,
30976 );
30977 },
30978
30979 .aggregate => return beginComptimePtrMutationInner(
30980 sema,
30981 block,
30982 src,
30983 elem_ty,
30984 &val_ptr.castTag(.aggregate).?.data[@intCast(elem_ptr.index)],
30985 ptr_elem_ty,
30986 parent.root,
30987 ),
30940 try val_ptr.unintern(mod, sema.arena, false, false);
30941
30942 const aggregate = switch (val_ptr.*) {
30943 .interned,
30944 .bytes,
30945 .repeated,
30946 .eu_payload,
30947 .opt_payload,
30948 .slice,
30949 .un,
30950 => unreachable,
30951 .aggregate => |*a| a,
30952 };
3098830953
30989 else => unreachable,
30990 },
30991 else => switch (mod.intern_pool.indexToKey(val_ptr.toIntern())) {
30992 .undef => {
30993 // An array has been initialized to undefined at comptime and now we
30994 // are for the first time setting an element. We must change the representation
30995 // of the array from `undef` to `array`.
30996 const arena = sema.arena;
30997
30998 const array_len_including_sentinel =
30999 try sema.usizeCast(block, src, parent.ty.arrayLenIncludingSentinel(mod));
31000 const elems = try arena.alloc(Value, array_len_including_sentinel);
31001 @memset(elems, Value.fromInterned((try mod.intern(.{ .undef = elem_ty.toIntern() }))));
31002
31003 val_ptr.* = try Value.Tag.aggregate.create(arena, elems);
31004
31005 return beginComptimePtrMutationInner(
31006 sema,
31007 block,
31008 src,
31009 elem_ty,
31010 &elems[@intCast(elem_ptr.index)],
31011 ptr_elem_ty,
31012 parent.root,
31013 );
31014 },
31015 else => unreachable,
31016 },
31017 }
30954 return sema.beginComptimePtrMutationInner(
30955 block,
30956 src,
30957 elem_ty,
30958 &aggregate.elems[@intCast(elem_ptr.index)],
30959 ptr_elem_ty,
30960 parent.root,
30961 );
3101830962 },
3101930963 else => {
3102030964 if (elem_ptr.index != 0) {
......@@ -31038,7 +30982,7 @@ fn beginComptimePtrMutation(
3103830982 if (!base_elem_ty.hasWellDefinedLayout(mod)) {
3103930983 // Even though the parent value type has well-defined memory layout, our
3104030984 // pointer type does not.
31041 return ComptimePtrMutationKit{
30985 return .{
3104230986 .root = parent.root,
3104330987 .pointee = .bad_ptr_ty,
3104430988 .ty = base_elem_ty,
......@@ -31048,7 +30992,7 @@ fn beginComptimePtrMutation(
3104830992 const elem_abi_size_u64 = try sema.typeAbiSize(base_elem_ty);
3104930993 const elem_abi_size = try sema.usizeCast(block, src, elem_abi_size_u64);
3105030994 const elem_idx = try sema.usizeCast(block, src, elem_ptr.index);
31051 return ComptimePtrMutationKit{
30995 return .{
3105230996 .root = parent.root,
3105330997 .pointee = .{ .reinterpret = .{
3105430998 .val_ptr = reinterpret.val_ptr,
......@@ -31067,56 +31011,68 @@ fn beginComptimePtrMutation(
3106731011 var parent = try sema.beginComptimePtrMutation(block, src, Value.fromInterned(field_ptr.base), base_child_ty);
3106831012 switch (parent.pointee) {
3106931013 .opv => unreachable,
31070 .direct => |val_ptr| switch (val_ptr.ip_index) {
31071 .empty_struct => {
31072 const duped = try sema.arena.create(Value);
31073 duped.* = val_ptr.*;
31074 return beginComptimePtrMutationInner(
31075 sema,
31076 block,
31077 src,
31078 parent.ty.structFieldType(field_index, mod),
31079 duped,
31080 ptr_elem_ty,
31081 parent.root,
31082 );
31083 },
31084 .none => switch (val_ptr.tag()) {
31085 .aggregate => return beginComptimePtrMutationInner(
31086 sema,
31014 .direct => |val_ptr| {
31015 try val_ptr.unintern(mod, sema.arena, false, false);
31016 switch (val_ptr.*) {
31017 .interned,
31018 .eu_payload,
31019 .opt_payload,
31020 .repeated,
31021 .bytes,
31022 => unreachable,
31023 .aggregate => |*a| return sema.beginComptimePtrMutationInner(
3108731024 block,
3108831025 src,
3108931026 parent.ty.structFieldType(field_index, mod),
31090 &val_ptr.castTag(.aggregate).?.data[field_index],
31027 &a.elems[field_index],
3109131028 ptr_elem_ty,
3109231029 parent.root,
3109331030 ),
31094 .repeated => {
31095 const arena = sema.arena;
31096
31097 const elems = try arena.alloc(Value, parent.ty.structFieldCount(mod));
31098 @memset(elems, val_ptr.castTag(.repeated).?.data);
31099 val_ptr.* = try Value.Tag.aggregate.create(arena, elems);
31100
31101 return beginComptimePtrMutationInner(
31102 sema,
31031 .slice => |*s| switch (field_index) {
31032 Value.slice_ptr_index => return sema.beginComptimePtrMutationInner(
3110331033 block,
3110431034 src,
31105 parent.ty.structFieldType(field_index, mod),
31106 &elems[field_index],
31035 parent.ty.slicePtrFieldType(mod),
31036 s.ptr,
3110731037 ptr_elem_ty,
3110831038 parent.root,
31109 );
31039 ),
31040 Value.slice_len_index => return sema.beginComptimePtrMutationInner(
31041 block,
31042 src,
31043 Type.usize,
31044 s.len,
31045 ptr_elem_ty,
31046 parent.root,
31047 ),
31048 else => unreachable,
3111031049 },
31111 .@"union" => {
31112 const payload = &val_ptr.castTag(.@"union").?.data;
31050 .un => |*un| {
3111331051 const layout = base_child_ty.containerLayout(mod);
3111431052
3111531053 const tag_type = base_child_ty.unionTagTypeHypothetical(mod);
3111631054 const hypothetical_tag = try mod.enumValueFieldIndex(tag_type, field_index);
31117 if (layout == .auto or (payload.tag != null and hypothetical_tag.eql(payload.tag.?, tag_type, mod))) {
31055 if (un.tag == .none and un.payload.* == .interned and un.payload.interned == .undef) {
31056 // A union has been initialized to undefined at comptime and now we
31057 // are for the first time setting the payload. We must change the
31058 // tag implicitly.
31059 const payload_ty = parent.ty.structFieldType(field_index, mod);
31060 un.tag = hypothetical_tag.toIntern();
31061 un.payload.* = .{ .interned = try mod.intern(.{ .undef = payload_ty.toIntern() }) };
31062 return beginComptimePtrMutationInner(
31063 sema,
31064 block,
31065 src,
31066 payload_ty,
31067 un.payload,
31068 ptr_elem_ty,
31069 parent.root,
31070 );
31071 }
31072
31073 if (layout == .auto or hypothetical_tag.toIntern() == un.tag) {
3111831074 // We need to set the active field of the union.
31119 payload.tag = hypothetical_tag;
31075 un.tag = hypothetical_tag.toIntern();
3112031076
3112131077 const field_ty = parent.ty.structFieldType(field_index, mod);
3112231078 return beginComptimePtrMutationInner(
......@@ -31124,7 +31080,7 @@ fn beginComptimePtrMutation(
3112431080 block,
3112531081 src,
3112631082 field_ty,
31127 &payload.val,
31083 un.payload,
3112831084 ptr_elem_ty,
3112931085 parent.root,
3113031086 );
......@@ -31132,11 +31088,10 @@ fn beginComptimePtrMutation(
3113231088 // Writing to a different field (a different or unknown tag is active) requires reinterpreting
3113331089 // memory of the entire union, which requires knowing its abiSize.
3113431090 try sema.resolveTypeLayout(parent.ty);
31135
3113631091 // This union value no longer has a well-defined tag type.
3113731092 // The reinterpretation will read it back out as .none.
31138 payload.val = try payload.val.unintern(sema.arena, mod);
31139 return ComptimePtrMutationKit{
31093 try un.payload.unintern(mod, sema.arena, false, false);
31094 return .{
3114031095 .root = parent.root,
3114131096 .pointee = .{ .reinterpret = .{
3114231097 .val_ptr = val_ptr,
......@@ -31147,119 +31102,12 @@ fn beginComptimePtrMutation(
3114731102 };
3114831103 }
3114931104 },
31150 .slice => switch (field_index) {
31151 Value.slice_ptr_index => return beginComptimePtrMutationInner(
31152 sema,
31153 block,
31154 src,
31155 parent.ty.slicePtrFieldType(mod),
31156 &val_ptr.castTag(.slice).?.data.ptr,
31157 ptr_elem_ty,
31158 parent.root,
31159 ),
31160
31161 Value.slice_len_index => return beginComptimePtrMutationInner(
31162 sema,
31163 block,
31164 src,
31165 Type.usize,
31166 &val_ptr.castTag(.slice).?.data.len,
31167 ptr_elem_ty,
31168 parent.root,
31169 ),
31170
31171 else => unreachable,
31172 },
31173 else => unreachable,
31174 },
31175 else => switch (mod.intern_pool.indexToKey(val_ptr.toIntern())) {
31176 .undef => {
31177 // A struct or union has been initialized to undefined at comptime and now we
31178 // are for the first time setting a field. We must change the representation
31179 // of the struct/union from `undef` to `struct`/`union`.
31180 const arena = sema.arena;
31181
31182 switch (parent.ty.zigTypeTag(mod)) {
31183 .Struct => {
31184 const fields = try arena.alloc(Value, parent.ty.structFieldCount(mod));
31185 for (fields, 0..) |*field, i| field.* = Value.fromInterned((try mod.intern(.{
31186 .undef = parent.ty.structFieldType(i, mod).toIntern(),
31187 })));
31188
31189 val_ptr.* = try Value.Tag.aggregate.create(arena, fields);
31190
31191 return beginComptimePtrMutationInner(
31192 sema,
31193 block,
31194 src,
31195 parent.ty.structFieldType(field_index, mod),
31196 &fields[field_index],
31197 ptr_elem_ty,
31198 parent.root,
31199 );
31200 },
31201 .Union => {
31202 const payload = try arena.create(Value.Payload.Union);
31203 const tag_ty = parent.ty.unionTagTypeHypothetical(mod);
31204 const payload_ty = parent.ty.structFieldType(field_index, mod);
31205 payload.* = .{ .data = .{
31206 .tag = try mod.enumValueFieldIndex(tag_ty, field_index),
31207 .val = Value.fromInterned((try mod.intern(.{ .undef = payload_ty.toIntern() }))),
31208 } };
31209
31210 val_ptr.* = Value.initPayload(&payload.base);
31211
31212 return beginComptimePtrMutationInner(
31213 sema,
31214 block,
31215 src,
31216 payload_ty,
31217 &payload.data.val,
31218 ptr_elem_ty,
31219 parent.root,
31220 );
31221 },
31222 .Pointer => {
31223 assert(parent.ty.isSlice(mod));
31224 const ptr_ty = parent.ty.slicePtrFieldType(mod);
31225 val_ptr.* = try Value.Tag.slice.create(arena, .{
31226 .ptr = Value.fromInterned((try mod.intern(.{ .undef = ptr_ty.toIntern() }))),
31227 .len = Value.fromInterned((try mod.intern(.{ .undef = .usize_type }))),
31228 });
31229
31230 switch (field_index) {
31231 Value.slice_ptr_index => return beginComptimePtrMutationInner(
31232 sema,
31233 block,
31234 src,
31235 ptr_ty,
31236 &val_ptr.castTag(.slice).?.data.ptr,
31237 ptr_elem_ty,
31238 parent.root,
31239 ),
31240 Value.slice_len_index => return beginComptimePtrMutationInner(
31241 sema,
31242 block,
31243 src,
31244 Type.usize,
31245 &val_ptr.castTag(.slice).?.data.len,
31246 ptr_elem_ty,
31247 parent.root,
31248 ),
31249
31250 else => unreachable,
31251 }
31252 },
31253 else => unreachable,
31254 }
31255 },
31256 else => unreachable,
31257 },
31105 }
3125831106 },
3125931107 .reinterpret => |reinterpret| {
3126031108 const field_offset_u64 = base_child_ty.structFieldOffset(field_index, mod);
3126131109 const field_offset = try sema.usizeCast(block, src, field_offset_u64);
31262 return ComptimePtrMutationKit{
31110 return .{
3126331111 .root = parent.root,
3126431112 .pointee = .{ .reinterpret = .{
3126531113 .val_ptr = reinterpret.val_ptr,
......@@ -31279,7 +31127,7 @@ fn beginComptimePtrMutationInner(
3127931127 block: *Block,
3128031128 src: LazySrcLoc,
3128131129 decl_ty: Type,
31282 decl_val: *Value,
31130 decl_val: *MutableValue,
3128331131 ptr_elem_ty: Type,
3128431132 root: ComptimePtrMutationKit.Root,
3128531133) CompileError!ComptimePtrMutationKit {
......@@ -31287,7 +31135,13 @@ fn beginComptimePtrMutationInner(
3128731135 const target = mod.getTarget();
3128831136 const coerce_ok = (try sema.coerceInMemoryAllowed(block, ptr_elem_ty, decl_ty, true, target, src, src)) == .ok;
3128931137
31290 decl_val.* = try decl_val.unintern(sema.arena, mod);
31138 const old_decl_val = decl_val.*;
31139 try decl_val.unintern(mod, sema.arena, false, false);
31140 if (decl_val.* == .un and decl_val.un.tag == .none and decl_val.un.payload.* == .interned and decl_val.un.payload.interned == .undef) {
31141 // HACKHACK: undefined union - re-intern it for now
31142 // `unintern` probably should just leave these as is, but I'm leaving it until I rewrite comptime pointer access.
31143 decl_val.* = old_decl_val;
31144 }
3129131145
3129231146 if (coerce_ok) {
3129331147 return ComptimePtrMutationKit{
......@@ -31333,21 +31187,16 @@ fn beginComptimePtrMutationInner(
3133331187 };
3133431188}
3133531189
31336const TypedValueAndOffset = struct {
31337 tv: TypedValue,
31338 byte_offset: usize,
31339};
31340
3134131190const ComptimePtrLoadKit = struct {
3134231191 /// The Value and Type corresponding to the pointee of the provided pointer.
3134331192 /// If a direct dereference is not possible, this is null.
31344 pointee: ?TypedValue,
31193 pointee: ?MutableValue,
3134531194 /// The largest parent Value containing `pointee` and having a well-defined memory layout.
3134631195 /// This is used for bitcasting, if direct dereferencing failed (i.e. `pointee` is null).
31347 parent: ?TypedValueAndOffset,
31348 /// Whether the `pointee` could be mutated by further
31349 /// semantic analysis and a copy must be performed.
31350 is_mutable: bool,
31196 parent: ?struct {
31197 val: MutableValue,
31198 byte_offset: usize,
31199 },
3135131200 /// If the root decl could not be used as `parent`, this is the type that
3135231201 /// caused that by not having a well-defined layout
3135331202 ty_without_well_defined_layout: ?Type,
......@@ -31374,53 +31223,41 @@ fn beginComptimePtrLoad(
3137431223 .ptr => |ptr| switch (ptr.addr) {
3137531224 .decl => |decl_index| blk: {
3137631225 const decl = mod.declPtr(decl_index);
31377 const decl_tv = try decl.typedValue();
3137831226 try sema.declareDependency(.{ .decl_val = decl_index });
3137931227 if (decl.val.getVariable(mod) != null) return error.RuntimeLoad;
31380
31381 const layout_defined = decl.ty.hasWellDefinedLayout(mod);
31228 const decl_val: MutableValue = .{ .interned = decl.val.toIntern() };
31229 const layout_defined = decl.typeOf(mod).hasWellDefinedLayout(mod);
3138231230 break :blk ComptimePtrLoadKit{
31383 .parent = if (layout_defined) .{ .tv = decl_tv, .byte_offset = 0 } else null,
31384 .pointee = decl_tv,
31385 .is_mutable = false,
31386 .ty_without_well_defined_layout = if (!layout_defined) decl.ty else null,
31231 .parent = if (layout_defined) .{ .val = decl_val, .byte_offset = 0 } else null,
31232 .pointee = decl_val,
31233 .ty_without_well_defined_layout = if (!layout_defined) decl.typeOf(mod) else null,
3138731234 };
3138831235 },
3138931236 .comptime_alloc => |alloc_index| kit: {
3139031237 const alloc = sema.getComptimeAlloc(alloc_index);
31391 const alloc_tv: TypedValue = .{
31392 .ty = alloc.ty,
31393 .val = alloc.val,
31394 };
31395 const layout_defined = alloc.ty.hasWellDefinedLayout(mod);
31238 const alloc_ty = alloc.val.typeOf(mod);
31239 const layout_defined = alloc_ty.hasWellDefinedLayout(mod);
3139631240 break :kit .{
31397 .parent = if (layout_defined) .{ .tv = alloc_tv, .byte_offset = 0 } else null,
31398 .pointee = alloc_tv,
31399 .is_mutable = true,
31400 .ty_without_well_defined_layout = if (!layout_defined) alloc.ty else null,
31241 .parent = if (layout_defined) .{ .val = alloc.val, .byte_offset = 0 } else null,
31242 .pointee = alloc.val,
31243 .ty_without_well_defined_layout = if (!layout_defined) alloc_ty else null,
3140131244 };
3140231245 },
3140331246 .anon_decl => |anon_decl| blk: {
3140431247 const decl_val = anon_decl.val;
3140531248 if (Value.fromInterned(decl_val).getVariable(mod) != null) return error.RuntimeLoad;
3140631249 const decl_ty = Type.fromInterned(ip.typeOf(decl_val));
31407 const decl_tv: TypedValue = .{ .ty = decl_ty, .val = Value.fromInterned(decl_val) };
31250 const decl_mv: MutableValue = .{ .interned = decl_val };
3140831251 const layout_defined = decl_ty.hasWellDefinedLayout(mod);
3140931252 break :blk ComptimePtrLoadKit{
31410 .parent = if (layout_defined) .{ .tv = decl_tv, .byte_offset = 0 } else null,
31411 .pointee = decl_tv,
31412 .is_mutable = false,
31253 .parent = if (layout_defined) .{ .val = decl_mv, .byte_offset = 0 } else null,
31254 .pointee = decl_mv,
3141331255 .ty_without_well_defined_layout = if (!layout_defined) decl_ty else null,
3141431256 };
3141531257 },
3141631258 .int => return error.RuntimeLoad,
3141731259 .eu_payload, .opt_payload => |container_ptr| blk: {
3141831260 const container_ty = Type.fromInterned(ip.typeOf(container_ptr)).childType(mod);
31419 const payload_ty = switch (ptr.addr) {
31420 .eu_payload => container_ty.errorUnionPayload(mod),
31421 .opt_payload => container_ty.optionalChild(mod),
31422 else => unreachable,
31423 };
3142431261 var deref = try sema.beginComptimePtrLoad(block, src, Value.fromInterned(container_ptr), container_ty);
3142531262
3142631263 // eu_payload and opt_payload never have a well-defined layout
......@@ -31429,15 +31266,14 @@ fn beginComptimePtrLoad(
3142931266 deref.ty_without_well_defined_layout = container_ty;
3143031267 }
3143131268
31432 if (deref.pointee) |*tv| {
31269 if (deref.pointee) |pointee| {
31270 const pointee_ty = pointee.typeOf(mod);
3143331271 const coerce_in_mem_ok =
31434 (try sema.coerceInMemoryAllowed(block, container_ty, tv.ty, false, target, src, src)) == .ok or
31435 (try sema.coerceInMemoryAllowed(block, tv.ty, container_ty, false, target, src, src)) == .ok;
31272 (try sema.coerceInMemoryAllowed(block, container_ty, pointee_ty, false, target, src, src)) == .ok or
31273 (try sema.coerceInMemoryAllowed(block, pointee_ty, container_ty, false, target, src, src)) == .ok;
3143631274 if (coerce_in_mem_ok) {
31437 const payload_val = switch (tv.val.ip_index) {
31438 .none => tv.val.cast(Value.Payload.SubValue).?.data,
31439 .null_value => return sema.fail(block, src, "attempt to use null value", .{}),
31440 else => Value.fromInterned(switch (ip.indexToKey(tv.val.toIntern())) {
31275 deref.pointee = switch (pointee) {
31276 .interned => |ip_index| .{ .interned = switch (ip.indexToKey(ip_index)) {
3144131277 .error_union => |error_union| switch (error_union.val) {
3144231278 .err_name => |err_name| return sema.fail(
3144331279 block,
......@@ -31452,23 +31288,20 @@ fn beginComptimePtrLoad(
3145231288 else => |payload| payload,
3145331289 },
3145431290 else => unreachable,
31455 }),
31291 } },
31292 .eu_payload, .opt_payload => |p| p.child.*,
31293 else => unreachable,
3145631294 };
31457 tv.* = TypedValue{ .ty = payload_ty, .val = payload_val };
3145831295 break :blk deref;
3145931296 }
3146031297 }
3146131298 deref.pointee = null;
3146231299 break :blk deref;
3146331300 },
31464 .comptime_field => |comptime_field| blk: {
31465 const field_ty = Type.fromInterned(ip.typeOf(comptime_field));
31466 break :blk ComptimePtrLoadKit{
31467 .parent = null,
31468 .pointee = .{ .ty = field_ty, .val = Value.fromInterned(comptime_field) },
31469 .is_mutable = false,
31470 .ty_without_well_defined_layout = field_ty,
31471 };
31301 .comptime_field => |field_val| .{
31302 .parent = null,
31303 .pointee = .{ .interned = field_val },
31304 .ty_without_well_defined_layout = Type.fromInterned(ip.typeOf(field_val)),
3147231305 },
3147331306 .elem => |elem_ptr| blk: {
3147431307 const elem_ty = Type.fromInterned(ip.typeOf(elem_ptr.base)).elemType2(mod);
......@@ -31501,30 +31334,37 @@ fn beginComptimePtrLoad(
3150131334
3150231335 // If we're loading an elem that was derived from a different type
3150331336 // than the true type of the underlying decl, we cannot deref directly
31504 const ty_matches = if (deref.pointee != null and deref.pointee.?.ty.isArrayOrVector(mod)) x: {
31505 const deref_elem_ty = deref.pointee.?.ty.childType(mod);
31506 break :x (try sema.coerceInMemoryAllowed(block, deref_elem_ty, elem_ty, false, target, src, src)) == .ok or
31507 (try sema.coerceInMemoryAllowed(block, elem_ty, deref_elem_ty, false, target, src, src)) == .ok;
31337 const ty_matches = if (deref.pointee) |pointee| match: {
31338 const ty = pointee.typeOf(mod);
31339 if (!ty.isArrayOrVector(mod)) break :match false;
31340 const deref_elem_ty = ty.childType(mod);
31341 if ((try sema.coerceInMemoryAllowed(block, deref_elem_ty, elem_ty, false, target, src, src)) == .ok) break :match true;
31342 if ((try sema.coerceInMemoryAllowed(block, elem_ty, deref_elem_ty, false, target, src, src)) == .ok) break :match true;
31343 break :match false;
3150831344 } else false;
3150931345 if (!ty_matches) {
3151031346 deref.pointee = null;
3151131347 break :blk deref;
3151231348 }
3151331349
31514 var array_tv = deref.pointee.?;
31515 const check_len = array_tv.ty.arrayLenIncludingSentinel(mod);
31350 var array_val = deref.pointee.?;
31351 const check_len = array_val.typeOf(mod).arrayLenIncludingSentinel(mod);
3151631352 if (maybe_array_ty) |load_ty| {
3151731353 // It's possible that we're loading a [N]T, in which case we'd like to slice
3151831354 // the pointee array directly from our parent array.
3151931355 if (load_ty.isArrayOrVector(mod) and load_ty.childType(mod).eql(elem_ty, mod)) {
3152031356 const len = try sema.usizeCast(block, src, load_ty.arrayLenIncludingSentinel(mod));
3152131357 const elem_idx = try sema.usizeCast(block, src, elem_ptr.index);
31522 deref.pointee = if (elem_ptr.index + len <= check_len) TypedValue{
31523 .ty = try mod.arrayType(.{
31524 .len = len,
31525 .child = elem_ty.toIntern(),
31526 }),
31527 .val = try array_tv.val.sliceArray(sema, elem_idx, elem_idx + len),
31358 deref.pointee = if (elem_ptr.index + len <= check_len) switch (array_val) {
31359 .aggregate => |a| .{ .aggregate = .{
31360 .ty = (try mod.arrayType(.{ .len = len, .child = elem_ty.toIntern() })).toIntern(),
31361 .elems = a.elems[elem_idx..][0..len],
31362 } },
31363 else => .{
31364 .interned = (try (Value.fromInterned(
31365 try array_val.intern(mod, sema.arena),
31366 ).sliceArray(sema, elem_idx, elem_idx + len))).toIntern(),
31367 },
3152831368 } else null;
3152931369 break :blk deref;
3153031370 }
......@@ -31535,18 +31375,12 @@ fn beginComptimePtrLoad(
3153531375 break :blk deref;
3153631376 }
3153731377 if (elem_ptr.index == check_len - 1) {
31538 if (array_tv.ty.sentinel(mod)) |sent| {
31539 deref.pointee = TypedValue{
31540 .ty = elem_ty,
31541 .val = sent,
31542 };
31378 if (array_val.typeOf(mod).sentinel(mod)) |sent| {
31379 deref.pointee = .{ .interned = sent.toIntern() };
3154331380 break :blk deref;
3154431381 }
3154531382 }
31546 deref.pointee = TypedValue{
31547 .ty = elem_ty,
31548 .val = try array_tv.val.elemValue(mod, @intCast(elem_ptr.index)),
31549 };
31383 deref.pointee = try array_val.getElem(mod, @intCast(elem_ptr.index));
3155031384 break :blk deref;
3155131385 },
3155231386 .field => |field_ptr| blk: {
......@@ -31570,37 +31404,17 @@ fn beginComptimePtrLoad(
3157031404 deref.ty_without_well_defined_layout = container_ty;
3157131405 }
3157231406
31573 const tv = deref.pointee orelse {
31574 deref.pointee = null;
31575 break :blk deref;
31576 };
31407 const pointee = deref.pointee orelse break :blk deref;
31408 const pointee_ty = pointee.typeOf(mod);
3157731409 const coerce_in_mem_ok =
31578 (try sema.coerceInMemoryAllowed(block, container_ty, tv.ty, false, target, src, src)) == .ok or
31579 (try sema.coerceInMemoryAllowed(block, tv.ty, container_ty, false, target, src, src)) == .ok;
31410 (try sema.coerceInMemoryAllowed(block, container_ty, pointee_ty, false, target, src, src)) == .ok or
31411 (try sema.coerceInMemoryAllowed(block, pointee_ty, container_ty, false, target, src, src)) == .ok;
3158031412 if (!coerce_in_mem_ok) {
3158131413 deref.pointee = null;
3158231414 break :blk deref;
3158331415 }
3158431416
31585 if (container_ty.isSlice(mod)) {
31586 deref.pointee = switch (field_index) {
31587 Value.slice_ptr_index => TypedValue{
31588 .ty = container_ty.slicePtrFieldType(mod),
31589 .val = tv.val.slicePtr(mod),
31590 },
31591 Value.slice_len_index => TypedValue{
31592 .ty = Type.usize,
31593 .val = Value.fromInterned(ip.indexToKey(try tv.val.intern(tv.ty, mod)).slice.len),
31594 },
31595 else => unreachable,
31596 };
31597 } else {
31598 const field_ty = container_ty.structFieldType(field_index, mod);
31599 deref.pointee = TypedValue{
31600 .ty = field_ty,
31601 .val = try tv.val.fieldValue(mod, field_index),
31602 };
31603 }
31417 deref.pointee = try pointee.getElem(mod, field_index);
3160431418 break :blk deref;
3160531419 },
3160631420 },
......@@ -31611,9 +31425,9 @@ fn beginComptimePtrLoad(
3161131425 else => unreachable,
3161231426 };
3161331427
31614 if (deref.pointee) |tv| {
31615 if (deref.parent == null and tv.ty.hasWellDefinedLayout(mod)) {
31616 deref.parent = .{ .tv = tv, .byte_offset = 0 };
31428 if (deref.pointee) |val| {
31429 if (deref.parent == null and val.typeOf(mod).hasWellDefinedLayout(mod)) {
31430 deref.parent = .{ .val = val, .byte_offset = 0 };
3161731431 }
3161831432 }
3161931433 return deref;
......@@ -31760,16 +31574,11 @@ fn coerceArrayPtrToSlice(
3176031574 if (try sema.resolveValue(inst)) |val| {
3176131575 const ptr_array_ty = sema.typeOf(inst);
3176231576 const array_ty = ptr_array_ty.childType(mod);
31577 const slice_ptr_ty = dest_ty.slicePtrFieldType(mod);
31578 const slice_ptr = try mod.getCoerced(val, slice_ptr_ty);
3176331579 const slice_val = try mod.intern(.{ .slice = .{
3176431580 .ty = dest_ty.toIntern(),
31765 .ptr = try mod.intern(.{ .ptr = .{
31766 .ty = dest_ty.slicePtrFieldType(mod).toIntern(),
31767 .addr = switch (mod.intern_pool.indexToKey(val.toIntern())) {
31768 .undef => .{ .int = try mod.intern(.{ .undef = .usize_type }) },
31769 .ptr => |ptr| ptr.addr,
31770 else => unreachable,
31771 },
31772 } }),
31581 .ptr = slice_ptr.toIntern(),
3177331582 .len = (try mod.intValue(Type.usize, array_ty.arrayLen(mod))).toIntern(),
3177431583 } });
3177531584 return Air.internedToRef(slice_val);
......@@ -31844,7 +31653,7 @@ fn coerceCompatiblePtrs(
3184431653 }
3184531654 // The comptime Value representation is compatible with both types.
3184631655 return Air.internedToRef(
31847 (try mod.getCoerced(Value.fromInterned((try val.intern(inst_ty, mod))), dest_ty)).toIntern(),
31656 (try mod.getCoerced(val, dest_ty)).toIntern(),
3184831657 );
3184931658 }
3185031659 try sema.requireRuntimeBlock(block, inst_src, null);
......@@ -31899,7 +31708,7 @@ fn coerceEnumToUnion(
3189931708 if (try sema.resolveDefinedValue(block, inst_src, enum_tag)) |val| {
3190031709 const field_index = union_ty.unionTagFieldIndex(val, sema.mod) orelse {
3190131710 return sema.fail(block, inst_src, "union '{}' has no tag with value '{}'", .{
31902 union_ty.fmt(sema.mod), val.fmtValue(tag_ty, sema.mod),
31711 union_ty.fmt(sema.mod), val.fmtValue(sema.mod),
3190331712 });
3190431713 };
3190531714
......@@ -32181,7 +31990,7 @@ fn coerceArrayLike(
3218131990 ref.* = coerced;
3218231991 if (runtime_src == null) {
3218331992 if (try sema.resolveValue(coerced)) |elem_val| {
32184 val.* = try elem_val.intern(dest_elem_ty, mod);
31993 val.* = elem_val.toIntern();
3218531994 } else {
3218631995 runtime_src = elem_src;
3218731996 }
......@@ -32246,7 +32055,7 @@ fn coerceTupleToArray(
3224632055 ref.* = coerced;
3224732056 if (runtime_src == null) {
3224832057 if (try sema.resolveValue(coerced)) |elem_val| {
32249 val.* = try elem_val.intern(dest_elem_ty, mod);
32058 val.* = elem_val.toIntern();
3225032059 } else {
3225132060 runtime_src = elem_src;
3225232061 }
......@@ -32650,7 +32459,7 @@ fn optRefValue(sema: *Sema, opt_val: ?Value) !Value {
3265032459 return Value.fromInterned((try mod.intern(.{ .opt = .{
3265132460 .ty = (try mod.optionalType(ptr_anyopaque_ty.toIntern())).toIntern(),
3265232461 .val = if (opt_val) |val| (try mod.getCoerced(
32653 Value.fromInterned((try sema.refValue(val.toIntern()))),
32462 Value.fromInterned(try sema.refValue(val.toIntern())),
3265432463 ptr_anyopaque_ty,
3265532464 )).toIntern() else .none,
3265632465 } })));
......@@ -32668,8 +32477,8 @@ fn analyzeDeclRefInner(sema: *Sema, decl_index: InternPool.DeclIndex, analyze_fn
3266832477 const mod = sema.mod;
3266932478 try sema.ensureDeclAnalyzed(decl_index);
3267032479
32671 const decl_tv = try mod.declPtr(decl_index).typedValue();
32672 const owner_decl = mod.declPtr(switch (mod.intern_pool.indexToKey(decl_tv.val.toIntern())) {
32480 const decl_val = try mod.declPtr(decl_index).valueOrFail();
32481 const owner_decl = mod.declPtr(switch (mod.intern_pool.indexToKey(decl_val.toIntern())) {
3267332482 .variable => |variable| variable.decl,
3267432483 .extern_func => |extern_func| extern_func.decl,
3267532484 .func => |func| func.owner_decl,
......@@ -32678,10 +32487,10 @@ fn analyzeDeclRefInner(sema: *Sema, decl_index: InternPool.DeclIndex, analyze_fn
3267832487 // TODO: if this is a `decl_ref` of a non-variable decl, only depend on decl type
3267932488 try sema.declareDependency(.{ .decl_val = decl_index });
3268032489 const ptr_ty = try sema.ptrType(.{
32681 .child = decl_tv.ty.toIntern(),
32490 .child = decl_val.typeOf(mod).toIntern(),
3268232491 .flags = .{
3268332492 .alignment = owner_decl.alignment,
32684 .is_const = if (decl_tv.val.getVariable(mod)) |variable| variable.is_const else true,
32493 .is_const = if (decl_val.getVariable(mod)) |variable| variable.is_const else true,
3268532494 .address_space = owner_decl.@"addrspace",
3268632495 },
3268732496 });
......@@ -32697,12 +32506,10 @@ fn analyzeDeclRefInner(sema: *Sema, decl_index: InternPool.DeclIndex, analyze_fn
3269732506fn maybeQueueFuncBodyAnalysis(sema: *Sema, decl_index: InternPool.DeclIndex) !void {
3269832507 const mod = sema.mod;
3269932508 const decl = mod.declPtr(decl_index);
32700 const tv = try decl.typedValue();
32701 if (tv.ty.zigTypeTag(mod) != .Fn) return;
32702 if (!try sema.fnHasRuntimeBits(tv.ty)) return;
32703 const func_index = tv.val.toIntern();
32704 if (!mod.intern_pool.isFuncBody(func_index)) return; // undef or extern function
32705 try mod.ensureFuncBodyAnalysisQueued(func_index);
32509 const decl_val = try decl.valueOrFail();
32510 if (!mod.intern_pool.isFuncBody(decl_val.toIntern())) return;
32511 if (!try sema.fnHasRuntimeBits(decl_val.typeOf(mod))) return;
32512 try mod.ensureFuncBodyAnalysisQueued(decl_val.toIntern());
3270632513}
3270732514
3270832515fn analyzeRef(
......@@ -32839,7 +32646,7 @@ fn analyzeSliceLen(
3283932646 if (slice_val.isUndef(mod)) {
3284032647 return mod.undefRef(Type.usize);
3284132648 }
32842 return mod.intRef(Type.usize, slice_val.sliceLen(sema.mod));
32649 return mod.intRef(Type.usize, try slice_val.sliceLen(sema));
3284332650 }
3284432651 try sema.requireRuntimeBlock(block, src, null);
3284532652 return block.addTyOp(.slice_len, Type.usize, slice_inst);
......@@ -33121,8 +32928,8 @@ fn analyzeSlice(
3312132928 msg,
3312232929 "expected '{}', found '{}'",
3312332930 .{
33124 Value.zero_comptime_int.fmtValue(Type.comptime_int, mod),
33125 start_value.fmtValue(Type.comptime_int, mod),
32931 Value.zero_comptime_int.fmtValue(mod),
32932 start_value.fmtValue(mod),
3312632933 },
3312732934 );
3312832935 break :msg msg;
......@@ -33138,8 +32945,8 @@ fn analyzeSlice(
3313832945 msg,
3313932946 "expected '{}', found '{}'",
3314032947 .{
33141 Value.one_comptime_int.fmtValue(Type.comptime_int, mod),
33142 end_value.fmtValue(Type.comptime_int, mod),
32948 Value.one_comptime_int.fmtValue(mod),
32949 end_value.fmtValue(mod),
3314332950 },
3314432951 );
3314532952 break :msg msg;
......@@ -33152,7 +32959,7 @@ fn analyzeSlice(
3315232959 block,
3315332960 end_src,
3315432961 "end index {} out of bounds for slice of single-item pointer",
33155 .{end_value.fmtValue(Type.comptime_int, mod)},
32962 .{end_value.fmtValue(mod)},
3315632963 );
3315732964 }
3315832965 }
......@@ -33247,8 +33054,8 @@ fn analyzeSlice(
3324733054 end_src,
3324833055 "end index {} out of bounds for array of length {}{s}",
3324933056 .{
33250 end_val.fmtValue(Type.usize, mod),
33251 len_val.fmtValue(Type.usize, mod),
33057 end_val.fmtValue(mod),
33058 len_val.fmtValue(mod),
3325233059 sentinel_label,
3325333060 },
3325433061 );
......@@ -33278,7 +33085,7 @@ fn analyzeSlice(
3327833085 return sema.fail(block, src, "slice of undefined", .{});
3327933086 }
3328033087 const has_sentinel = slice_ty.sentinel(mod) != null;
33281 const slice_len = slice_val.sliceLen(mod);
33088 const slice_len = try slice_val.sliceLen(sema);
3328233089 const len_plus_sent = slice_len + @intFromBool(has_sentinel);
3328333090 const slice_len_val_with_sentinel = try mod.intValue(Type.usize, len_plus_sent);
3328433091 if (!(try sema.compareAll(end_val, .lte, slice_len_val_with_sentinel, Type.usize))) {
......@@ -33292,8 +33099,8 @@ fn analyzeSlice(
3329233099 end_src,
3329333100 "end index {} out of bounds for slice of length {d}{s}",
3329433101 .{
33295 end_val.fmtValue(Type.usize, mod),
33296 slice_val.sliceLen(mod),
33102 end_val.fmtValue(mod),
33103 try slice_val.sliceLen(sema),
3329733104 sentinel_label,
3329833105 },
3329933106 );
......@@ -33352,8 +33159,8 @@ fn analyzeSlice(
3335233159 start_src,
3335333160 "start index {} is larger than end index {}",
3335433161 .{
33355 start_val.fmtValue(Type.usize, mod),
33356 end_val.fmtValue(Type.usize, mod),
33162 start_val.fmtValue(mod),
33163 end_val.fmtValue(mod),
3335733164 },
3335833165 );
3335933166 }
......@@ -33391,8 +33198,8 @@ fn analyzeSlice(
3339133198 const msg = try sema.errMsg(block, src, "value in memory does not match slice sentinel", .{});
3339233199 errdefer msg.destroy(sema.gpa);
3339333200 try sema.errNote(block, src, msg, "expected '{}', found '{}'", .{
33394 expected_sentinel.fmtValue(elem_ty, mod),
33395 actual_sentinel.fmtValue(elem_ty, mod),
33201 expected_sentinel.fmtValue(mod),
33202 actual_sentinel.fmtValue(mod),
3339633203 });
3339733204
3339833205 break :msg msg;
......@@ -33483,10 +33290,7 @@ fn analyzeSlice(
3348333290 };
3348433291
3348533292 if (!new_ptr_val.isUndef(mod)) {
33486 return Air.internedToRef((try mod.getCoerced(
33487 Value.fromInterned((try new_ptr_val.intern(new_ptr_ty, mod))),
33488 return_ty,
33489 )).toIntern());
33293 return Air.internedToRef((try mod.getCoerced(new_ptr_val, return_ty)).toIntern());
3349033294 }
3349133295
3349233296 // Special case: @as([]i32, undefined)[x..x]
......@@ -33525,7 +33329,7 @@ fn analyzeSlice(
3352533329 if (try sema.resolveDefinedValue(block, src, ptr_or_slice)) |slice_val| {
3352633330 // we don't need to add one for sentinels because the
3352733331 // underlying value data includes the sentinel
33528 break :blk try mod.intRef(Type.usize, slice_val.sliceLen(mod));
33332 break :blk try mod.intRef(Type.usize, try slice_val.sliceLen(sema));
3352933333 }
3353033334
3353133335 const slice_len_inst = try block.addTyOp(.slice_len, Type.usize, ptr_or_slice);
......@@ -33998,7 +33802,7 @@ fn wrapErrorUnionPayload(
3399833802 if (try sema.resolveValue(coerced)) |val| {
3399933803 return Air.internedToRef((try mod.intern(.{ .error_union = .{
3400033804 .ty = dest_ty.toIntern(),
34001 .val = .{ .payload = try val.intern(dest_payload_ty, mod) },
33805 .val = .{ .payload = val.toIntern() },
3400233806 } })));
3400333807 }
3400433808 try sema.requireRuntimeBlock(block, inst_src, null);
......@@ -36611,7 +36415,7 @@ fn resolveInferredErrorSet(
3661136415 // inferred error sets, each call gets an adhoc InferredErrorSet object, which
3661236416 // has no corresponding function body.
3661336417 const ies_func_owner_decl = mod.declPtr(func.owner_decl);
36614 const ies_func_info = mod.typeToFunc(ies_func_owner_decl.ty).?;
36418 const ies_func_info = mod.typeToFunc(ies_func_owner_decl.typeOf(mod)).?;
3661536419 // if ies declared by a inline function with generic return type, the return_type should be generic_poison,
3661636420 // because inline function does not create a new declaration, and the ies has been filled with analyzeCall,
3661736421 // so here we can simply skip this case.
......@@ -37174,15 +36978,14 @@ fn semaStructFieldInits(
3717436978 });
3717536979 };
3717636980
37177 const field_init = try default_val.intern(field_ty, mod);
37178 if (Value.fromInterned(field_init).canMutateComptimeVarState(mod)) {
36981 if (default_val.canMutateComptimeVarState(mod)) {
3717936982 const init_src = mod.fieldSrcLoc(decl_index, .{
3718036983 .index = field_i,
3718136984 .range = .value,
3718236985 }).lazy;
3718336986 return sema.fail(&block_scope, init_src, "field default value contains reference to comptime-mutable memory", .{});
3718436987 }
37185 struct_type.field_inits.get(ip)[field_i] = field_init;
36988 struct_type.field_inits.get(ip)[field_i] = default_val.toIntern();
3718636989 }
3718736990 }
3718836991}
......@@ -37410,7 +37213,7 @@ fn semaUnionFields(mod: *Module, arena: Allocator, union_type: InternPool.Loaded
3741037213 const field_src = mod.fieldSrcLoc(union_type.decl, .{ .index = field_i }).lazy;
3741137214 const other_field_src = mod.fieldSrcLoc(union_type.decl, .{ .index = gop.index }).lazy;
3741237215 const msg = msg: {
37413 const msg = try sema.errMsg(&block_scope, field_src, "enum tag value {} already taken", .{enum_tag_val.fmtValue(int_tag_ty, mod)});
37216 const msg = try sema.errMsg(&block_scope, field_src, "enum tag value {} already taken", .{enum_tag_val.fmtValue(mod)});
3741437217 errdefer msg.destroy(gpa);
3741537218 try sema.errNote(&block_scope, other_field_src, msg, "other occurrence here", .{});
3741637219 break :msg msg;
......@@ -37607,10 +37410,12 @@ fn generateUnionTagTypeNumbered(
3760737410 errdefer mod.destroyDecl(new_decl_index);
3760837411 const fqn = try union_owner_decl.fullyQualifiedName(mod);
3760937412 const name = try ip.getOrPutStringFmt(gpa, "@typeInfo({}).Union.tag_type.?", .{fqn.fmt(ip)});
37610 try mod.initNewAnonDecl(new_decl_index, src_decl.src_line, .{
37611 .ty = Type.noreturn,
37612 .val = Value.@"unreachable",
37613 }, name);
37413 try mod.initNewAnonDecl(
37414 new_decl_index,
37415 src_decl.src_line,
37416 Value.@"unreachable",
37417 name,
37418 );
3761437419 errdefer mod.abortAnonDecl(new_decl_index);
3761537420
3761637421 const new_decl = mod.declPtr(new_decl_index);
......@@ -37629,7 +37434,6 @@ fn generateUnionTagTypeNumbered(
3762937434 .tag_mode = .explicit,
3763037435 });
3763137436
37632 new_decl.ty = Type.type;
3763337437 new_decl.val = Value.fromInterned(enum_ty);
3763437438
3763537439 try mod.finalizeAnonDecl(new_decl_index);
......@@ -37652,10 +37456,12 @@ fn generateUnionTagTypeSimple(
3765237456 const new_decl_index = try mod.allocateNewDecl(block.namespace, src_decl.src_node);
3765337457 errdefer mod.destroyDecl(new_decl_index);
3765437458 const name = try ip.getOrPutStringFmt(gpa, "@typeInfo({}).Union.tag_type.?", .{fqn.fmt(ip)});
37655 try mod.initNewAnonDecl(new_decl_index, src_decl.src_line, .{
37656 .ty = Type.noreturn,
37657 .val = Value.@"unreachable",
37658 }, name);
37459 try mod.initNewAnonDecl(
37460 new_decl_index,
37461 src_decl.src_line,
37462 Value.@"unreachable",
37463 name,
37464 );
3765937465 mod.declPtr(new_decl_index).name_fully_qualified = true;
3766037466 break :new_decl_index new_decl_index;
3766137467 };
......@@ -37675,7 +37481,6 @@ fn generateUnionTagTypeSimple(
3767537481
3767637482 const new_decl = mod.declPtr(new_decl_index);
3767737483 new_decl.owns_tv = true;
37678 new_decl.ty = Type.type;
3767937484 new_decl.val = Value.fromInterned(enum_ty);
3768037485
3768137486 try mod.finalizeAnonDecl(new_decl_index);
......@@ -37991,7 +37796,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
3799137796 return sema.failWithOwnedErrorMsg(null, msg);
3799237797 }
3799337798 if (try sema.typeHasOnePossibleValue(field_ty)) |field_opv| {
37994 field_val.* = try field_opv.intern(field_ty, mod);
37799 field_val.* = field_opv.toIntern();
3799537800 } else return null;
3799637801 }
3799737802
......@@ -38290,17 +38095,18 @@ fn pointerDerefExtra(sema: *Sema, block: *Block, src: LazySrcLoc, ptr_val: Value
3829038095 else => |e| return e,
3829138096 };
3829238097
38293 if (deref.pointee) |tv| {
38098 if (deref.pointee) |pointee| {
38099 const uncoerced_val = Value.fromInterned(try pointee.intern(mod, sema.arena));
38100 const ty = Type.fromInterned(mod.intern_pool.typeOf(uncoerced_val.toIntern()));
3829438101 const coerce_in_mem_ok =
38295 (try sema.coerceInMemoryAllowed(block, load_ty, tv.ty, false, target, src, src)) == .ok or
38296 (try sema.coerceInMemoryAllowed(block, tv.ty, load_ty, false, target, src, src)) == .ok;
38102 (try sema.coerceInMemoryAllowed(block, load_ty, ty, false, target, src, src)) == .ok or
38103 (try sema.coerceInMemoryAllowed(block, ty, load_ty, false, target, src, src)) == .ok;
3829738104 if (coerce_in_mem_ok) {
3829838105 // We have a Value that lines up in virtual memory exactly with what we want to load,
3829938106 // and it is in-memory coercible to load_ty. It may be returned without modifications.
3830038107 // Move mutable decl values to the InternPool and assert other decls are already in
3830138108 // the InternPool.
38302 const uncoerced_val = if (deref.is_mutable) try tv.val.intern(tv.ty, mod) else tv.val.toIntern();
38303 const coerced_val = try mod.getCoerced(Value.fromInterned(uncoerced_val), load_ty);
38109 const coerced_val = try mod.getCoerced(uncoerced_val, load_ty);
3830438110 return .{ .val = coerced_val };
3830538111 }
3830638112 }
......@@ -38314,21 +38120,35 @@ fn pointerDerefExtra(sema: *Sema, block: *Block, src: LazySrcLoc, ptr_val: Value
3831438120 const load_sz = try sema.typeAbiSize(load_ty);
3831538121
3831638122 // Try the smaller bit-cast first, since that's more efficient than using the larger `parent`
38317 if (deref.pointee) |tv| if (load_sz <= try sema.typeAbiSize(tv.ty))
38318 return DerefResult{ .val = (try sema.bitCastVal(block, src, tv.val, tv.ty, load_ty, 0)) orelse return .runtime_load };
38123 if (deref.pointee) |pointee| {
38124 const val_ip_index = try pointee.intern(mod, sema.arena);
38125 const val = Value.fromInterned(val_ip_index);
38126 const ty = Type.fromInterned(mod.intern_pool.typeOf(val_ip_index));
38127 if (load_sz <= try sema.typeAbiSize(ty)) {
38128 return .{ .val = (try sema.bitCastVal(block, src, val, ty, load_ty, 0)) orelse return .runtime_load };
38129 }
38130 }
3831938131
3832038132 // If that fails, try to bit-cast from the largest parent value with a well-defined layout
38321 if (deref.parent) |parent| if (load_sz + parent.byte_offset <= try sema.typeAbiSize(parent.tv.ty))
38322 return DerefResult{ .val = (try sema.bitCastVal(block, src, parent.tv.val, parent.tv.ty, load_ty, parent.byte_offset)) orelse return .runtime_load };
38133 if (deref.parent) |parent| {
38134 const parent_ip_index = try parent.val.intern(mod, sema.arena);
38135 const parent_val = Value.fromInterned(parent_ip_index);
38136 const parent_ty = Type.fromInterned(mod.intern_pool.typeOf(parent_ip_index));
38137 if (load_sz + parent.byte_offset <= try sema.typeAbiSize(parent_ty)) {
38138 return .{ .val = (try sema.bitCastVal(block, src, parent_val, parent_ty, load_ty, parent.byte_offset)) orelse return .runtime_load };
38139 }
38140 }
3832338141
3832438142 if (deref.ty_without_well_defined_layout) |bad_ty| {
3832538143 // We got no parent for bit-casting, or the parent we got was too small. Either way, the problem
3832638144 // is that some type we encountered when de-referencing does not have a well-defined layout.
38327 return DerefResult{ .needed_well_defined = bad_ty };
38145 return .{ .needed_well_defined = bad_ty };
3832838146 } else {
3832938147 // If all encountered types had well-defined layouts, the parent is the root decl and it just
3833038148 // wasn't big enough for the load.
38331 return DerefResult{ .out_of_bounds = deref.parent.?.tv.ty };
38149 const parent_ip_index = try deref.parent.?.val.intern(mod, sema.arena);
38150 const parent_ty = Type.fromInterned(mod.intern_pool.typeOf(parent_ip_index));
38151 return .{ .out_of_bounds = parent_ty };
3833238152 }
3833338153}
3833438154
......@@ -38530,7 +38350,7 @@ fn intAddInner(sema: *Sema, lhs: Value, rhs: Value, ty: Type, overflow_idx: *usi
3853038350 },
3853138351 else => |e| return e,
3853238352 };
38533 scalar.* = try val.intern(scalar_ty, mod);
38353 scalar.* = val.toIntern();
3853438354 }
3853538355 return Value.fromInterned((try mod.intern(.{ .aggregate = .{
3853638356 .ty = ty.toIntern(),
......@@ -38620,7 +38440,7 @@ fn intSubInner(sema: *Sema, lhs: Value, rhs: Value, ty: Type, overflow_idx: *usi
3862038440 },
3862138441 else => |e| return e,
3862238442 };
38623 scalar.* = try val.intern(scalar_ty, mod);
38443 scalar.* = val.toIntern();
3862438444 }
3862538445 return Value.fromInterned((try mod.intern(.{ .aggregate = .{
3862638446 .ty = ty.toIntern(),
......@@ -38690,8 +38510,8 @@ fn intSubWithOverflow(
3869038510 const lhs_elem = try lhs.elemValue(sema.mod, i);
3869138511 const rhs_elem = try rhs.elemValue(sema.mod, i);
3869238512 const of_math_result = try sema.intSubWithOverflowScalar(lhs_elem, rhs_elem, scalar_ty);
38693 of.* = try of_math_result.overflow_bit.intern(Type.u1, mod);
38694 scalar.* = try of_math_result.wrapped_result.intern(scalar_ty, mod);
38513 of.* = of_math_result.overflow_bit.toIntern();
38514 scalar.* = of_math_result.wrapped_result.toIntern();
3869538515 }
3869638516 return Value.OverflowArithmeticResult{
3869738517 .overflow_bit = Value.fromInterned((try mod.intern(.{ .aggregate = .{
......@@ -38746,19 +38566,17 @@ fn intFromFloat(
3874638566) CompileError!Value {
3874738567 const mod = sema.mod;
3874838568 if (float_ty.zigTypeTag(mod) == .Vector) {
38749 const elem_ty = float_ty.scalarType(mod);
3875038569 const result_data = try sema.arena.alloc(InternPool.Index, float_ty.vectorLen(mod));
38751 const scalar_ty = int_ty.scalarType(mod);
3875238570 for (result_data, 0..) |*scalar, i| {
3875338571 const elem_val = try val.elemValue(sema.mod, i);
38754 scalar.* = try (try sema.intFromFloatScalar(block, src, elem_val, elem_ty, int_ty.scalarType(mod), mode)).intern(scalar_ty, mod);
38572 scalar.* = (try sema.intFromFloatScalar(block, src, elem_val, int_ty.scalarType(mod), mode)).toIntern();
3875538573 }
3875638574 return Value.fromInterned((try mod.intern(.{ .aggregate = .{
3875738575 .ty = int_ty.toIntern(),
3875838576 .storage = .{ .elems = result_data },
3875938577 } })));
3876038578 }
38761 return sema.intFromFloatScalar(block, src, val, float_ty, int_ty, mode);
38579 return sema.intFromFloatScalar(block, src, val, int_ty, mode);
3876238580}
3876338581
3876438582// float is expected to be finite and non-NaN
......@@ -38791,7 +38609,6 @@ fn intFromFloatScalar(
3879138609 block: *Block,
3879238610 src: LazySrcLoc,
3879338611 val: Value,
38794 float_ty: Type,
3879538612 int_ty: Type,
3879638613 mode: IntFromFloatMode,
3879738614) CompileError!Value {
......@@ -38803,7 +38620,7 @@ fn intFromFloatScalar(
3880338620 block,
3880438621 src,
3880538622 "fractional component prevents float value '{}' from coercion to type '{}'",
38806 .{ val.fmtValue(float_ty, mod), int_ty.fmt(mod) },
38623 .{ val.fmtValue(mod), int_ty.fmt(mod) },
3880738624 );
3880838625
3880938626 const float = val.toFloat(f128, mod);
......@@ -38825,7 +38642,7 @@ fn intFromFloatScalar(
3882538642
3882638643 if (!(try sema.intFitsInType(cti_result, int_ty, null))) {
3882738644 return sema.fail(block, src, "float value '{}' cannot be stored in integer type '{}'", .{
38828 val.fmtValue(float_ty, sema.mod), int_ty.fmt(sema.mod),
38645 val.fmtValue(sema.mod), int_ty.fmt(sema.mod),
3882938646 });
3883038647 }
3883138648 return mod.getCoerced(cti_result, int_ty);
......@@ -38944,8 +38761,8 @@ fn intAddWithOverflow(
3894438761 const lhs_elem = try lhs.elemValue(sema.mod, i);
3894538762 const rhs_elem = try rhs.elemValue(sema.mod, i);
3894638763 const of_math_result = try sema.intAddWithOverflowScalar(lhs_elem, rhs_elem, scalar_ty);
38947 of.* = try of_math_result.overflow_bit.intern(Type.u1, mod);
38948 scalar.* = try of_math_result.wrapped_result.intern(scalar_ty, mod);
38764 of.* = of_math_result.overflow_bit.toIntern();
38765 scalar.* = of_math_result.wrapped_result.toIntern();
3894938766 }
3895038767 return Value.OverflowArithmeticResult{
3895138768 .overflow_bit = Value.fromInterned((try mod.intern(.{ .aggregate = .{
......@@ -39055,7 +38872,7 @@ fn compareVector(
3905538872 const lhs_elem = try lhs.elemValue(sema.mod, i);
3905638873 const rhs_elem = try rhs.elemValue(sema.mod, i);
3905738874 const res_bool = try sema.compareScalar(lhs_elem, op, rhs_elem, ty.scalarType(mod));
39058 scalar.* = try Value.makeBool(res_bool).intern(Type.bool, mod);
38875 scalar.* = Value.makeBool(res_bool).toIntern();
3905938876 }
3906038877 return Value.fromInterned((try mod.intern(.{ .aggregate = .{
3906138878 .ty = (try mod.vectorType(.{ .len = ty.vectorLen(mod), .child = .bool_type })).toIntern(),
......@@ -39232,45 +39049,22 @@ fn validateRuntimeValue(sema: *Sema, block: *Block, val_src: LazySrcLoc, val: Ai
3923239049}
3923339050
3923439051/// Returns true if any value contained in `val` is undefined.
39235fn anyUndef(sema: *Sema, val: Value) !bool {
39052fn anyUndef(sema: *Sema, block: *Block, src: LazySrcLoc, val: Value) !bool {
3923639053 const mod = sema.mod;
39237 if (val.ip_index == .none) return switch (val.tag()) {
39238 .eu_payload => try sema.anyUndef(val.castTag(.eu_payload).?.data),
39239 .opt_payload => try sema.anyUndef(val.castTag(.opt_payload).?.data),
39240 .repeated => try sema.anyUndef(val.castTag(.repeated).?.data),
39054 return switch (mod.intern_pool.indexToKey(val.toIntern())) {
39055 .undef => true,
39056 .simple_value => |v| v == .undefined,
3924139057 .slice => {
39242 const slice = val.castTag(.slice).?.data;
39243 for (0..@intCast(slice.len.toUnsignedInt(mod))) |idx| {
39244 if (try sema.anyUndef((try slice.ptr.maybeElemValueFull(sema, mod, idx)).?)) return true;
39245 }
39246 return false;
39247 },
39248 .bytes => false,
39249 .aggregate => for (val.castTag(.aggregate).?.data) |elem| {
39250 if (try sema.anyUndef(elem)) break true;
39058 // If the slice contents are runtime-known, reification will fail later on with a
39059 // specific error message.
39060 const arr = try sema.maybeDerefSliceAsArray(block, src, val) orelse return false;
39061 return sema.anyUndef(block, src, arr);
39062 },
39063 .aggregate => |aggregate| for (0..aggregate.storage.values().len) |i| {
39064 const elem = mod.intern_pool.indexToKey(val.toIntern()).aggregate.storage.values()[i];
39065 if (try sema.anyUndef(block, src, Value.fromInterned(elem))) break true;
3925139066 } else false,
39252 .@"union" => {
39253 const un = val.castTag(.@"union").?.data;
39254 if (un.tag) |t| {
39255 if (try sema.anyUndef(t)) return true;
39256 }
39257 return sema.anyUndef(un.val);
39258 },
39259 };
39260 return switch (val.toIntern()) {
39261 .undef => true,
39262 else => switch (mod.intern_pool.indexToKey(val.toIntern())) {
39263 .undef => true,
39264 .simple_value => |v| v == .undefined,
39265 .slice => |slice| for (0..@intCast(Value.fromInterned(slice.len).toUnsignedInt(mod))) |idx| {
39266 if (try sema.anyUndef((try val.maybeElemValueFull(sema, mod, idx)).?)) break true;
39267 } else false,
39268 .aggregate => |aggregate| for (0..aggregate.storage.values().len) |i| {
39269 const elem = mod.intern_pool.indexToKey(val.toIntern()).aggregate.storage.values()[i];
39270 if (try sema.anyUndef(Value.fromInterned(elem))) break true;
39271 } else false,
39272 else => false,
39273 },
39067 else => false,
3927439068 };
3927539069}
3927639070
......@@ -39283,12 +39077,11 @@ fn sliceToIpString(
3928339077 reason: NeededComptimeReason,
3928439078) CompileError!InternPool.NullTerminatedString {
3928539079 const zcu = sema.mod;
39286 const ip = &zcu.intern_pool;
39287 const slice_ty = Type.fromInterned(ip.typeOf(slice_val.toIntern()));
39080 const slice_ty = slice_val.typeOf(zcu);
3928839081 assert(slice_ty.isSlice(zcu));
3928939082 assert(slice_ty.childType(zcu).toIntern() == .u8_type);
3929039083 const array_val = try sema.derefSliceAsArray(block, src, slice_val, reason);
39291 const array_ty = Type.fromInterned(ip.typeOf(array_val.toIntern()));
39084 const array_ty = array_val.typeOf(zcu);
3929239085 return array_val.toIpString(array_ty, zcu);
3929339086}
3929439087
......@@ -39302,9 +39095,23 @@ fn derefSliceAsArray(
3930239095 slice_val: Value,
3930339096 reason: NeededComptimeReason,
3930439097) CompileError!Value {
39098 return try sema.maybeDerefSliceAsArray(block, src, slice_val) orelse {
39099 return sema.failWithNeededComptime(block, src, reason);
39100 };
39101}
39102
39103/// Given a slice value, attempts to dereference it into a comptime-known array.
39104/// Returns `null` if the contents of the slice are not comptime-known.
39105/// Asserts that `slice_val` is a slice.
39106fn maybeDerefSliceAsArray(
39107 sema: *Sema,
39108 block: *Block,
39109 src: LazySrcLoc,
39110 slice_val: Value,
39111) CompileError!?Value {
3930539112 const zcu = sema.mod;
3930639113 const ip = &zcu.intern_pool;
39307 assert(Type.fromInterned(ip.typeOf(slice_val.toIntern())).isSlice(zcu));
39114 assert(slice_val.typeOf(zcu).isSlice(zcu));
3930839115 const slice = switch (ip.indexToKey(slice_val.toIntern())) {
3930939116 .undef => return sema.failWithUseOfUndef(block, src),
3931039117 .slice => |slice| slice,
......@@ -39324,7 +39131,5 @@ fn derefSliceAsArray(
3932439131 break :p p;
3932539132 });
3932639133 const casted_ptr = try zcu.getCoerced(Value.fromInterned(slice.ptr), ptr_ty);
39327 return try sema.pointerDeref(block, src, casted_ptr, ptr_ty) orelse {
39328 return sema.failWithNeededComptime(block, src, reason);
39329 };
39134 return sema.pointerDeref(block, src, casted_ptr, ptr_ty);
3933039135}
src/TypedValue.zig deleted-528
......@@ -1,528 +0,0 @@
1const std = @import("std");
2const Type = @import("type.zig").Type;
3const Value = @import("Value.zig");
4const Module = @import("Module.zig");
5const Allocator = std.mem.Allocator;
6const TypedValue = @This();
7const Target = std.Target;
8
9ty: Type,
10val: Value,
11
12/// Memory management for TypedValue. The main purpose of this type
13/// is to be small and have a deinit() function to free associated resources.
14pub const Managed = struct {
15 /// If the tag value is less than Tag.no_payload_count, then no pointer
16 /// dereference is needed.
17 typed_value: TypedValue,
18 /// If this is `null` then there is no memory management needed.
19 arena: ?*std.heap.ArenaAllocator.State = null,
20
21 pub fn deinit(self: *Managed, allocator: Allocator) void {
22 if (self.arena) |a| a.promote(allocator).deinit();
23 self.* = undefined;
24 }
25};
26
27/// Assumes arena allocation. Does a recursive copy.
28pub fn copy(self: TypedValue, arena: Allocator) error{OutOfMemory}!TypedValue {
29 return TypedValue{
30 .ty = self.ty,
31 .val = try self.val.copy(arena),
32 };
33}
34
35pub fn eql(a: TypedValue, b: TypedValue, mod: *Module) bool {
36 if (a.ty.toIntern() != b.ty.toIntern()) return false;
37 return a.val.eql(b.val, a.ty, mod);
38}
39
40pub fn hash(tv: TypedValue, hasher: *std.hash.Wyhash, mod: *Module) void {
41 return tv.val.hash(tv.ty, hasher, mod);
42}
43
44pub fn intFromEnum(tv: TypedValue, mod: *Module) Allocator.Error!Value {
45 return tv.val.intFromEnum(tv.ty, mod);
46}
47
48const max_aggregate_items = 100;
49const max_string_len = 256;
50
51const FormatContext = struct {
52 tv: TypedValue,
53 mod: *Module,
54};
55
56pub fn format(
57 ctx: FormatContext,
58 comptime fmt: []const u8,
59 options: std.fmt.FormatOptions,
60 writer: anytype,
61) !void {
62 _ = options;
63 comptime std.debug.assert(fmt.len == 0);
64 return ctx.tv.print(writer, 3, ctx.mod) catch |err| switch (err) {
65 error.OutOfMemory => @panic("OOM"), // We're not allowed to return this from a format function
66 else => |e| return e,
67 };
68}
69
70/// Prints the Value according to the Type, not according to the Value Tag.
71pub fn print(
72 tv: TypedValue,
73 writer: anytype,
74 level: u8,
75 mod: *Module,
76) (@TypeOf(writer).Error || Allocator.Error)!void {
77 var val = tv.val;
78 var ty = tv.ty;
79 const ip = &mod.intern_pool;
80 while (true) switch (val.ip_index) {
81 .none => switch (val.tag()) {
82 .aggregate => return printAggregate(ty, val, writer, level, mod),
83 .@"union" => {
84 if (level == 0) {
85 return writer.writeAll(".{ ... }");
86 }
87 const payload = val.castTag(.@"union").?.data;
88 try writer.writeAll(".{ ");
89
90 if (payload.tag) |tag| {
91 try print(.{
92 .ty = Type.fromInterned(ip.loadUnionType(ty.toIntern()).enum_tag_ty),
93 .val = tag,
94 }, writer, level - 1, mod);
95 try writer.writeAll(" = ");
96 const field_ty = ty.unionFieldType(tag, mod).?;
97 try print(.{
98 .ty = field_ty,
99 .val = payload.val,
100 }, writer, level - 1, mod);
101 } else {
102 try writer.writeAll("(unknown tag) = ");
103 const backing_ty = try ty.unionBackingType(mod);
104 try print(.{
105 .ty = backing_ty,
106 .val = payload.val,
107 }, writer, level - 1, mod);
108 }
109
110 return writer.writeAll(" }");
111 },
112 .bytes => return writer.print("\"{}\"", .{std.zig.fmtEscapes(val.castTag(.bytes).?.data)}),
113 .repeated => {
114 if (level == 0) {
115 return writer.writeAll(".{ ... }");
116 }
117 var i: u32 = 0;
118 try writer.writeAll(".{ ");
119 const elem_tv = TypedValue{
120 .ty = ty.elemType2(mod),
121 .val = val.castTag(.repeated).?.data,
122 };
123 const len = ty.arrayLen(mod);
124 const max_len = @min(len, max_aggregate_items);
125 while (i < max_len) : (i += 1) {
126 if (i != 0) try writer.writeAll(", ");
127 try print(elem_tv, writer, level - 1, mod);
128 }
129 if (len > max_aggregate_items) {
130 try writer.writeAll(", ...");
131 }
132 return writer.writeAll(" }");
133 },
134 .slice => {
135 if (level == 0) {
136 return writer.writeAll(".{ ... }");
137 }
138 const payload = val.castTag(.slice).?.data;
139 const elem_ty = ty.elemType2(mod);
140 const len = payload.len.toUnsignedInt(mod);
141
142 if (elem_ty.eql(Type.u8, mod)) str: {
143 const max_len: usize = @min(len, max_string_len);
144 var buf: [max_string_len]u8 = undefined;
145
146 var i: u32 = 0;
147 while (i < max_len) : (i += 1) {
148 const maybe_elem_val = payload.ptr.maybeElemValue(mod, i) catch |err| switch (err) {
149 error.OutOfMemory => @panic("OOM"), // TODO: eliminate this panic
150 };
151 const elem_val = maybe_elem_val orelse return writer.writeAll(".{ (reinterpreted data) }");
152 if (elem_val.isUndef(mod)) break :str;
153 buf[i] = std.math.cast(u8, elem_val.toUnsignedInt(mod)) orelse break :str;
154 }
155
156 // TODO would be nice if this had a bit of unicode awareness.
157 const truncated = if (len > max_string_len) " (truncated)" else "";
158 return writer.print("\"{}{s}\"", .{ std.zig.fmtEscapes(buf[0..max_len]), truncated });
159 }
160
161 try writer.writeAll(".{ ");
162
163 const max_len = @min(len, max_aggregate_items);
164 var i: u32 = 0;
165 while (i < max_len) : (i += 1) {
166 if (i != 0) try writer.writeAll(", ");
167 const maybe_elem_val = payload.ptr.maybeElemValue(mod, i) catch |err| switch (err) {
168 error.OutOfMemory => @panic("OOM"), // TODO: eliminate this panic
169 };
170 const elem_val = maybe_elem_val orelse return writer.writeAll("(reinterpreted data) }");
171 try print(.{
172 .ty = elem_ty,
173 .val = elem_val,
174 }, writer, level - 1, mod);
175 }
176 if (len > max_aggregate_items) {
177 try writer.writeAll(", ...");
178 }
179 return writer.writeAll(" }");
180 },
181 .eu_payload => {
182 val = val.castTag(.eu_payload).?.data;
183 ty = ty.errorUnionPayload(mod);
184 },
185 .opt_payload => {
186 val = val.castTag(.opt_payload).?.data;
187 ty = ty.optionalChild(mod);
188 },
189 },
190 else => switch (ip.indexToKey(val.toIntern())) {
191 .int_type,
192 .ptr_type,
193 .array_type,
194 .vector_type,
195 .opt_type,
196 .anyframe_type,
197 .error_union_type,
198 .simple_type,
199 .struct_type,
200 .anon_struct_type,
201 .union_type,
202 .opaque_type,
203 .enum_type,
204 .func_type,
205 .error_set_type,
206 .inferred_error_set_type,
207 => return Type.print(val.toType(), writer, mod),
208 .undef => return writer.writeAll("undefined"),
209 .simple_value => |simple_value| switch (simple_value) {
210 .void => return writer.writeAll("{}"),
211 .empty_struct => return printAggregate(ty, val, writer, level, mod),
212 .generic_poison => return writer.writeAll("(generic poison)"),
213 else => return writer.writeAll(@tagName(simple_value)),
214 },
215 .variable => return writer.writeAll("(variable)"),
216 .extern_func => |extern_func| return writer.print("(extern function '{}')", .{
217 mod.declPtr(extern_func.decl).name.fmt(ip),
218 }),
219 .func => |func| return writer.print("(function '{}')", .{
220 mod.declPtr(func.owner_decl).name.fmt(ip),
221 }),
222 .int => |int| switch (int.storage) {
223 inline .u64, .i64, .big_int => |x| return writer.print("{}", .{x}),
224 .lazy_align => |lazy_ty| return writer.print("{d}", .{
225 Type.fromInterned(lazy_ty).abiAlignment(mod),
226 }),
227 .lazy_size => |lazy_ty| return writer.print("{d}", .{
228 Type.fromInterned(lazy_ty).abiSize(mod),
229 }),
230 },
231 .err => |err| return writer.print("error.{}", .{
232 err.name.fmt(ip),
233 }),
234 .error_union => |error_union| switch (error_union.val) {
235 .err_name => |err_name| return writer.print("error.{}", .{
236 err_name.fmt(ip),
237 }),
238 .payload => |payload| {
239 val = Value.fromInterned(payload);
240 ty = ty.errorUnionPayload(mod);
241 },
242 },
243 .enum_literal => |enum_literal| return writer.print(".{}", .{
244 enum_literal.fmt(ip),
245 }),
246 .enum_tag => |enum_tag| {
247 if (level == 0) {
248 return writer.writeAll("(enum)");
249 }
250 const enum_type = ip.loadEnumType(ty.toIntern());
251 if (enum_type.tagValueIndex(ip, val.toIntern())) |tag_index| {
252 try writer.print(".{i}", .{enum_type.names.get(ip)[tag_index].fmt(ip)});
253 return;
254 }
255 try writer.writeAll("@enumFromInt(");
256 try print(.{
257 .ty = Type.fromInterned(ip.typeOf(enum_tag.int)),
258 .val = Value.fromInterned(enum_tag.int),
259 }, writer, level - 1, mod);
260 try writer.writeAll(")");
261 return;
262 },
263 .empty_enum_value => return writer.writeAll("(empty enum value)"),
264 .float => |float| switch (float.storage) {
265 inline else => |x| return writer.print("{d}", .{@as(f64, @floatCast(x))}),
266 },
267 .slice => |slice| {
268 const ptr_ty = switch (ip.indexToKey(slice.ptr)) {
269 .ptr => |ptr| ty: {
270 if (ptr.addr == .int) return print(.{
271 .ty = Type.fromInterned(ptr.ty),
272 .val = Value.fromInterned(slice.ptr),
273 }, writer, level - 1, mod);
274 break :ty ip.indexToKey(ptr.ty).ptr_type;
275 },
276 .undef => |ptr_ty| ip.indexToKey(ptr_ty).ptr_type,
277 else => unreachable,
278 };
279 if (level == 0) {
280 return writer.writeAll(".{ ... }");
281 }
282 const elem_ty = Type.fromInterned(ptr_ty.child);
283 const len = Value.fromInterned(slice.len).toUnsignedInt(mod);
284 if (elem_ty.eql(Type.u8, mod)) str: {
285 const max_len = @min(len, max_string_len);
286 var buf: [max_string_len]u8 = undefined;
287 for (buf[0..max_len], 0..) |*c, i| {
288 const maybe_elem = try val.maybeElemValue(mod, i);
289 const elem = maybe_elem orelse return writer.writeAll(".{ (reinterpreted data) }");
290 if (elem.isUndef(mod)) break :str;
291 c.* = @as(u8, @intCast(elem.toUnsignedInt(mod)));
292 }
293 const truncated = if (len > max_string_len) " (truncated)" else "";
294 return writer.print("\"{}{s}\"", .{ std.zig.fmtEscapes(buf[0..max_len]), truncated });
295 }
296 try writer.writeAll(".{ ");
297 const max_len = @min(len, max_aggregate_items);
298 for (0..max_len) |i| {
299 if (i != 0) try writer.writeAll(", ");
300 const maybe_elem = try val.maybeElemValue(mod, i);
301 const elem = maybe_elem orelse return writer.writeAll("(reinterpreted data) }");
302 try print(.{
303 .ty = elem_ty,
304 .val = elem,
305 }, writer, level - 1, mod);
306 }
307 if (len > max_aggregate_items) {
308 try writer.writeAll(", ...");
309 }
310 return writer.writeAll(" }");
311 },
312 .ptr => |ptr| {
313 switch (ptr.addr) {
314 .decl => |decl_index| {
315 const decl = mod.declPtr(decl_index);
316 if (level == 0) return writer.print("(decl '{}')", .{decl.name.fmt(ip)});
317 return print(.{
318 .ty = decl.ty,
319 .val = decl.val,
320 }, writer, level - 1, mod);
321 },
322 .anon_decl => |anon_decl| {
323 const decl_val = anon_decl.val;
324 if (level == 0) return writer.print("(anon decl '{d}')", .{
325 @intFromEnum(decl_val),
326 });
327 return print(.{
328 .ty = Type.fromInterned(ip.typeOf(decl_val)),
329 .val = Value.fromInterned(decl_val),
330 }, writer, level - 1, mod);
331 },
332 .comptime_alloc => {
333 // TODO: we need a Sema to print this!
334 return writer.writeAll("(comptime alloc)");
335 },
336 .comptime_field => |field_val_ip| {
337 return print(.{
338 .ty = Type.fromInterned(ip.typeOf(field_val_ip)),
339 .val = Value.fromInterned(field_val_ip),
340 }, writer, level - 1, mod);
341 },
342 .int => |int_ip| {
343 try writer.writeAll("@ptrFromInt(");
344 try print(.{
345 .ty = Type.usize,
346 .val = Value.fromInterned(int_ip),
347 }, writer, level - 1, mod);
348 try writer.writeByte(')');
349 },
350 .eu_payload => |eu_ip| {
351 try writer.writeAll("(payload of ");
352 try print(.{
353 .ty = Type.fromInterned(ip.typeOf(eu_ip)),
354 .val = Value.fromInterned(eu_ip),
355 }, writer, level - 1, mod);
356 try writer.writeAll(")");
357 },
358 .opt_payload => |opt_ip| {
359 try print(.{
360 .ty = Type.fromInterned(ip.typeOf(opt_ip)),
361 .val = Value.fromInterned(opt_ip),
362 }, writer, level - 1, mod);
363 try writer.writeAll(".?");
364 },
365 .elem => |elem| {
366 if (level == 0) {
367 try writer.writeAll("(...)");
368 } else {
369 try print(.{
370 .ty = Type.fromInterned(ip.typeOf(elem.base)),
371 .val = Value.fromInterned(elem.base),
372 }, writer, level - 1, mod);
373 }
374 try writer.print("[{}]", .{elem.index});
375 },
376 .field => |field| {
377 const ptr_container_ty = Type.fromInterned(ip.typeOf(field.base));
378 if (level == 0) {
379 try writer.writeAll("(...)");
380 } else {
381 try print(.{
382 .ty = ptr_container_ty,
383 .val = Value.fromInterned(field.base),
384 }, writer, level - 1, mod);
385 }
386
387 const container_ty = ptr_container_ty.childType(mod);
388 switch (container_ty.zigTypeTag(mod)) {
389 .Struct => {
390 if (container_ty.structFieldName(@intCast(field.index), mod).unwrap()) |field_name| {
391 try writer.print(".{i}", .{field_name.fmt(ip)});
392 } else {
393 try writer.print("[{d}]", .{field.index});
394 }
395 },
396 .Union => {
397 const field_name = mod.typeToUnion(container_ty).?.loadTagType(ip).names.get(ip)[@intCast(field.index)];
398 try writer.print(".{i}", .{field_name.fmt(ip)});
399 },
400 .Pointer => {
401 std.debug.assert(container_ty.isSlice(mod));
402 try writer.writeAll(switch (field.index) {
403 Value.slice_ptr_index => ".ptr",
404 Value.slice_len_index => ".len",
405 else => unreachable,
406 });
407 },
408 else => unreachable,
409 }
410 },
411 }
412 return;
413 },
414 .opt => |opt| switch (opt.val) {
415 .none => return writer.writeAll("null"),
416 else => |payload| {
417 val = Value.fromInterned(payload);
418 ty = ty.optionalChild(mod);
419 },
420 },
421 .aggregate => |aggregate| switch (aggregate.storage) {
422 .bytes => |bytes| {
423 // Strip the 0 sentinel off of strings before printing
424 const zero_sent = blk: {
425 const sent = ty.sentinel(mod) orelse break :blk false;
426 break :blk sent.eql(Value.zero_u8, Type.u8, mod);
427 };
428 const str = if (zero_sent) bytes[0 .. bytes.len - 1] else bytes;
429 return writer.print("\"{}\"", .{std.zig.fmtEscapes(str)});
430 },
431 .elems, .repeated_elem => return printAggregate(ty, val, writer, level, mod),
432 },
433 .un => |un| {
434 try writer.writeAll(".{ ");
435 if (level > 0) {
436 if (un.tag != .none) {
437 try print(.{
438 .ty = ty.unionTagTypeHypothetical(mod),
439 .val = Value.fromInterned(un.tag),
440 }, writer, level - 1, mod);
441 try writer.writeAll(" = ");
442 const field_ty = ty.unionFieldType(Value.fromInterned(un.tag), mod).?;
443 try print(.{
444 .ty = field_ty,
445 .val = Value.fromInterned(un.val),
446 }, writer, level - 1, mod);
447 } else {
448 try writer.writeAll("(unknown tag) = ");
449 const backing_ty = try ty.unionBackingType(mod);
450 try print(.{
451 .ty = backing_ty,
452 .val = Value.fromInterned(un.val),
453 }, writer, level - 1, mod);
454 }
455 } else try writer.writeAll("...");
456 return writer.writeAll(" }");
457 },
458 .memoized_call => unreachable,
459 },
460 };
461}
462
463fn printAggregate(
464 ty: Type,
465 val: Value,
466 writer: anytype,
467 level: u8,
468 mod: *Module,
469) (@TypeOf(writer).Error || Allocator.Error)!void {
470 if (level == 0) {
471 return writer.writeAll(".{ ... }");
472 }
473 const ip = &mod.intern_pool;
474 if (ty.zigTypeTag(mod) == .Struct) {
475 try writer.writeAll(".{");
476 const max_len = @min(ty.structFieldCount(mod), max_aggregate_items);
477
478 for (0..max_len) |i| {
479 if (i != 0) try writer.writeAll(", ");
480
481 const field_name = ty.structFieldName(@intCast(i), mod);
482
483 if (field_name.unwrap()) |name| try writer.print(".{} = ", .{name.fmt(ip)});
484 try print(.{
485 .ty = ty.structFieldType(i, mod),
486 .val = try val.fieldValue(mod, i),
487 }, writer, level - 1, mod);
488 }
489 if (ty.structFieldCount(mod) > max_aggregate_items) {
490 try writer.writeAll(", ...");
491 }
492 return writer.writeAll("}");
493 } else {
494 const elem_ty = ty.elemType2(mod);
495 const len = ty.arrayLen(mod);
496
497 if (elem_ty.eql(Type.u8, mod)) str: {
498 const max_len: usize = @min(len, max_string_len);
499 var buf: [max_string_len]u8 = undefined;
500
501 var i: u32 = 0;
502 while (i < max_len) : (i += 1) {
503 const elem = try val.fieldValue(mod, i);
504 if (elem.isUndef(mod)) break :str;
505 buf[i] = std.math.cast(u8, elem.toUnsignedInt(mod)) orelse break :str;
506 }
507
508 const truncated = if (len > max_string_len) " (truncated)" else "";
509 return writer.print("\"{}{s}\"", .{ std.zig.fmtEscapes(buf[0..max_len]), truncated });
510 }
511
512 try writer.writeAll(".{ ");
513
514 const max_len = @min(len, max_aggregate_items);
515 var i: u32 = 0;
516 while (i < max_len) : (i += 1) {
517 if (i != 0) try writer.writeAll(", ");
518 try print(.{
519 .ty = elem_ty,
520 .val = try val.fieldValue(mod, i),
521 }, writer, level - 1, mod);
522 }
523 if (len > max_aggregate_items) {
524 try writer.writeAll(", ...");
525 }
526 return writer.writeAll(" }");
527 }
528}
src/Value.zig+174-647
......@@ -8,129 +8,13 @@ const Target = std.Target;
88const Allocator = std.mem.Allocator;
99const Zcu = @import("Module.zig");
1010const Module = Zcu;
11const TypedValue = @import("TypedValue.zig");
1211const Sema = @import("Sema.zig");
1312const InternPool = @import("InternPool.zig");
13const print_value = @import("print_value.zig");
1414const Value = @This();
1515
16/// We are migrating towards using this for every Value object. However, many
17/// values are still represented the legacy way. This is indicated by using
18/// InternPool.Index.none.
1916ip_index: InternPool.Index,
2017
21/// This is the raw data, with no bookkeeping, no memory awareness,
22/// no de-duplication, and no type system awareness.
23/// This union takes advantage of the fact that the first page of memory
24/// is unmapped, giving us 4096 possible enum tags that have no payload.
25legacy: extern union {
26 ptr_otherwise: *Payload,
27},
28
29// Keep in sync with tools/stage2_pretty_printers_common.py
30pub const Tag = enum(usize) {
31 // The first section of this enum are tags that require no payload.
32 // After this, the tag requires a payload.
33
34 /// When the type is error union:
35 /// * If the tag is `.@"error"`, the error union is an error.
36 /// * If the tag is `.eu_payload`, the error union is a payload.
37 /// * A nested error such as `anyerror!(anyerror!T)` in which the the outer error union
38 /// is non-error, but the inner error union is an error, is represented as
39 /// a tag of `.eu_payload`, with a sub-tag of `.@"error"`.
40 eu_payload,
41 /// When the type is optional:
42 /// * If the tag is `.null_value`, the optional is null.
43 /// * If the tag is `.opt_payload`, the optional is a payload.
44 /// * A nested optional such as `??T` in which the the outer optional
45 /// is non-null, but the inner optional is null, is represented as
46 /// a tag of `.opt_payload`, with a sub-tag of `.null_value`.
47 opt_payload,
48 /// Pointer and length as sub `Value` objects.
49 slice,
50 /// A slice of u8 whose memory is managed externally.
51 bytes,
52 /// This value is repeated some number of times. The amount of times to repeat
53 /// is stored externally.
54 repeated,
55 /// An instance of a struct, array, or vector.
56 /// Each element/field stored as a `Value`.
57 /// In the case of sentinel-terminated arrays, the sentinel value *is* stored,
58 /// so the slice length will be one more than the type's array length.
59 aggregate,
60 /// An instance of a union.
61 @"union",
62
63 pub fn Type(comptime t: Tag) type {
64 return switch (t) {
65 .eu_payload,
66 .opt_payload,
67 .repeated,
68 => Payload.SubValue,
69 .slice => Payload.Slice,
70 .bytes => Payload.Bytes,
71 .aggregate => Payload.Aggregate,
72 .@"union" => Payload.Union,
73 };
74 }
75
76 pub fn create(comptime t: Tag, ally: Allocator, data: Data(t)) error{OutOfMemory}!Value {
77 const ptr = try ally.create(t.Type());
78 ptr.* = .{
79 .base = .{ .tag = t },
80 .data = data,
81 };
82 return Value{
83 .ip_index = .none,
84 .legacy = .{ .ptr_otherwise = &ptr.base },
85 };
86 }
87
88 pub fn Data(comptime t: Tag) type {
89 return std.meta.fieldInfo(t.Type(), .data).type;
90 }
91};
92
93pub fn initPayload(payload: *Payload) Value {
94 return Value{
95 .ip_index = .none,
96 .legacy = .{ .ptr_otherwise = payload },
97 };
98}
99
100pub fn tag(self: Value) Tag {
101 assert(self.ip_index == .none);
102 return self.legacy.ptr_otherwise.tag;
103}
104
105/// Prefer `castTag` to this.
106pub fn cast(self: Value, comptime T: type) ?*T {
107 if (self.ip_index != .none) {
108 return null;
109 }
110 if (@hasField(T, "base_tag")) {
111 return self.castTag(T.base_tag);
112 }
113 inline for (@typeInfo(Tag).Enum.fields) |field| {
114 const t = @as(Tag, @enumFromInt(field.value));
115 if (self.legacy.ptr_otherwise.tag == t) {
116 if (T == t.Type()) {
117 return @fieldParentPtr(T, "base", self.legacy.ptr_otherwise);
118 }
119 return null;
120 }
121 }
122 unreachable;
123}
124
125pub fn castTag(self: Value, comptime t: Tag) ?*t.Type() {
126 if (self.ip_index != .none) return null;
127
128 if (self.legacy.ptr_otherwise.tag == t)
129 return @fieldParentPtr(t.Type(), "base", self.legacy.ptr_otherwise);
130
131 return null;
132}
133
13418pub fn format(val: Value, comptime fmt: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void {
13519 _ = val;
13620 _ = fmt;
......@@ -148,42 +32,16 @@ pub fn dump(
14832 out_stream: anytype,
14933) !void {
15034 comptime assert(fmt.len == 0);
151 if (start_val.ip_index != .none) {
152 try out_stream.print("(interned: {})", .{start_val.toIntern()});
153 return;
154 }
155 var val = start_val;
156 while (true) switch (val.tag()) {
157 .aggregate => {
158 return out_stream.writeAll("(aggregate)");
159 },
160 .@"union" => {
161 return out_stream.writeAll("(union value)");
162 },
163 .bytes => return out_stream.print("\"{}\"", .{std.zig.fmtEscapes(val.castTag(.bytes).?.data)}),
164 .repeated => {
165 try out_stream.writeAll("(repeated) ");
166 val = val.castTag(.repeated).?.data;
167 },
168 .eu_payload => {
169 try out_stream.writeAll("(eu_payload) ");
170 val = val.castTag(.repeated).?.data;
171 },
172 .opt_payload => {
173 try out_stream.writeAll("(opt_payload) ");
174 val = val.castTag(.repeated).?.data;
175 },
176 .slice => return out_stream.writeAll("(slice)"),
177 };
35 try out_stream.print("(interned: {})", .{start_val.toIntern()});
17836}
17937
18038pub fn fmtDebug(val: Value) std.fmt.Formatter(dump) {
18139 return .{ .data = val };
18240}
18341
184pub fn fmtValue(val: Value, ty: Type, mod: *Module) std.fmt.Formatter(TypedValue.format) {
42pub fn fmtValue(val: Value, mod: *Module) std.fmt.Formatter(print_value.format) {
18543 return .{ .data = .{
186 .tv = .{ .ty = ty, .val = val },
44 .val = val,
18745 .mod = mod,
18846 } };
18947}
......@@ -252,162 +110,9 @@ fn arrayToIpString(val: Value, len_u64: u64, mod: *Module) !InternPool.NullTermi
252110 return ip.getOrPutTrailingString(gpa, len);
253111}
254112
255pub fn intern2(val: Value, ty: Type, mod: *Module) Allocator.Error!InternPool.Index {
256 if (val.ip_index != .none) return val.ip_index;
257 return intern(val, ty, mod);
258}
259
260pub fn intern(val: Value, ty: Type, mod: *Module) Allocator.Error!InternPool.Index {
261 if (val.ip_index != .none) return (try mod.getCoerced(val, ty)).toIntern();
262 const ip = &mod.intern_pool;
263 switch (val.tag()) {
264 .eu_payload => {
265 const pl = val.castTag(.eu_payload).?.data;
266 return mod.intern(.{ .error_union = .{
267 .ty = ty.toIntern(),
268 .val = .{ .payload = try pl.intern(ty.errorUnionPayload(mod), mod) },
269 } });
270 },
271 .opt_payload => {
272 const pl = val.castTag(.opt_payload).?.data;
273 return mod.intern(.{ .opt = .{
274 .ty = ty.toIntern(),
275 .val = try pl.intern(ty.optionalChild(mod), mod),
276 } });
277 },
278 .slice => {
279 const pl = val.castTag(.slice).?.data;
280 return mod.intern(.{ .slice = .{
281 .ty = ty.toIntern(),
282 .len = try pl.len.intern(Type.usize, mod),
283 .ptr = try pl.ptr.intern(ty.slicePtrFieldType(mod), mod),
284 } });
285 },
286 .bytes => {
287 const pl = val.castTag(.bytes).?.data;
288 return mod.intern(.{ .aggregate = .{
289 .ty = ty.toIntern(),
290 .storage = .{ .bytes = pl },
291 } });
292 },
293 .repeated => {
294 const pl = val.castTag(.repeated).?.data;
295 return mod.intern(.{ .aggregate = .{
296 .ty = ty.toIntern(),
297 .storage = .{ .repeated_elem = try pl.intern(ty.childType(mod), mod) },
298 } });
299 },
300 .aggregate => {
301 const len = @as(usize, @intCast(ty.arrayLen(mod)));
302 const old_elems = val.castTag(.aggregate).?.data[0..len];
303 const new_elems = try mod.gpa.alloc(InternPool.Index, old_elems.len);
304 defer mod.gpa.free(new_elems);
305 const ty_key = ip.indexToKey(ty.toIntern());
306 for (new_elems, old_elems, 0..) |*new_elem, old_elem, field_i|
307 new_elem.* = try old_elem.intern(switch (ty_key) {
308 .struct_type => ty.structFieldType(field_i, mod),
309 .anon_struct_type => |info| Type.fromInterned(info.types.get(ip)[field_i]),
310 inline .array_type, .vector_type => |info| Type.fromInterned(info.child),
311 else => unreachable,
312 }, mod);
313 return mod.intern(.{ .aggregate = .{
314 .ty = ty.toIntern(),
315 .storage = .{ .elems = new_elems },
316 } });
317 },
318 .@"union" => {
319 const pl = val.castTag(.@"union").?.data;
320 if (pl.tag) |pl_tag| {
321 return mod.intern(.{ .un = .{
322 .ty = ty.toIntern(),
323 .tag = try pl_tag.intern(ty.unionTagTypeHypothetical(mod), mod),
324 .val = try pl.val.intern(ty.unionFieldType(pl_tag, mod).?, mod),
325 } });
326 } else {
327 return mod.intern(.{ .un = .{
328 .ty = ty.toIntern(),
329 .tag = .none,
330 .val = try pl.val.intern(try ty.unionBackingType(mod), mod),
331 } });
332 }
333 },
334 }
335}
336
337pub fn unintern(val: Value, arena: Allocator, mod: *Module) Allocator.Error!Value {
338 return if (val.ip_index == .none) val else switch (mod.intern_pool.indexToKey(val.toIntern())) {
339 .int_type,
340 .ptr_type,
341 .array_type,
342 .vector_type,
343 .opt_type,
344 .anyframe_type,
345 .error_union_type,
346 .simple_type,
347 .struct_type,
348 .anon_struct_type,
349 .union_type,
350 .opaque_type,
351 .enum_type,
352 .func_type,
353 .error_set_type,
354 .inferred_error_set_type,
355
356 .undef,
357 .simple_value,
358 .variable,
359 .extern_func,
360 .func,
361 .int,
362 .err,
363 .enum_literal,
364 .enum_tag,
365 .empty_enum_value,
366 .float,
367 .ptr,
368 => val,
369
370 .error_union => |error_union| switch (error_union.val) {
371 .err_name => val,
372 .payload => |payload| Tag.eu_payload.create(arena, Value.fromInterned(payload)),
373 },
374
375 .slice => |slice| Tag.slice.create(arena, .{
376 .ptr = Value.fromInterned(slice.ptr),
377 .len = Value.fromInterned(slice.len),
378 }),
379
380 .opt => |opt| switch (opt.val) {
381 .none => val,
382 else => |payload| Tag.opt_payload.create(arena, Value.fromInterned(payload)),
383 },
384
385 .aggregate => |aggregate| switch (aggregate.storage) {
386 .bytes => |bytes| Tag.bytes.create(arena, try arena.dupe(u8, bytes)),
387 .elems => |old_elems| {
388 const new_elems = try arena.alloc(Value, old_elems.len);
389 for (new_elems, old_elems) |*new_elem, old_elem| new_elem.* = Value.fromInterned(old_elem);
390 return Tag.aggregate.create(arena, new_elems);
391 },
392 .repeated_elem => |elem| Tag.repeated.create(arena, Value.fromInterned(elem)),
393 },
394
395 .un => |un| Tag.@"union".create(arena, .{
396 // toValue asserts that the value cannot be .none which is valid on unions.
397 .tag = if (un.tag == .none) null else Value.fromInterned(un.tag),
398 .val = Value.fromInterned(un.val),
399 }),
400
401 .memoized_call => unreachable,
402 };
403}
404
405113pub fn fromInterned(i: InternPool.Index) Value {
406114 assert(i != .none);
407 return .{
408 .ip_index = i,
409 .legacy = undefined,
410 };
115 return .{ .ip_index = i };
411116}
412117
413118pub fn toIntern(val: Value) InternPool.Index {
......@@ -492,24 +197,24 @@ pub fn isFuncBody(val: Value, mod: *Module) bool {
492197}
493198
494199pub fn getFunction(val: Value, mod: *Module) ?InternPool.Key.Func {
495 return if (val.ip_index != .none) switch (mod.intern_pool.indexToKey(val.toIntern())) {
200 return switch (mod.intern_pool.indexToKey(val.toIntern())) {
496201 .func => |x| x,
497202 else => null,
498 } else null;
203 };
499204}
500205
501206pub fn getExternFunc(val: Value, mod: *Module) ?InternPool.Key.ExternFunc {
502 return if (val.ip_index != .none) switch (mod.intern_pool.indexToKey(val.toIntern())) {
207 return switch (mod.intern_pool.indexToKey(val.toIntern())) {
503208 .extern_func => |extern_func| extern_func,
504209 else => null,
505 } else null;
210 };
506211}
507212
508213pub fn getVariable(val: Value, mod: *Module) ?InternPool.Key.Variable {
509 return if (val.ip_index != .none) switch (mod.intern_pool.indexToKey(val.toIntern())) {
214 return switch (mod.intern_pool.indexToKey(val.toIntern())) {
510215 .variable => |variable| variable,
511216 else => null,
512 } else null;
217 };
513218}
514219
515220/// If the value fits in a u64, return it, otherwise null.
......@@ -544,12 +249,12 @@ pub fn getUnsignedIntAdvanced(val: Value, mod: *Module, opt_sema: ?*Sema) !?u64
544249 .int => |int| Value.fromInterned(int).getUnsignedIntAdvanced(mod, opt_sema),
545250 .elem => |elem| {
546251 const base_addr = (try Value.fromInterned(elem.base).getUnsignedIntAdvanced(mod, opt_sema)) orelse return null;
547 const elem_ty = Type.fromInterned(mod.intern_pool.typeOf(elem.base)).elemType2(mod);
252 const elem_ty = Value.fromInterned(elem.base).typeOf(mod).elemType2(mod);
548253 return base_addr + elem.index * elem_ty.abiSize(mod);
549254 },
550255 .field => |field| {
551256 const base_addr = (try Value.fromInterned(field.base).getUnsignedIntAdvanced(mod, opt_sema)) orelse return null;
552 const struct_ty = Type.fromInterned(mod.intern_pool.typeOf(field.base)).childType(mod);
257 const struct_ty = Value.fromInterned(field.base).typeOf(mod).childType(mod);
553258 if (opt_sema) |sema| try sema.resolveTypeLayout(struct_ty);
554259 return base_addr + struct_ty.structFieldOffset(@as(usize, @intCast(field.index)), mod);
555260 },
......@@ -600,16 +305,16 @@ pub fn toBool(val: Value) bool {
600305 };
601306}
602307
603fn isDeclRef(val: Value, mod: *Module) bool {
308fn ptrHasIntAddr(val: Value, mod: *Module) bool {
604309 var check = val;
605310 while (true) switch (mod.intern_pool.indexToKey(check.toIntern())) {
606311 .ptr => |ptr| switch (ptr.addr) {
607 .decl, .comptime_alloc, .comptime_field, .anon_decl => return true,
312 .decl, .comptime_alloc, .comptime_field, .anon_decl => return false,
313 .int => return true,
608314 .eu_payload, .opt_payload => |base| check = Value.fromInterned(base),
609315 .elem, .field => |base_index| check = Value.fromInterned(base_index.base),
610 .int => return false,
611316 },
612 else => return false,
317 else => unreachable,
613318 };
614319}
615320
......@@ -677,25 +382,14 @@ pub fn writeToMemory(val: Value, ty: Type, mod: *Module, buffer: []u8) error{
677382 .auto => return error.IllDefinedMemoryLayout,
678383 .@"extern" => for (0..struct_type.field_types.len) |i| {
679384 const off: usize = @intCast(ty.structFieldOffset(i, mod));
680 const field_val = switch (val.ip_index) {
681 .none => switch (val.tag()) {
682 .bytes => {
683 buffer[off] = val.castTag(.bytes).?.data[i];
684 continue;
685 },
686 .aggregate => val.castTag(.aggregate).?.data[i],
687 .repeated => val.castTag(.repeated).?.data,
688 else => unreachable,
385 const field_val = Value.fromInterned(switch (ip.indexToKey(val.toIntern()).aggregate.storage) {
386 .bytes => |bytes| {
387 buffer[off] = bytes[i];
388 continue;
689389 },
690 else => Value.fromInterned(switch (ip.indexToKey(val.toIntern()).aggregate.storage) {
691 .bytes => |bytes| {
692 buffer[off] = bytes[i];
693 continue;
694 },
695 .elems => |elems| elems[i],
696 .repeated_elem => |elem| elem,
697 }),
698 };
390 .elems => |elems| elems[i],
391 .repeated_elem => |elem| elem,
392 });
699393 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]);
700394 try writeToMemory(field_val, field_ty, mod, buffer[off..]);
701395 },
......@@ -745,7 +439,7 @@ pub fn writeToMemory(val: Value, ty: Type, mod: *Module, buffer: []u8) error{
745439 },
746440 .Pointer => {
747441 if (ty.isSlice(mod)) return error.IllDefinedMemoryLayout;
748 if (val.isDeclRef(mod)) return error.ReinterpretDeclRef;
442 if (!val.ptrHasIntAddr(mod)) return error.ReinterpretDeclRef;
749443 return val.writeToMemory(Type.usize, mod, buffer);
750444 },
751445 .Optional => {
......@@ -842,19 +536,11 @@ pub fn writeToPackedMemory(
842536 assert(struct_type.layout == .@"packed");
843537 var bits: u16 = 0;
844538 for (0..struct_type.field_types.len) |i| {
845 const field_val = switch (val.ip_index) {
846 .none => switch (val.tag()) {
847 .bytes => unreachable,
848 .aggregate => val.castTag(.aggregate).?.data[i],
849 .repeated => val.castTag(.repeated).?.data,
850 else => unreachable,
851 },
852 else => Value.fromInterned(switch (ip.indexToKey(val.toIntern()).aggregate.storage) {
853 .bytes => unreachable,
854 .elems => |elems| elems[i],
855 .repeated_elem => |elem| elem,
856 }),
857 };
539 const field_val = Value.fromInterned(switch (ip.indexToKey(val.toIntern()).aggregate.storage) {
540 .bytes => unreachable,
541 .elems => |elems| elems[i],
542 .repeated_elem => |elem| elem,
543 });
858544 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]);
859545 const field_bits: u16 = @intCast(field_ty.bitSize(mod));
860546 try field_val.writeToPackedMemory(field_ty, mod, buffer, bit_offset + bits);
......@@ -880,7 +566,7 @@ pub fn writeToPackedMemory(
880566 },
881567 .Pointer => {
882568 assert(!ty.isSlice(mod)); // No well defined layout.
883 if (val.isDeclRef(mod)) return error.ReinterpretDeclRef;
569 if (!val.ptrHasIntAddr(mod)) return error.ReinterpretDeclRef;
884570 return val.writeToPackedMemory(Type.usize, mod, buffer, bit_offset);
885571 },
886572 .Optional => {
......@@ -972,7 +658,7 @@ pub fn readFromMemory(
972658 const elems = try arena.alloc(InternPool.Index, @as(usize, @intCast(ty.arrayLen(mod))));
973659 var offset: usize = 0;
974660 for (elems) |*elem| {
975 elem.* = try (try readFromMemory(elem_ty, mod, buffer[offset..], arena)).intern(elem_ty, mod);
661 elem.* = (try readFromMemory(elem_ty, mod, buffer[offset..], arena)).toIntern();
976662 offset += @as(usize, @intCast(elem_size));
977663 }
978664 return Value.fromInterned((try mod.intern(.{ .aggregate = .{
......@@ -997,7 +683,7 @@ pub fn readFromMemory(
997683 const field_ty = Type.fromInterned(field_types.get(ip)[i]);
998684 const off: usize = @intCast(ty.structFieldOffset(i, mod));
999685 const sz: usize = @intCast(field_ty.abiSize(mod));
1000 field_val.* = try (try readFromMemory(field_ty, mod, buffer[off..(off + sz)], arena)).intern(field_ty, mod);
686 field_val.* = (try readFromMemory(field_ty, mod, buffer[off..(off + sz)], arena)).toIntern();
1001687 }
1002688 return Value.fromInterned((try mod.intern(.{ .aggregate = .{
1003689 .ty = ty.toIntern(),
......@@ -1027,7 +713,7 @@ pub fn readFromMemory(
1027713 .@"extern" => {
1028714 const union_size = ty.abiSize(mod);
1029715 const array_ty = try mod.arrayType(.{ .len = union_size, .child = .u8_type });
1030 const val = try (try readFromMemory(array_ty, mod, buffer, arena)).intern(array_ty, mod);
716 const val = (try readFromMemory(array_ty, mod, buffer, arena)).toIntern();
1031717 return Value.fromInterned((try mod.intern(.{ .un = .{
1032718 .ty = ty.toIntern(),
1033719 .tag = .none,
......@@ -1094,30 +780,19 @@ pub fn readFromPackedMemory(
1094780 return Value.true;
1095781 }
1096782 },
1097 .Int, .Enum => |ty_tag| {
783 .Int => {
1098784 if (buffer.len == 0) return mod.intValue(ty, 0);
1099785 const int_info = ty.intInfo(mod);
1100786 const bits = int_info.bits;
1101787 if (bits == 0) return mod.intValue(ty, 0);
1102788
1103789 // Fast path for integers <= u64
1104 if (bits <= 64) {
1105 const int_ty = switch (ty_tag) {
1106 .Int => ty,
1107 .Enum => ty.intTagType(mod),
1108 else => unreachable,
1109 };
1110 return mod.getCoerced(switch (int_info.signedness) {
1111 .signed => return mod.intValue(
1112 int_ty,
1113 std.mem.readVarPackedInt(i64, buffer, bit_offset, bits, endian, .signed),
1114 ),
1115 .unsigned => return mod.intValue(
1116 int_ty,
1117 std.mem.readVarPackedInt(u64, buffer, bit_offset, bits, endian, .unsigned),
1118 ),
1119 }, ty);
1120 }
790 if (bits <= 64) switch (int_info.signedness) {
791 // Use different backing types for unsigned vs signed to avoid the need to go via
792 // a larger type like `i128`.
793 .unsigned => return mod.intValue(ty, std.mem.readVarPackedInt(u64, buffer, bit_offset, bits, endian, .unsigned)),
794 .signed => return mod.intValue(ty, std.mem.readVarPackedInt(i64, buffer, bit_offset, bits, endian, .signed)),
795 };
1121796
1122797 // Slow path, we have to construct a big-int
1123798 const abi_size = @as(usize, @intCast(ty.abiSize(mod)));
......@@ -1129,6 +804,11 @@ pub fn readFromPackedMemory(
1129804 bigint.readPackedTwosComplement(buffer, bit_offset, bits, endian, int_info.signedness);
1130805 return mod.intValue_big(ty, bigint.toConst());
1131806 },
807 .Enum => {
808 const int_ty = ty.intTagType(mod);
809 const int_val = try Value.readFromPackedMemory(int_ty, mod, buffer, bit_offset, arena);
810 return mod.getCoerced(int_val, ty);
811 },
1132812 .Float => return Value.fromInterned((try mod.intern(.{ .float = .{
1133813 .ty = ty.toIntern(),
1134814 .storage = switch (ty.floatBits(target)) {
......@@ -1149,7 +829,7 @@ pub fn readFromPackedMemory(
1149829 for (elems, 0..) |_, i| {
1150830 // On big-endian systems, LLVM reverses the element order of vectors by default
1151831 const tgt_elem_i = if (endian == .big) elems.len - i - 1 else i;
1152 elems[tgt_elem_i] = try (try readFromPackedMemory(elem_ty, mod, buffer, bit_offset + bits, arena)).intern(elem_ty, mod);
832 elems[tgt_elem_i] = (try readFromPackedMemory(elem_ty, mod, buffer, bit_offset + bits, arena)).toIntern();
1153833 bits += elem_bit_size;
1154834 }
1155835 return Value.fromInterned((try mod.intern(.{ .aggregate = .{
......@@ -1166,7 +846,7 @@ pub fn readFromPackedMemory(
1166846 for (field_vals, 0..) |*field_val, i| {
1167847 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]);
1168848 const field_bits: u16 = @intCast(field_ty.bitSize(mod));
1169 field_val.* = try (try readFromPackedMemory(field_ty, mod, buffer, bit_offset + bits, arena)).intern(field_ty, mod);
849 field_val.* = (try readFromPackedMemory(field_ty, mod, buffer, bit_offset + bits, arena)).toIntern();
1170850 bits += field_bits;
1171851 }
1172852 return Value.fromInterned((try mod.intern(.{ .aggregate = .{
......@@ -1581,80 +1261,34 @@ pub fn slicePtr(val: Value, mod: *Module) Value {
15811261 return Value.fromInterned(mod.intern_pool.slicePtr(val.toIntern()));
15821262}
15831263
1584pub fn sliceLen(val: Value, mod: *Module) u64 {
1585 const ip = &mod.intern_pool;
1586 return switch (ip.indexToKey(val.toIntern())) {
1587 .ptr => |ptr| switch (ip.indexToKey(switch (ptr.addr) {
1588 .decl => |decl| mod.declPtr(decl).ty.toIntern(),
1589 .comptime_alloc => @panic("TODO"),
1590 .anon_decl => |anon_decl| ip.typeOf(anon_decl.val),
1591 .comptime_field => |comptime_field| ip.typeOf(comptime_field),
1592 else => unreachable,
1593 })) {
1594 .array_type => |array_type| array_type.len,
1595 else => 1,
1596 },
1597 .slice => |slice| Value.fromInterned(slice.len).toUnsignedInt(mod),
1598 else => unreachable,
1599 };
1264/// Gets the `len` field of a slice value as a `u64`.
1265/// Resolves the length using the provided `Sema` if necessary.
1266pub fn sliceLen(val: Value, sema: *Sema) !u64 {
1267 return Value.fromInterned(sema.mod.intern_pool.sliceLen(val.toIntern())).toUnsignedIntAdvanced(sema);
16001268}
16011269
1602/// Asserts the value is a single-item pointer to an array, or an array,
1603/// or an unknown-length pointer, and returns the element value at the index.
1604pub fn elemValue(val: Value, mod: *Module, index: usize) Allocator.Error!Value {
1605 return (try val.maybeElemValue(mod, index)).?;
1606}
1607
1608/// Like `elemValue`, but returns `null` instead of asserting on failure.
1609pub fn maybeElemValue(val: Value, mod: *Module, index: usize) Allocator.Error!?Value {
1610 return val.maybeElemValueFull(null, mod, index);
1611}
1612
1613pub fn maybeElemValueFull(val: Value, sema: ?*Sema, mod: *Module, index: usize) Allocator.Error!?Value {
1614 return switch (val.ip_index) {
1615 .none => switch (val.tag()) {
1616 .bytes => try mod.intValue(Type.u8, val.castTag(.bytes).?.data[index]),
1617 .repeated => val.castTag(.repeated).?.data,
1618 .aggregate => val.castTag(.aggregate).?.data[index],
1619 .slice => val.castTag(.slice).?.data.ptr.maybeElemValueFull(sema, mod, index),
1620 else => null,
1270/// Asserts the value is an aggregate, and returns the element value at the given index.
1271pub fn elemValue(val: Value, zcu: *Zcu, index: usize) Allocator.Error!Value {
1272 const ip = &zcu.intern_pool;
1273 switch (zcu.intern_pool.indexToKey(val.toIntern())) {
1274 .undef => |ty| {
1275 return Value.fromInterned(try zcu.intern(.{ .undef = Type.fromInterned(ty).childType(zcu).toIntern() }));
16211276 },
1622 else => switch (mod.intern_pool.indexToKey(val.toIntern())) {
1623 .undef => |ty| Value.fromInterned((try mod.intern(.{
1624 .undef = Type.fromInterned(ty).elemType2(mod).toIntern(),
1625 }))),
1626 .slice => |slice| return Value.fromInterned(slice.ptr).maybeElemValueFull(sema, mod, index),
1627 .ptr => |ptr| switch (ptr.addr) {
1628 .decl => |decl| mod.declPtr(decl).val.maybeElemValueFull(sema, mod, index),
1629 .anon_decl => |anon_decl| Value.fromInterned(anon_decl.val).maybeElemValueFull(sema, mod, index),
1630 .comptime_alloc => |idx| if (sema) |s| s.getComptimeAlloc(idx).val.maybeElemValueFull(sema, mod, index) else null,
1631 .int, .eu_payload => null,
1632 .opt_payload => |base| Value.fromInterned(base).maybeElemValueFull(sema, mod, index),
1633 .comptime_field => |field_val| Value.fromInterned(field_val).maybeElemValueFull(sema, mod, index),
1634 .elem => |elem| Value.fromInterned(elem.base).maybeElemValueFull(sema, mod, index + @as(usize, @intCast(elem.index))),
1635 .field => |field| if (Value.fromInterned(field.base).pointerDecl(mod)) |decl_index| {
1636 const base_decl = mod.declPtr(decl_index);
1637 const field_val = try base_decl.val.fieldValue(mod, @as(usize, @intCast(field.index)));
1638 return field_val.maybeElemValueFull(sema, mod, index);
1639 } else null,
1640 },
1641 .opt => |opt| Value.fromInterned(opt.val).maybeElemValueFull(sema, mod, index),
1642 .aggregate => |aggregate| {
1643 const len = mod.intern_pool.aggregateTypeLen(aggregate.ty);
1644 if (index < len) return Value.fromInterned(switch (aggregate.storage) {
1645 .bytes => |bytes| try mod.intern(.{ .int = .{
1646 .ty = .u8_type,
1647 .storage = .{ .u64 = bytes[index] },
1648 } }),
1649 .elems => |elems| elems[index],
1650 .repeated_elem => |elem| elem,
1651 });
1652 assert(index == len);
1653 return Value.fromInterned(mod.intern_pool.indexToKey(aggregate.ty).array_type.sentinel);
1654 },
1655 else => null,
1277 .aggregate => |aggregate| {
1278 const len = ip.aggregateTypeLen(aggregate.ty);
1279 if (index < len) return Value.fromInterned(switch (aggregate.storage) {
1280 .bytes => |bytes| try zcu.intern(.{ .int = .{
1281 .ty = .u8_type,
1282 .storage = .{ .u64 = bytes[index] },
1283 } }),
1284 .elems => |elems| elems[index],
1285 .repeated_elem => |elem| elem,
1286 });
1287 assert(index == len);
1288 return Type.fromInterned(aggregate.ty).sentinel(zcu).?;
16561289 },
1657 };
1290 else => unreachable,
1291 }
16581292}
16591293
16601294pub fn isLazyAlign(val: Value, mod: *Module) bool {
......@@ -1686,83 +1320,48 @@ pub fn sliceArray(
16861320) error{OutOfMemory}!Value {
16871321 // TODO: write something like getCoercedInts to avoid needing to dupe
16881322 const mod = sema.mod;
1689 return switch (val.ip_index) {
1690 .none => switch (val.tag()) {
1691 .slice => val.castTag(.slice).?.data.ptr.sliceArray(sema, start, end),
1692 .bytes => Tag.bytes.create(sema.arena, val.castTag(.bytes).?.data[start..end]),
1693 .repeated => val,
1694 .aggregate => Tag.aggregate.create(sema.arena, val.castTag(.aggregate).?.data[start..end]),
1695 else => unreachable,
1696 },
1697 else => switch (mod.intern_pool.indexToKey(val.toIntern())) {
1698 .ptr => |ptr| switch (ptr.addr) {
1699 .decl => |decl| try mod.declPtr(decl).val.sliceArray(sema, start, end),
1700 .comptime_alloc => |idx| sema.getComptimeAlloc(idx).val.sliceArray(sema, start, end),
1701 .comptime_field => |comptime_field| Value.fromInterned(comptime_field)
1702 .sliceArray(sema, start, end),
1703 .elem => |elem| Value.fromInterned(elem.base)
1704 .sliceArray(sema, start + @as(usize, @intCast(elem.index)), end + @as(usize, @intCast(elem.index))),
1705 else => unreachable,
1706 },
1707 .aggregate => |aggregate| Value.fromInterned((try mod.intern(.{ .aggregate = .{
1708 .ty = switch (mod.intern_pool.indexToKey(mod.intern_pool.typeOf(val.toIntern()))) {
1709 .array_type => |array_type| try mod.arrayType(.{
1710 .len = @as(u32, @intCast(end - start)),
1711 .child = array_type.child,
1712 .sentinel = if (end == array_type.len) array_type.sentinel else .none,
1713 }),
1714 .vector_type => |vector_type| try mod.vectorType(.{
1715 .len = @as(u32, @intCast(end - start)),
1716 .child = vector_type.child,
1717 }),
1718 else => unreachable,
1719 }.toIntern(),
1720 .storage = switch (aggregate.storage) {
1721 .bytes => .{ .bytes = try sema.arena.dupe(u8, mod.intern_pool.indexToKey(val.toIntern()).aggregate.storage.bytes[start..end]) },
1722 .elems => .{ .elems = try sema.arena.dupe(InternPool.Index, mod.intern_pool.indexToKey(val.toIntern()).aggregate.storage.elems[start..end]) },
1723 .repeated_elem => |elem| .{ .repeated_elem = elem },
1724 },
1725 } }))),
1323 const aggregate = mod.intern_pool.indexToKey(val.toIntern()).aggregate;
1324 return Value.fromInterned(try mod.intern(.{ .aggregate = .{
1325 .ty = switch (mod.intern_pool.indexToKey(mod.intern_pool.typeOf(val.toIntern()))) {
1326 .array_type => |array_type| try mod.arrayType(.{
1327 .len = @as(u32, @intCast(end - start)),
1328 .child = array_type.child,
1329 .sentinel = if (end == array_type.len) array_type.sentinel else .none,
1330 }),
1331 .vector_type => |vector_type| try mod.vectorType(.{
1332 .len = @as(u32, @intCast(end - start)),
1333 .child = vector_type.child,
1334 }),
17261335 else => unreachable,
1336 }.toIntern(),
1337 .storage = switch (aggregate.storage) {
1338 .bytes => .{ .bytes = try sema.arena.dupe(u8, mod.intern_pool.indexToKey(val.toIntern()).aggregate.storage.bytes[start..end]) },
1339 .elems => .{ .elems = try sema.arena.dupe(InternPool.Index, mod.intern_pool.indexToKey(val.toIntern()).aggregate.storage.elems[start..end]) },
1340 .repeated_elem => |elem| .{ .repeated_elem = elem },
17271341 },
1728 };
1342 } }));
17291343}
17301344
17311345pub fn fieldValue(val: Value, mod: *Module, index: usize) !Value {
1732 return switch (val.ip_index) {
1733 .none => switch (val.tag()) {
1734 .aggregate => {
1735 const field_values = val.castTag(.aggregate).?.data;
1736 return field_values[index];
1737 },
1738 .@"union" => {
1739 const payload = val.castTag(.@"union").?.data;
1740 // TODO assert the tag is correct
1741 return payload.val;
1742 },
1743 else => unreachable,
1744 },
1745 else => switch (mod.intern_pool.indexToKey(val.toIntern())) {
1746 .undef => |ty| Value.fromInterned((try mod.intern(.{
1747 .undef = Type.fromInterned(ty).structFieldType(index, mod).toIntern(),
1748 }))),
1749 .aggregate => |aggregate| Value.fromInterned(switch (aggregate.storage) {
1750 .bytes => |bytes| try mod.intern(.{ .int = .{
1751 .ty = .u8_type,
1752 .storage = .{ .u64 = bytes[index] },
1753 } }),
1754 .elems => |elems| elems[index],
1755 .repeated_elem => |elem| elem,
1756 }),
1757 // TODO assert the tag is correct
1758 .un => |un| Value.fromInterned(un.val),
1759 else => unreachable,
1760 },
1346 return switch (mod.intern_pool.indexToKey(val.toIntern())) {
1347 .undef => |ty| Value.fromInterned((try mod.intern(.{
1348 .undef = Type.fromInterned(ty).structFieldType(index, mod).toIntern(),
1349 }))),
1350 .aggregate => |aggregate| Value.fromInterned(switch (aggregate.storage) {
1351 .bytes => |bytes| try mod.intern(.{ .int = .{
1352 .ty = .u8_type,
1353 .storage = .{ .u64 = bytes[index] },
1354 } }),
1355 .elems => |elems| elems[index],
1356 .repeated_elem => |elem| elem,
1357 }),
1358 // TODO assert the tag is correct
1359 .un => |un| Value.fromInterned(un.val),
1360 else => unreachable,
17611361 };
17621362}
17631363
17641364pub fn unionTag(val: Value, mod: *Module) ?Value {
1765 if (val.ip_index == .none) return val.castTag(.@"union").?.data.tag;
17661365 return switch (mod.intern_pool.indexToKey(val.toIntern())) {
17671366 .undef, .enum_tag => val,
17681367 .un => |un| if (un.tag != .none) Value.fromInterned(un.tag) else return null,
......@@ -1771,7 +1370,6 @@ pub fn unionTag(val: Value, mod: *Module) ?Value {
17711370}
17721371
17731372pub fn unionValue(val: Value, mod: *Module) Value {
1774 if (val.ip_index == .none) return val.castTag(.@"union").?.data.val;
17751373 return switch (mod.intern_pool.indexToKey(val.toIntern())) {
17761374 .un => |un| Value.fromInterned(un.val),
17771375 else => unreachable,
......@@ -1792,7 +1390,7 @@ pub fn elemPtr(
17921390 };
17931391 switch (mod.intern_pool.indexToKey(ptr_val.toIntern())) {
17941392 .ptr => |ptr| switch (ptr.addr) {
1795 .elem => |elem| if (Type.fromInterned(mod.intern_pool.typeOf(elem.base)).elemType2(mod).eql(elem_ty, mod))
1393 .elem => |elem| if (Value.fromInterned(elem.base).typeOf(mod).elemType2(mod).eql(elem_ty, mod))
17961394 return Value.fromInterned((try mod.intern(.{ .ptr = .{
17971395 .ty = elem_ptr_ty.toIntern(),
17981396 .addr = .{ .elem = .{
......@@ -1817,7 +1415,7 @@ pub fn elemPtr(
18171415}
18181416
18191417pub fn isUndef(val: Value, mod: *Module) bool {
1820 return val.ip_index != .none and mod.intern_pool.isUndef(val.toIntern());
1418 return mod.intern_pool.isUndef(val.toIntern());
18211419}
18221420
18231421/// TODO: check for cases such as array that is not marked undef but all the element
......@@ -1911,7 +1509,7 @@ pub fn floatFromIntAdvanced(val: Value, arena: Allocator, int_ty: Type, float_ty
19111509 const scalar_ty = float_ty.scalarType(mod);
19121510 for (result_data, 0..) |*scalar, i| {
19131511 const elem_val = try val.elemValue(mod, i);
1914 scalar.* = try (try floatFromIntScalar(elem_val, scalar_ty, mod, opt_sema)).intern(scalar_ty, mod);
1512 scalar.* = (try floatFromIntScalar(elem_val, scalar_ty, mod, opt_sema)).toIntern();
19151513 }
19161514 return Value.fromInterned((try mod.intern(.{ .aggregate = .{
19171515 .ty = float_ty.toIntern(),
......@@ -1989,7 +1587,7 @@ pub fn intAddSat(
19891587 for (result_data, 0..) |*scalar, i| {
19901588 const lhs_elem = try lhs.elemValue(mod, i);
19911589 const rhs_elem = try rhs.elemValue(mod, i);
1992 scalar.* = try (try intAddSatScalar(lhs_elem, rhs_elem, scalar_ty, arena, mod)).intern(scalar_ty, mod);
1590 scalar.* = (try intAddSatScalar(lhs_elem, rhs_elem, scalar_ty, arena, mod)).toIntern();
19931591 }
19941592 return Value.fromInterned((try mod.intern(.{ .aggregate = .{
19951593 .ty = ty.toIntern(),
......@@ -2039,7 +1637,7 @@ pub fn intSubSat(
20391637 for (result_data, 0..) |*scalar, i| {
20401638 const lhs_elem = try lhs.elemValue(mod, i);
20411639 const rhs_elem = try rhs.elemValue(mod, i);
2042 scalar.* = try (try intSubSatScalar(lhs_elem, rhs_elem, scalar_ty, arena, mod)).intern(scalar_ty, mod);
1640 scalar.* = (try intSubSatScalar(lhs_elem, rhs_elem, scalar_ty, arena, mod)).toIntern();
20431641 }
20441642 return Value.fromInterned((try mod.intern(.{ .aggregate = .{
20451643 .ty = ty.toIntern(),
......@@ -2091,8 +1689,8 @@ pub fn intMulWithOverflow(
20911689 const lhs_elem = try lhs.elemValue(mod, i);
20921690 const rhs_elem = try rhs.elemValue(mod, i);
20931691 const of_math_result = try intMulWithOverflowScalar(lhs_elem, rhs_elem, scalar_ty, arena, mod);
2094 of.* = try of_math_result.overflow_bit.intern(Type.u1, mod);
2095 scalar.* = try of_math_result.wrapped_result.intern(scalar_ty, mod);
1692 of.* = of_math_result.overflow_bit.toIntern();
1693 scalar.* = of_math_result.wrapped_result.toIntern();
20961694 }
20971695 return OverflowArithmeticResult{
20981696 .overflow_bit = Value.fromInterned((try mod.intern(.{ .aggregate = .{
......@@ -2157,7 +1755,7 @@ pub fn numberMulWrap(
21571755 for (result_data, 0..) |*scalar, i| {
21581756 const lhs_elem = try lhs.elemValue(mod, i);
21591757 const rhs_elem = try rhs.elemValue(mod, i);
2160 scalar.* = try (try numberMulWrapScalar(lhs_elem, rhs_elem, scalar_ty, arena, mod)).intern(scalar_ty, mod);
1758 scalar.* = (try numberMulWrapScalar(lhs_elem, rhs_elem, scalar_ty, arena, mod)).toIntern();
21611759 }
21621760 return Value.fromInterned((try mod.intern(.{ .aggregate = .{
21631761 .ty = ty.toIntern(),
......@@ -2203,7 +1801,7 @@ pub fn intMulSat(
22031801 for (result_data, 0..) |*scalar, i| {
22041802 const lhs_elem = try lhs.elemValue(mod, i);
22051803 const rhs_elem = try rhs.elemValue(mod, i);
2206 scalar.* = try (try intMulSatScalar(lhs_elem, rhs_elem, scalar_ty, arena, mod)).intern(scalar_ty, mod);
1804 scalar.* = (try intMulSatScalar(lhs_elem, rhs_elem, scalar_ty, arena, mod)).toIntern();
22071805 }
22081806 return Value.fromInterned((try mod.intern(.{ .aggregate = .{
22091807 .ty = ty.toIntern(),
......@@ -2279,7 +1877,7 @@ pub fn bitwiseNot(val: Value, ty: Type, arena: Allocator, mod: *Module) !Value {
22791877 const scalar_ty = ty.scalarType(mod);
22801878 for (result_data, 0..) |*scalar, i| {
22811879 const elem_val = try val.elemValue(mod, i);
2282 scalar.* = try (try bitwiseNotScalar(elem_val, scalar_ty, arena, mod)).intern(scalar_ty, mod);
1880 scalar.* = (try bitwiseNotScalar(elem_val, scalar_ty, arena, mod)).toIntern();
22831881 }
22841882 return Value.fromInterned((try mod.intern(.{ .aggregate = .{
22851883 .ty = ty.toIntern(),
......@@ -2322,7 +1920,7 @@ pub fn bitwiseAnd(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *
23221920 for (result_data, 0..) |*scalar, i| {
23231921 const lhs_elem = try lhs.elemValue(mod, i);
23241922 const rhs_elem = try rhs.elemValue(mod, i);
2325 scalar.* = try (try bitwiseAndScalar(lhs_elem, rhs_elem, scalar_ty, allocator, mod)).intern(scalar_ty, mod);
1923 scalar.* = (try bitwiseAndScalar(lhs_elem, rhs_elem, scalar_ty, allocator, mod)).toIntern();
23261924 }
23271925 return Value.fromInterned((try mod.intern(.{ .aggregate = .{
23281926 .ty = ty.toIntern(),
......@@ -2361,7 +1959,7 @@ pub fn bitwiseNand(lhs: Value, rhs: Value, ty: Type, arena: Allocator, mod: *Mod
23611959 for (result_data, 0..) |*scalar, i| {
23621960 const lhs_elem = try lhs.elemValue(mod, i);
23631961 const rhs_elem = try rhs.elemValue(mod, i);
2364 scalar.* = try (try bitwiseNandScalar(lhs_elem, rhs_elem, scalar_ty, arena, mod)).intern(scalar_ty, mod);
1962 scalar.* = (try bitwiseNandScalar(lhs_elem, rhs_elem, scalar_ty, arena, mod)).toIntern();
23651963 }
23661964 return Value.fromInterned((try mod.intern(.{ .aggregate = .{
23671965 .ty = ty.toIntern(),
......@@ -2389,7 +1987,7 @@ pub fn bitwiseOr(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *M
23891987 for (result_data, 0..) |*scalar, i| {
23901988 const lhs_elem = try lhs.elemValue(mod, i);
23911989 const rhs_elem = try rhs.elemValue(mod, i);
2392 scalar.* = try (try bitwiseOrScalar(lhs_elem, rhs_elem, scalar_ty, allocator, mod)).intern(scalar_ty, mod);
1990 scalar.* = (try bitwiseOrScalar(lhs_elem, rhs_elem, scalar_ty, allocator, mod)).toIntern();
23931991 }
23941992 return Value.fromInterned((try mod.intern(.{ .aggregate = .{
23951993 .ty = ty.toIntern(),
......@@ -2427,7 +2025,7 @@ pub fn bitwiseXor(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *
24272025 for (result_data, 0..) |*scalar, i| {
24282026 const lhs_elem = try lhs.elemValue(mod, i);
24292027 const rhs_elem = try rhs.elemValue(mod, i);
2430 scalar.* = try (try bitwiseXorScalar(lhs_elem, rhs_elem, scalar_ty, allocator, mod)).intern(scalar_ty, mod);
2028 scalar.* = (try bitwiseXorScalar(lhs_elem, rhs_elem, scalar_ty, allocator, mod)).toIntern();
24312029 }
24322030 return Value.fromInterned((try mod.intern(.{ .aggregate = .{
24332031 .ty = ty.toIntern(),
......@@ -2493,7 +2091,7 @@ fn intDivInner(lhs: Value, rhs: Value, ty: Type, overflow_idx: *usize, allocator
24932091 },
24942092 else => |e| return e,
24952093 };
2496 scalar.* = try val.intern(scalar_ty, mod);
2094 scalar.* = val.toIntern();
24972095 }
24982096 return Value.fromInterned((try mod.intern(.{ .aggregate = .{
24992097 .ty = ty.toIntern(),
......@@ -2541,7 +2139,7 @@ pub fn intDivFloor(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod:
25412139 for (result_data, 0..) |*scalar, i| {
25422140 const lhs_elem = try lhs.elemValue(mod, i);
25432141 const rhs_elem = try rhs.elemValue(mod, i);
2544 scalar.* = try (try intDivFloorScalar(lhs_elem, rhs_elem, scalar_ty, allocator, mod)).intern(scalar_ty, mod);
2142 scalar.* = (try intDivFloorScalar(lhs_elem, rhs_elem, scalar_ty, allocator, mod)).toIntern();
25452143 }
25462144 return Value.fromInterned((try mod.intern(.{ .aggregate = .{
25472145 .ty = ty.toIntern(),
......@@ -2583,7 +2181,7 @@ pub fn intMod(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Modu
25832181 for (result_data, 0..) |*scalar, i| {
25842182 const lhs_elem = try lhs.elemValue(mod, i);
25852183 const rhs_elem = try rhs.elemValue(mod, i);
2586 scalar.* = try (try intModScalar(lhs_elem, rhs_elem, scalar_ty, allocator, mod)).intern(scalar_ty, mod);
2184 scalar.* = (try intModScalar(lhs_elem, rhs_elem, scalar_ty, allocator, mod)).toIntern();
25872185 }
25882186 return Value.fromInterned((try mod.intern(.{ .aggregate = .{
25892187 .ty = ty.toIntern(),
......@@ -2620,7 +2218,6 @@ pub fn intModScalar(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod:
26202218
26212219/// Returns true if the value is a floating point type and is NaN. Returns false otherwise.
26222220pub fn isNan(val: Value, mod: *const Module) bool {
2623 if (val.ip_index == .none) return false;
26242221 return switch (mod.intern_pool.indexToKey(val.toIntern())) {
26252222 .float => |float| switch (float.storage) {
26262223 inline else => |x| std.math.isNan(x),
......@@ -2631,7 +2228,6 @@ pub fn isNan(val: Value, mod: *const Module) bool {
26312228
26322229/// Returns true if the value is a floating point type and is infinite. Returns false otherwise.
26332230pub fn isInf(val: Value, mod: *const Module) bool {
2634 if (val.ip_index == .none) return false;
26352231 return switch (mod.intern_pool.indexToKey(val.toIntern())) {
26362232 .float => |float| switch (float.storage) {
26372233 inline else => |x| std.math.isInf(x),
......@@ -2641,7 +2237,6 @@ pub fn isInf(val: Value, mod: *const Module) bool {
26412237}
26422238
26432239pub fn isNegativeInf(val: Value, mod: *const Module) bool {
2644 if (val.ip_index == .none) return false;
26452240 return switch (mod.intern_pool.indexToKey(val.toIntern())) {
26462241 .float => |float| switch (float.storage) {
26472242 inline else => |x| std.math.isNegativeInf(x),
......@@ -2657,7 +2252,7 @@ pub fn floatRem(lhs: Value, rhs: Value, float_type: Type, arena: Allocator, mod:
26572252 for (result_data, 0..) |*scalar, i| {
26582253 const lhs_elem = try lhs.elemValue(mod, i);
26592254 const rhs_elem = try rhs.elemValue(mod, i);
2660 scalar.* = try (try floatRemScalar(lhs_elem, rhs_elem, scalar_ty, mod)).intern(scalar_ty, mod);
2255 scalar.* = (try floatRemScalar(lhs_elem, rhs_elem, scalar_ty, mod)).toIntern();
26612256 }
26622257 return Value.fromInterned((try mod.intern(.{ .aggregate = .{
26632258 .ty = float_type.toIntern(),
......@@ -2690,7 +2285,7 @@ pub fn floatMod(lhs: Value, rhs: Value, float_type: Type, arena: Allocator, mod:
26902285 for (result_data, 0..) |*scalar, i| {
26912286 const lhs_elem = try lhs.elemValue(mod, i);
26922287 const rhs_elem = try rhs.elemValue(mod, i);
2693 scalar.* = try (try floatModScalar(lhs_elem, rhs_elem, scalar_ty, mod)).intern(scalar_ty, mod);
2288 scalar.* = (try floatModScalar(lhs_elem, rhs_elem, scalar_ty, mod)).toIntern();
26942289 }
26952290 return Value.fromInterned((try mod.intern(.{ .aggregate = .{
26962291 .ty = float_type.toIntern(),
......@@ -2751,7 +2346,7 @@ fn intMulInner(lhs: Value, rhs: Value, ty: Type, overflow_idx: *usize, allocator
27512346 },
27522347 else => |e| return e,
27532348 };
2754 scalar.* = try val.intern(scalar_ty, mod);
2349 scalar.* = val.toIntern();
27552350 }
27562351 return Value.fromInterned((try mod.intern(.{ .aggregate = .{
27572352 .ty = ty.toIntern(),
......@@ -2793,7 +2388,7 @@ pub fn intTrunc(val: Value, ty: Type, allocator: Allocator, signedness: std.buil
27932388 const scalar_ty = ty.scalarType(mod);
27942389 for (result_data, 0..) |*scalar, i| {
27952390 const elem_val = try val.elemValue(mod, i);
2796 scalar.* = try (try intTruncScalar(elem_val, scalar_ty, allocator, signedness, bits, mod)).intern(scalar_ty, mod);
2391 scalar.* = (try intTruncScalar(elem_val, scalar_ty, allocator, signedness, bits, mod)).toIntern();
27972392 }
27982393 return Value.fromInterned((try mod.intern(.{ .aggregate = .{
27992394 .ty = ty.toIntern(),
......@@ -2818,7 +2413,7 @@ pub fn intTruncBitsAsValue(
28182413 for (result_data, 0..) |*scalar, i| {
28192414 const elem_val = try val.elemValue(mod, i);
28202415 const bits_elem = try bits.elemValue(mod, i);
2821 scalar.* = try (try intTruncScalar(elem_val, scalar_ty, allocator, signedness, @as(u16, @intCast(bits_elem.toUnsignedInt(mod))), mod)).intern(scalar_ty, mod);
2416 scalar.* = (try intTruncScalar(elem_val, scalar_ty, allocator, signedness, @as(u16, @intCast(bits_elem.toUnsignedInt(mod))), mod)).toIntern();
28222417 }
28232418 return Value.fromInterned((try mod.intern(.{ .aggregate = .{
28242419 .ty = ty.toIntern(),
......@@ -2858,7 +2453,7 @@ pub fn shl(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module)
28582453 for (result_data, 0..) |*scalar, i| {
28592454 const lhs_elem = try lhs.elemValue(mod, i);
28602455 const rhs_elem = try rhs.elemValue(mod, i);
2861 scalar.* = try (try shlScalar(lhs_elem, rhs_elem, scalar_ty, allocator, mod)).intern(scalar_ty, mod);
2456 scalar.* = (try shlScalar(lhs_elem, rhs_elem, scalar_ty, allocator, mod)).toIntern();
28622457 }
28632458 return Value.fromInterned((try mod.intern(.{ .aggregate = .{
28642459 .ty = ty.toIntern(),
......@@ -2908,8 +2503,8 @@ pub fn shlWithOverflow(
29082503 const lhs_elem = try lhs.elemValue(mod, i);
29092504 const rhs_elem = try rhs.elemValue(mod, i);
29102505 const of_math_result = try shlWithOverflowScalar(lhs_elem, rhs_elem, scalar_ty, allocator, mod);
2911 of.* = try of_math_result.overflow_bit.intern(Type.u1, mod);
2912 scalar.* = try of_math_result.wrapped_result.intern(scalar_ty, mod);
2506 of.* = of_math_result.overflow_bit.toIntern();
2507 scalar.* = of_math_result.wrapped_result.toIntern();
29132508 }
29142509 return OverflowArithmeticResult{
29152510 .overflow_bit = Value.fromInterned((try mod.intern(.{ .aggregate = .{
......@@ -2969,7 +2564,7 @@ pub fn shlSat(
29692564 for (result_data, 0..) |*scalar, i| {
29702565 const lhs_elem = try lhs.elemValue(mod, i);
29712566 const rhs_elem = try rhs.elemValue(mod, i);
2972 scalar.* = try (try shlSatScalar(lhs_elem, rhs_elem, scalar_ty, arena, mod)).intern(scalar_ty, mod);
2567 scalar.* = (try shlSatScalar(lhs_elem, rhs_elem, scalar_ty, arena, mod)).toIntern();
29732568 }
29742569 return Value.fromInterned((try mod.intern(.{ .aggregate = .{
29752570 .ty = ty.toIntern(),
......@@ -3019,7 +2614,7 @@ pub fn shlTrunc(
30192614 for (result_data, 0..) |*scalar, i| {
30202615 const lhs_elem = try lhs.elemValue(mod, i);
30212616 const rhs_elem = try rhs.elemValue(mod, i);
3022 scalar.* = try (try shlTruncScalar(lhs_elem, rhs_elem, scalar_ty, arena, mod)).intern(scalar_ty, mod);
2617 scalar.* = (try shlTruncScalar(lhs_elem, rhs_elem, scalar_ty, arena, mod)).toIntern();
30232618 }
30242619 return Value.fromInterned((try mod.intern(.{ .aggregate = .{
30252620 .ty = ty.toIntern(),
......@@ -3049,7 +2644,7 @@ pub fn shr(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module)
30492644 for (result_data, 0..) |*scalar, i| {
30502645 const lhs_elem = try lhs.elemValue(mod, i);
30512646 const rhs_elem = try rhs.elemValue(mod, i);
3052 scalar.* = try (try shrScalar(lhs_elem, rhs_elem, scalar_ty, allocator, mod)).intern(scalar_ty, mod);
2647 scalar.* = (try shrScalar(lhs_elem, rhs_elem, scalar_ty, allocator, mod)).toIntern();
30532648 }
30542649 return Value.fromInterned((try mod.intern(.{ .aggregate = .{
30552650 .ty = ty.toIntern(),
......@@ -3101,7 +2696,7 @@ pub fn floatNeg(
31012696 const scalar_ty = float_type.scalarType(mod);
31022697 for (result_data, 0..) |*scalar, i| {
31032698 const elem_val = try val.elemValue(mod, i);
3104 scalar.* = try (try floatNegScalar(elem_val, scalar_ty, mod)).intern(scalar_ty, mod);
2699 scalar.* = (try floatNegScalar(elem_val, scalar_ty, mod)).toIntern();
31052700 }
31062701 return Value.fromInterned((try mod.intern(.{ .aggregate = .{
31072702 .ty = float_type.toIntern(),
......@@ -3144,7 +2739,7 @@ pub fn floatAdd(
31442739 for (result_data, 0..) |*scalar, i| {
31452740 const lhs_elem = try lhs.elemValue(mod, i);
31462741 const rhs_elem = try rhs.elemValue(mod, i);
3147 scalar.* = try (try floatAddScalar(lhs_elem, rhs_elem, scalar_ty, mod)).intern(scalar_ty, mod);
2742 scalar.* = (try floatAddScalar(lhs_elem, rhs_elem, scalar_ty, mod)).toIntern();
31482743 }
31492744 return Value.fromInterned((try mod.intern(.{ .aggregate = .{
31502745 .ty = float_type.toIntern(),
......@@ -3188,7 +2783,7 @@ pub fn floatSub(
31882783 for (result_data, 0..) |*scalar, i| {
31892784 const lhs_elem = try lhs.elemValue(mod, i);
31902785 const rhs_elem = try rhs.elemValue(mod, i);
3191 scalar.* = try (try floatSubScalar(lhs_elem, rhs_elem, scalar_ty, mod)).intern(scalar_ty, mod);
2786 scalar.* = (try floatSubScalar(lhs_elem, rhs_elem, scalar_ty, mod)).toIntern();
31922787 }
31932788 return Value.fromInterned((try mod.intern(.{ .aggregate = .{
31942789 .ty = float_type.toIntern(),
......@@ -3232,7 +2827,7 @@ pub fn floatDiv(
32322827 for (result_data, 0..) |*scalar, i| {
32332828 const lhs_elem = try lhs.elemValue(mod, i);
32342829 const rhs_elem = try rhs.elemValue(mod, i);
3235 scalar.* = try (try floatDivScalar(lhs_elem, rhs_elem, scalar_ty, mod)).intern(scalar_ty, mod);
2830 scalar.* = (try floatDivScalar(lhs_elem, rhs_elem, scalar_ty, mod)).toIntern();
32362831 }
32372832 return Value.fromInterned((try mod.intern(.{ .aggregate = .{
32382833 .ty = float_type.toIntern(),
......@@ -3276,7 +2871,7 @@ pub fn floatDivFloor(
32762871 for (result_data, 0..) |*scalar, i| {
32772872 const lhs_elem = try lhs.elemValue(mod, i);
32782873 const rhs_elem = try rhs.elemValue(mod, i);
3279 scalar.* = try (try floatDivFloorScalar(lhs_elem, rhs_elem, scalar_ty, mod)).intern(scalar_ty, mod);
2874 scalar.* = (try floatDivFloorScalar(lhs_elem, rhs_elem, scalar_ty, mod)).toIntern();
32802875 }
32812876 return Value.fromInterned((try mod.intern(.{ .aggregate = .{
32822877 .ty = float_type.toIntern(),
......@@ -3320,7 +2915,7 @@ pub fn floatDivTrunc(
33202915 for (result_data, 0..) |*scalar, i| {
33212916 const lhs_elem = try lhs.elemValue(mod, i);
33222917 const rhs_elem = try rhs.elemValue(mod, i);
3323 scalar.* = try (try floatDivTruncScalar(lhs_elem, rhs_elem, scalar_ty, mod)).intern(scalar_ty, mod);
2918 scalar.* = (try floatDivTruncScalar(lhs_elem, rhs_elem, scalar_ty, mod)).toIntern();
33242919 }
33252920 return Value.fromInterned((try mod.intern(.{ .aggregate = .{
33262921 .ty = float_type.toIntern(),
......@@ -3364,7 +2959,7 @@ pub fn floatMul(
33642959 for (result_data, 0..) |*scalar, i| {
33652960 const lhs_elem = try lhs.elemValue(mod, i);
33662961 const rhs_elem = try rhs.elemValue(mod, i);
3367 scalar.* = try (try floatMulScalar(lhs_elem, rhs_elem, scalar_ty, mod)).intern(scalar_ty, mod);
2962 scalar.* = (try floatMulScalar(lhs_elem, rhs_elem, scalar_ty, mod)).toIntern();
33682963 }
33692964 return Value.fromInterned((try mod.intern(.{ .aggregate = .{
33702965 .ty = float_type.toIntern(),
......@@ -3401,7 +2996,7 @@ pub fn sqrt(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value
34012996 const scalar_ty = float_type.scalarType(mod);
34022997 for (result_data, 0..) |*scalar, i| {
34032998 const elem_val = try val.elemValue(mod, i);
3404 scalar.* = try (try sqrtScalar(elem_val, scalar_ty, mod)).intern(scalar_ty, mod);
2999 scalar.* = (try sqrtScalar(elem_val, scalar_ty, mod)).toIntern();
34053000 }
34063001 return Value.fromInterned((try mod.intern(.{ .aggregate = .{
34073002 .ty = float_type.toIntern(),
......@@ -3433,7 +3028,7 @@ pub fn sin(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value
34333028 const scalar_ty = float_type.scalarType(mod);
34343029 for (result_data, 0..) |*scalar, i| {
34353030 const elem_val = try val.elemValue(mod, i);
3436 scalar.* = try (try sinScalar(elem_val, scalar_ty, mod)).intern(scalar_ty, mod);
3031 scalar.* = (try sinScalar(elem_val, scalar_ty, mod)).toIntern();
34373032 }
34383033 return Value.fromInterned((try mod.intern(.{ .aggregate = .{
34393034 .ty = float_type.toIntern(),
......@@ -3465,7 +3060,7 @@ pub fn cos(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value
34653060 const scalar_ty = float_type.scalarType(mod);
34663061 for (result_data, 0..) |*scalar, i| {
34673062 const elem_val = try val.elemValue(mod, i);
3468 scalar.* = try (try cosScalar(elem_val, scalar_ty, mod)).intern(scalar_ty, mod);
3063 scalar.* = (try cosScalar(elem_val, scalar_ty, mod)).toIntern();
34693064 }
34703065 return Value.fromInterned((try mod.intern(.{ .aggregate = .{
34713066 .ty = float_type.toIntern(),
......@@ -3497,7 +3092,7 @@ pub fn tan(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value
34973092 const scalar_ty = float_type.scalarType(mod);
34983093 for (result_data, 0..) |*scalar, i| {
34993094 const elem_val = try val.elemValue(mod, i);
3500 scalar.* = try (try tanScalar(elem_val, scalar_ty, mod)).intern(scalar_ty, mod);
3095 scalar.* = (try tanScalar(elem_val, scalar_ty, mod)).toIntern();
35013096 }
35023097 return Value.fromInterned((try mod.intern(.{ .aggregate = .{
35033098 .ty = float_type.toIntern(),
......@@ -3529,7 +3124,7 @@ pub fn exp(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value
35293124 const scalar_ty = float_type.scalarType(mod);
35303125 for (result_data, 0..) |*scalar, i| {
35313126 const elem_val = try val.elemValue(mod, i);
3532 scalar.* = try (try expScalar(elem_val, scalar_ty, mod)).intern(scalar_ty, mod);
3127 scalar.* = (try expScalar(elem_val, scalar_ty, mod)).toIntern();
35333128 }
35343129 return Value.fromInterned((try mod.intern(.{ .aggregate = .{
35353130 .ty = float_type.toIntern(),
......@@ -3561,7 +3156,7 @@ pub fn exp2(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value
35613156 const scalar_ty = float_type.scalarType(mod);
35623157 for (result_data, 0..) |*scalar, i| {
35633158 const elem_val = try val.elemValue(mod, i);
3564 scalar.* = try (try exp2Scalar(elem_val, scalar_ty, mod)).intern(scalar_ty, mod);
3159 scalar.* = (try exp2Scalar(elem_val, scalar_ty, mod)).toIntern();
35653160 }
35663161 return Value.fromInterned((try mod.intern(.{ .aggregate = .{
35673162 .ty = float_type.toIntern(),
......@@ -3593,7 +3188,7 @@ pub fn log(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value
35933188 const scalar_ty = float_type.scalarType(mod);
35943189 for (result_data, 0..) |*scalar, i| {
35953190 const elem_val = try val.elemValue(mod, i);
3596 scalar.* = try (try logScalar(elem_val, scalar_ty, mod)).intern(scalar_ty, mod);
3191 scalar.* = (try logScalar(elem_val, scalar_ty, mod)).toIntern();
35973192 }
35983193 return Value.fromInterned((try mod.intern(.{ .aggregate = .{
35993194 .ty = float_type.toIntern(),
......@@ -3625,7 +3220,7 @@ pub fn log2(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value
36253220 const scalar_ty = float_type.scalarType(mod);
36263221 for (result_data, 0..) |*scalar, i| {
36273222 const elem_val = try val.elemValue(mod, i);
3628 scalar.* = try (try log2Scalar(elem_val, scalar_ty, mod)).intern(scalar_ty, mod);
3223 scalar.* = (try log2Scalar(elem_val, scalar_ty, mod)).toIntern();
36293224 }
36303225 return Value.fromInterned((try mod.intern(.{ .aggregate = .{
36313226 .ty = float_type.toIntern(),
......@@ -3657,7 +3252,7 @@ pub fn log10(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Valu
36573252 const scalar_ty = float_type.scalarType(mod);
36583253 for (result_data, 0..) |*scalar, i| {
36593254 const elem_val = try val.elemValue(mod, i);
3660 scalar.* = try (try log10Scalar(elem_val, scalar_ty, mod)).intern(scalar_ty, mod);
3255 scalar.* = (try log10Scalar(elem_val, scalar_ty, mod)).toIntern();
36613256 }
36623257 return Value.fromInterned((try mod.intern(.{ .aggregate = .{
36633258 .ty = float_type.toIntern(),
......@@ -3689,7 +3284,7 @@ pub fn abs(val: Value, ty: Type, arena: Allocator, mod: *Module) !Value {
36893284 const scalar_ty = ty.scalarType(mod);
36903285 for (result_data, 0..) |*scalar, i| {
36913286 const elem_val = try val.elemValue(mod, i);
3692 scalar.* = try (try absScalar(elem_val, scalar_ty, mod, arena)).intern(scalar_ty, mod);
3287 scalar.* = (try absScalar(elem_val, scalar_ty, mod, arena)).toIntern();
36933288 }
36943289 return Value.fromInterned((try mod.intern(.{ .aggregate = .{
36953290 .ty = ty.toIntern(),
......@@ -3740,7 +3335,7 @@ pub fn floor(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Valu
37403335 const scalar_ty = float_type.scalarType(mod);
37413336 for (result_data, 0..) |*scalar, i| {
37423337 const elem_val = try val.elemValue(mod, i);
3743 scalar.* = try (try floorScalar(elem_val, scalar_ty, mod)).intern(scalar_ty, mod);
3338 scalar.* = (try floorScalar(elem_val, scalar_ty, mod)).toIntern();
37443339 }
37453340 return Value.fromInterned((try mod.intern(.{ .aggregate = .{
37463341 .ty = float_type.toIntern(),
......@@ -3772,7 +3367,7 @@ pub fn ceil(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value
37723367 const scalar_ty = float_type.scalarType(mod);
37733368 for (result_data, 0..) |*scalar, i| {
37743369 const elem_val = try val.elemValue(mod, i);
3775 scalar.* = try (try ceilScalar(elem_val, scalar_ty, mod)).intern(scalar_ty, mod);
3370 scalar.* = (try ceilScalar(elem_val, scalar_ty, mod)).toIntern();
37763371 }
37773372 return Value.fromInterned((try mod.intern(.{ .aggregate = .{
37783373 .ty = float_type.toIntern(),
......@@ -3804,7 +3399,7 @@ pub fn round(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Valu
38043399 const scalar_ty = float_type.scalarType(mod);
38053400 for (result_data, 0..) |*scalar, i| {
38063401 const elem_val = try val.elemValue(mod, i);
3807 scalar.* = try (try roundScalar(elem_val, scalar_ty, mod)).intern(scalar_ty, mod);
3402 scalar.* = (try roundScalar(elem_val, scalar_ty, mod)).toIntern();
38083403 }
38093404 return Value.fromInterned((try mod.intern(.{ .aggregate = .{
38103405 .ty = float_type.toIntern(),
......@@ -3836,7 +3431,7 @@ pub fn trunc(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Valu
38363431 const scalar_ty = float_type.scalarType(mod);
38373432 for (result_data, 0..) |*scalar, i| {
38383433 const elem_val = try val.elemValue(mod, i);
3839 scalar.* = try (try truncScalar(elem_val, scalar_ty, mod)).intern(scalar_ty, mod);
3434 scalar.* = (try truncScalar(elem_val, scalar_ty, mod)).toIntern();
38403435 }
38413436 return Value.fromInterned((try mod.intern(.{ .aggregate = .{
38423437 .ty = float_type.toIntern(),
......@@ -3877,7 +3472,7 @@ pub fn mulAdd(
38773472 const mulend1_elem = try mulend1.elemValue(mod, i);
38783473 const mulend2_elem = try mulend2.elemValue(mod, i);
38793474 const addend_elem = try addend.elemValue(mod, i);
3880 scalar.* = try (try mulAddScalar(scalar_ty, mulend1_elem, mulend2_elem, addend_elem, mod)).intern(scalar_ty, mod);
3475 scalar.* = (try mulAddScalar(scalar_ty, mulend1_elem, mulend2_elem, addend_elem, mod)).toIntern();
38813476 }
38823477 return Value.fromInterned((try mod.intern(.{ .aggregate = .{
38833478 .ty = float_type.toIntern(),
......@@ -3939,6 +3534,10 @@ pub fn isGenericPoison(val: Value) bool {
39393534 return val.toIntern() == .generic_poison;
39403535}
39413536
3537pub fn typeOf(val: Value, zcu: *const Zcu) Type {
3538 return Type.fromInterned(zcu.intern_pool.typeOf(val.toIntern()));
3539}
3540
39423541/// For an integer (comptime or fixed-width) `val`, returns the comptime-known bounds of the value.
39433542/// If `val` is not undef, the bounds are both `val`.
39443543/// If `val` is undef and has a fixed-width type, the bounds are the bounds of the type.
......@@ -3953,98 +3552,26 @@ pub fn intValueBounds(val: Value, mod: *Module) !?[2]Value {
39533552 };
39543553}
39553554
3956/// This type is not copyable since it may contain pointers to its inner data.
3957pub const Payload = struct {
3958 tag: Tag,
3959
3960 pub const Slice = struct {
3961 base: Payload,
3962 data: struct {
3963 ptr: Value,
3964 len: Value,
3965 },
3966 };
3967
3968 pub const Bytes = struct {
3969 base: Payload,
3970 /// Includes the sentinel, if any.
3971 data: []const u8,
3972 };
3973
3974 pub const SubValue = struct {
3975 base: Payload,
3976 data: Value,
3977 };
3978
3979 pub const Aggregate = struct {
3980 base: Payload,
3981 /// Field values. The types are according to the struct or array type.
3982 /// The length is provided here so that copying a Value does not depend on the Type.
3983 data: []Value,
3984 };
3985
3986 pub const Union = struct {
3987 pub const base_tag = Tag.@"union";
3988
3989 base: Payload = .{ .tag = base_tag },
3990 data: Data,
3991
3992 pub const Data = struct {
3993 tag: ?Value,
3994 val: Value,
3995 };
3996 };
3997};
3998
39993555pub const BigIntSpace = InternPool.Key.Int.Storage.BigIntSpace;
40003556
4001pub const zero_usize: Value = .{ .ip_index = .zero_usize, .legacy = undefined };
4002pub const zero_u8: Value = .{ .ip_index = .zero_u8, .legacy = undefined };
4003pub const zero_comptime_int: Value = .{ .ip_index = .zero, .legacy = undefined };
4004pub const one_comptime_int: Value = .{ .ip_index = .one, .legacy = undefined };
4005pub const negative_one_comptime_int: Value = .{ .ip_index = .negative_one, .legacy = undefined };
4006pub const undef: Value = .{ .ip_index = .undef, .legacy = undefined };
4007pub const @"void": Value = .{ .ip_index = .void_value, .legacy = undefined };
4008pub const @"null": Value = .{ .ip_index = .null_value, .legacy = undefined };
4009pub const @"false": Value = .{ .ip_index = .bool_false, .legacy = undefined };
4010pub const @"true": Value = .{ .ip_index = .bool_true, .legacy = undefined };
4011pub const @"unreachable": Value = .{ .ip_index = .unreachable_value, .legacy = undefined };
4012
4013pub const generic_poison: Value = .{ .ip_index = .generic_poison, .legacy = undefined };
4014pub const generic_poison_type: Value = .{ .ip_index = .generic_poison_type, .legacy = undefined };
4015pub const empty_struct: Value = .{ .ip_index = .empty_struct, .legacy = undefined };
3557pub const zero_usize: Value = .{ .ip_index = .zero_usize };
3558pub const zero_u8: Value = .{ .ip_index = .zero_u8 };
3559pub const zero_comptime_int: Value = .{ .ip_index = .zero };
3560pub const one_comptime_int: Value = .{ .ip_index = .one };
3561pub const negative_one_comptime_int: Value = .{ .ip_index = .negative_one };
3562pub const undef: Value = .{ .ip_index = .undef };
3563pub const @"void": Value = .{ .ip_index = .void_value };
3564pub const @"null": Value = .{ .ip_index = .null_value };
3565pub const @"false": Value = .{ .ip_index = .bool_false };
3566pub const @"true": Value = .{ .ip_index = .bool_true };
3567pub const @"unreachable": Value = .{ .ip_index = .unreachable_value };
3568
3569pub const generic_poison: Value = .{ .ip_index = .generic_poison };
3570pub const generic_poison_type: Value = .{ .ip_index = .generic_poison_type };
3571pub const empty_struct: Value = .{ .ip_index = .empty_struct };
40163572
40173573pub fn makeBool(x: bool) Value {
40183574 return if (x) Value.true else Value.false;
40193575}
40203576
40213577pub const RuntimeIndex = InternPool.RuntimeIndex;
4022
4023/// This function is used in the debugger pretty formatters in tools/ to fetch the
4024/// Tag to Payload mapping to facilitate fancy debug printing for this type.
4025fn dbHelper(self: *Value, tag_to_payload_map: *map: {
4026 const tags = @typeInfo(Tag).Enum.fields;
4027 var fields: [tags.len]std.builtin.Type.StructField = undefined;
4028 for (&fields, tags) |*field, t| field.* = .{
4029 .name = t.name ++ "",
4030 .type = *@field(Tag, t.name).Type(),
4031 .default_value = null,
4032 .is_comptime = false,
4033 .alignment = 0,
4034 };
4035 break :map @Type(.{ .Struct = .{
4036 .layout = .@"extern",
4037 .fields = &fields,
4038 .decls = &.{},
4039 .is_tuple = false,
4040 } });
4041}) void {
4042 _ = self;
4043 _ = tag_to_payload_map;
4044}
4045
4046comptime {
4047 if (!builtin.strip_debug_info) {
4048 _ = &dbHelper;
4049 }
4050}
src/arch/aarch64/CodeGen.zig+4-8
......@@ -10,7 +10,6 @@ const Emit = @import("Emit.zig");
1010const Liveness = @import("../../Liveness.zig");
1111const Type = @import("../../type.zig").Type;
1212const Value = @import("../../Value.zig");
13const TypedValue = @import("../../TypedValue.zig");
1413const link = @import("../../link.zig");
1514const Module = @import("../../Module.zig");
1615const InternPool = @import("../../InternPool.zig");
......@@ -342,7 +341,7 @@ pub fn generate(
342341 const func = zcu.funcInfo(func_index);
343342 const fn_owner_decl = zcu.declPtr(func.owner_decl);
344343 assert(fn_owner_decl.has_tv);
345 const fn_type = fn_owner_decl.ty;
344 const fn_type = fn_owner_decl.typeOf(zcu);
346345 const namespace = zcu.namespacePtr(fn_owner_decl.src_namespace);
347346 const target = &namespace.file_scope.mod.resolved_target.result;
348347
......@@ -6143,10 +6142,7 @@ fn resolveInst(self: *Self, inst: Air.Inst.Ref) InnerError!MCValue {
61436142 if (!inst_ty.hasRuntimeBitsIgnoreComptime(mod) and !inst_ty.isError(mod))
61446143 return MCValue{ .none = {} };
61456144
6146 const inst_index = inst.toIndex() orelse return self.genTypedValue(.{
6147 .ty = inst_ty,
6148 .val = (try self.air.value(inst, mod)).?,
6149 });
6145 const inst_index = inst.toIndex() orelse return self.genTypedValue((try self.air.value(inst, mod)).?);
61506146
61516147 return self.getResolvedInstValue(inst_index);
61526148}
......@@ -6163,11 +6159,11 @@ fn getResolvedInstValue(self: *Self, inst: Air.Inst.Index) MCValue {
61636159 }
61646160}
61656161
6166fn genTypedValue(self: *Self, arg_tv: TypedValue) InnerError!MCValue {
6162fn genTypedValue(self: *Self, val: Value) InnerError!MCValue {
61676163 const mcv: MCValue = switch (try codegen.genTypedValue(
61686164 self.bin_file,
61696165 self.src_loc,
6170 arg_tv,
6166 val,
61716167 self.owner_decl,
61726168 )) {
61736169 .mcv => |mcv| switch (mcv) {
src/arch/arm/CodeGen.zig+4-8
......@@ -10,7 +10,6 @@ const Emit = @import("Emit.zig");
1010const Liveness = @import("../../Liveness.zig");
1111const Type = @import("../../type.zig").Type;
1212const Value = @import("../../Value.zig");
13const TypedValue = @import("../../TypedValue.zig");
1413const link = @import("../../link.zig");
1514const Module = @import("../../Module.zig");
1615const InternPool = @import("../../InternPool.zig");
......@@ -349,7 +348,7 @@ pub fn generate(
349348 const func = zcu.funcInfo(func_index);
350349 const fn_owner_decl = zcu.declPtr(func.owner_decl);
351350 assert(fn_owner_decl.has_tv);
352 const fn_type = fn_owner_decl.ty;
351 const fn_type = fn_owner_decl.typeOf(zcu);
353352 const namespace = zcu.namespacePtr(fn_owner_decl.src_namespace);
354353 const target = &namespace.file_scope.mod.resolved_target.result;
355354
......@@ -6097,10 +6096,7 @@ fn resolveInst(self: *Self, inst: Air.Inst.Ref) InnerError!MCValue {
60976096 if (!inst_ty.hasRuntimeBitsIgnoreComptime(mod) and !inst_ty.isError(mod))
60986097 return MCValue{ .none = {} };
60996098
6100 const inst_index = inst.toIndex() orelse return self.genTypedValue(.{
6101 .ty = inst_ty,
6102 .val = (try self.air.value(inst, mod)).?,
6103 });
6099 const inst_index = inst.toIndex() orelse return self.genTypedValue((try self.air.value(inst, mod)).?);
61046100
61056101 return self.getResolvedInstValue(inst_index);
61066102}
......@@ -6117,12 +6113,12 @@ fn getResolvedInstValue(self: *Self, inst: Air.Inst.Index) MCValue {
61176113 }
61186114}
61196115
6120fn genTypedValue(self: *Self, arg_tv: TypedValue) InnerError!MCValue {
6116fn genTypedValue(self: *Self, val: Value) InnerError!MCValue {
61216117 const mod = self.bin_file.comp.module.?;
61226118 const mcv: MCValue = switch (try codegen.genTypedValue(
61236119 self.bin_file,
61246120 self.src_loc,
6125 arg_tv,
6121 val,
61266122 mod.funcOwnerDeclIndex(self.func_index),
61276123 )) {
61286124 .mcv => |mcv| switch (mcv) {
src/arch/riscv64/CodeGen.zig+4-8
......@@ -9,7 +9,6 @@ const Emit = @import("Emit.zig");
99const Liveness = @import("../../Liveness.zig");
1010const Type = @import("../../type.zig").Type;
1111const Value = @import("../../Value.zig");
12const TypedValue = @import("../../TypedValue.zig");
1312const link = @import("../../link.zig");
1413const Module = @import("../../Module.zig");
1514const InternPool = @import("../../InternPool.zig");
......@@ -230,7 +229,7 @@ pub fn generate(
230229 const func = zcu.funcInfo(func_index);
231230 const fn_owner_decl = zcu.declPtr(func.owner_decl);
232231 assert(fn_owner_decl.has_tv);
233 const fn_type = fn_owner_decl.ty;
232 const fn_type = fn_owner_decl.typeOf(zcu);
234233 const namespace = zcu.namespacePtr(fn_owner_decl.src_namespace);
235234 const target = &namespace.file_scope.mod.resolved_target.result;
236235
......@@ -2552,10 +2551,7 @@ fn resolveInst(self: *Self, inst: Air.Inst.Ref) InnerError!MCValue {
25522551 if (!inst_ty.hasRuntimeBits(mod))
25532552 return MCValue{ .none = {} };
25542553
2555 const inst_index = inst.toIndex() orelse return self.genTypedValue(.{
2556 .ty = inst_ty,
2557 .val = (try self.air.value(inst, mod)).?,
2558 });
2554 const inst_index = inst.toIndex() orelse return self.genTypedValue((try self.air.value(inst, mod)).?);
25592555
25602556 return self.getResolvedInstValue(inst_index);
25612557}
......@@ -2572,12 +2568,12 @@ fn getResolvedInstValue(self: *Self, inst: Air.Inst.Index) MCValue {
25722568 }
25732569}
25742570
2575fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {
2571fn genTypedValue(self: *Self, val: Value) InnerError!MCValue {
25762572 const mod = self.bin_file.comp.module.?;
25772573 const mcv: MCValue = switch (try codegen.genTypedValue(
25782574 self.bin_file,
25792575 self.src_loc,
2580 typed_value,
2576 val,
25812577 mod.funcOwnerDeclIndex(self.func_index),
25822578 )) {
25832579 .mcv => |mcv| switch (mcv) {
src/arch/sparc64/CodeGen.zig+5-8
......@@ -12,7 +12,7 @@ const builtin = @import("builtin");
1212const link = @import("../../link.zig");
1313const Module = @import("../../Module.zig");
1414const InternPool = @import("../../InternPool.zig");
15const TypedValue = @import("../../TypedValue.zig");
15const Value = @import("../../Value.zig");
1616const ErrorMsg = Module.ErrorMsg;
1717const codegen = @import("../../codegen.zig");
1818const Air = @import("../../Air.zig");
......@@ -273,7 +273,7 @@ pub fn generate(
273273 const func = zcu.funcInfo(func_index);
274274 const fn_owner_decl = zcu.declPtr(func.owner_decl);
275275 assert(fn_owner_decl.has_tv);
276 const fn_type = fn_owner_decl.ty;
276 const fn_type = fn_owner_decl.typeOf(zcu);
277277 const namespace = zcu.namespacePtr(fn_owner_decl.src_namespace);
278278 const target = &namespace.file_scope.mod.resolved_target.result;
279279
......@@ -4118,12 +4118,12 @@ fn genStoreASI(self: *Self, value_reg: Register, addr_reg: Register, off_reg: Re
41184118 }
41194119}
41204120
4121fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {
4121fn genTypedValue(self: *Self, val: Value) InnerError!MCValue {
41224122 const mod = self.bin_file.comp.module.?;
41234123 const mcv: MCValue = switch (try codegen.genTypedValue(
41244124 self.bin_file,
41254125 self.src_loc,
4126 typed_value,
4126 val,
41274127 mod.funcOwnerDeclIndex(self.func_index),
41284128 )) {
41294129 .mcv => |mcv| switch (mcv) {
......@@ -4546,10 +4546,7 @@ fn resolveInst(self: *Self, ref: Air.Inst.Ref) InnerError!MCValue {
45464546 return self.getResolvedInstValue(inst);
45474547 }
45484548
4549 return self.genTypedValue(.{
4550 .ty = ty,
4551 .val = (try self.air.value(ref, mod)).?,
4552 });
4549 return self.genTypedValue((try self.air.value(ref, mod)).?);
45534550}
45544551
45554552fn ret(self: *Self, mcv: MCValue) !void {
src/arch/wasm/CodeGen.zig+25-30
......@@ -18,7 +18,6 @@ const Value = @import("../../Value.zig");
1818const Compilation = @import("../../Compilation.zig");
1919const LazySrcLoc = std.zig.LazySrcLoc;
2020const link = @import("../../link.zig");
21const TypedValue = @import("../../TypedValue.zig");
2221const Air = @import("../../Air.zig");
2322const Liveness = @import("../../Liveness.zig");
2423const target_util = @import("../../target.zig");
......@@ -805,7 +804,7 @@ fn resolveInst(func: *CodeGen, ref: Air.Inst.Ref) InnerError!WValue {
805804 // In the other cases, we will simply lower the constant to a value that fits
806805 // into a single local (such as a pointer, integer, bool, etc).
807806 const result = if (isByRef(ty, mod)) blk: {
808 const sym_index = try func.bin_file.lowerUnnamedConst(.{ .ty = ty, .val = val }, func.decl_index);
807 const sym_index = try func.bin_file.lowerUnnamedConst(val, func.decl_index);
809808 break :blk WValue{ .memory = sym_index };
810809 } else try func.lowerConstant(val, ty);
811810
......@@ -1243,12 +1242,12 @@ pub fn generate(
12431242fn genFunc(func: *CodeGen) InnerError!void {
12441243 const mod = func.bin_file.base.comp.module.?;
12451244 const ip = &mod.intern_pool;
1246 const fn_info = mod.typeToFunc(func.decl.ty).?;
1245 const fn_info = mod.typeToFunc(func.decl.typeOf(mod)).?;
12471246 var func_type = try genFunctype(func.gpa, fn_info.cc, fn_info.param_types.get(ip), Type.fromInterned(fn_info.return_type), mod);
12481247 defer func_type.deinit(func.gpa);
12491248 _ = try func.bin_file.storeDeclType(func.decl_index, func_type);
12501249
1251 var cc_result = try func.resolveCallingConventionValues(func.decl.ty);
1250 var cc_result = try func.resolveCallingConventionValues(func.decl.typeOf(mod));
12521251 defer cc_result.deinit(func.gpa);
12531252
12541253 func.args = cc_result.args;
......@@ -2087,7 +2086,7 @@ fn airRet(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
20872086 const mod = func.bin_file.base.comp.module.?;
20882087 const un_op = func.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
20892088 const operand = try func.resolveInst(un_op);
2090 const fn_info = mod.typeToFunc(func.decl.ty).?;
2089 const fn_info = mod.typeToFunc(func.decl.typeOf(mod)).?;
20912090 const ret_ty = Type.fromInterned(fn_info.return_type);
20922091
20932092 // result must be stored in the stack and we return a pointer
......@@ -2135,7 +2134,7 @@ fn airRetPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
21352134 break :result try func.allocStack(Type.usize); // create pointer to void
21362135 }
21372136
2138 const fn_info = mod.typeToFunc(func.decl.ty).?;
2137 const fn_info = mod.typeToFunc(func.decl.typeOf(mod)).?;
21392138 if (firstParamSRet(fn_info.cc, Type.fromInterned(fn_info.return_type), mod)) {
21402139 break :result func.return_value;
21412140 }
......@@ -2152,7 +2151,7 @@ fn airRetLoad(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
21522151 const operand = try func.resolveInst(un_op);
21532152 const ret_ty = func.typeOf(un_op).childType(mod);
21542153
2155 const fn_info = mod.typeToFunc(func.decl.ty).?;
2154 const fn_info = mod.typeToFunc(func.decl.typeOf(mod)).?;
21562155 if (!ret_ty.hasRuntimeBitsIgnoreComptime(mod)) {
21572156 if (ret_ty.isError(mod)) {
21582157 try func.addImm32(0);
......@@ -2193,7 +2192,7 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif
21932192 break :blk function.owner_decl;
21942193 } else if (func_val.getExternFunc(mod)) |extern_func| {
21952194 const ext_decl = mod.declPtr(extern_func.decl);
2196 const ext_info = mod.typeToFunc(ext_decl.ty).?;
2195 const ext_info = mod.typeToFunc(ext_decl.typeOf(mod)).?;
21972196 var func_type = try genFunctype(func.gpa, ext_info.cc, ext_info.param_types.get(ip), Type.fromInterned(ext_info.return_type), mod);
21982197 defer func_type.deinit(func.gpa);
21992198 const atom_index = try func.bin_file.getOrCreateAtomForDecl(extern_func.decl);
......@@ -2216,7 +2215,7 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif
22162215 },
22172216 else => {},
22182217 }
2219 return func.fail("Expected a function, but instead found type '{}'", .{func_val.tag()});
2218 return func.fail("Expected a function, but instead found '{s}'", .{@tagName(ip.indexToKey(func_val.toIntern()))});
22202219 };
22212220
22222221 const sret = if (first_param_sret) blk: {
......@@ -2530,7 +2529,7 @@ fn airArg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
25302529 const mod = func.bin_file.base.comp.module.?;
25312530 const arg_index = func.arg_index;
25322531 const arg = func.args[arg_index];
2533 const cc = mod.typeToFunc(func.decl.ty).?.cc;
2532 const cc = mod.typeToFunc(func.decl.typeOf(mod)).?.cc;
25342533 const arg_ty = func.typeOfIndex(inst);
25352534 if (cc == .C) {
25362535 const arg_classes = abi.classifyType(arg_ty, mod);
......@@ -3119,11 +3118,7 @@ fn lowerParentPtr(func: *CodeGen, ptr_val: Value, offset: u32) InnerError!WValue
31193118}
31203119
31213120fn lowerParentPtrDecl(func: *CodeGen, ptr_val: Value, decl_index: InternPool.DeclIndex, offset: u32) InnerError!WValue {
3122 const mod = func.bin_file.base.comp.module.?;
3123 const decl = mod.declPtr(decl_index);
3124 try mod.markDeclAlive(decl);
3125 const ptr_ty = try mod.singleMutPtrType(decl.ty);
3126 return func.lowerDeclRefValue(.{ .ty = ptr_ty, .val = ptr_val }, decl_index, offset);
3121 return func.lowerDeclRefValue(ptr_val, decl_index, offset);
31273122}
31283123
31293124fn lowerAnonDeclRef(
......@@ -3158,7 +3153,7 @@ fn lowerAnonDeclRef(
31583153 } else return WValue{ .memory_offset = .{ .pointer = target_sym_index, .offset = offset } };
31593154}
31603155
3161fn lowerDeclRefValue(func: *CodeGen, tv: TypedValue, decl_index: InternPool.DeclIndex, offset: u32) InnerError!WValue {
3156fn lowerDeclRefValue(func: *CodeGen, val: Value, decl_index: InternPool.DeclIndex, offset: u32) InnerError!WValue {
31623157 const mod = func.bin_file.base.comp.module.?;
31633158
31643159 const decl = mod.declPtr(decl_index);
......@@ -3166,23 +3161,23 @@ fn lowerDeclRefValue(func: *CodeGen, tv: TypedValue, decl_index: InternPool.Decl
31663161 // want to lower the actual decl, rather than the alias itself.
31673162 if (decl.val.getFunction(mod)) |func_val| {
31683163 if (func_val.owner_decl != decl_index) {
3169 return func.lowerDeclRefValue(tv, func_val.owner_decl, offset);
3164 return func.lowerDeclRefValue(val, func_val.owner_decl, offset);
31703165 }
31713166 } else if (decl.val.getExternFunc(mod)) |func_val| {
31723167 if (func_val.decl != decl_index) {
3173 return func.lowerDeclRefValue(tv, func_val.decl, offset);
3168 return func.lowerDeclRefValue(val, func_val.decl, offset);
31743169 }
31753170 }
3176 if (decl.ty.zigTypeTag(mod) != .Fn and !decl.ty.hasRuntimeBitsIgnoreComptime(mod)) {
3171 const decl_ty = decl.typeOf(mod);
3172 if (decl_ty.zigTypeTag(mod) != .Fn and !decl_ty.hasRuntimeBitsIgnoreComptime(mod)) {
31773173 return WValue{ .imm32 = 0xaaaaaaaa };
31783174 }
31793175
3180 try mod.markDeclAlive(decl);
31813176 const atom_index = try func.bin_file.getOrCreateAtomForDecl(decl_index);
31823177 const atom = func.bin_file.getAtom(atom_index);
31833178
31843179 const target_sym_index = @intFromEnum(atom.sym_index);
3185 if (decl.ty.zigTypeTag(mod) == .Fn) {
3180 if (decl_ty.zigTypeTag(mod) == .Fn) {
31863181 return WValue{ .function_index = target_sym_index };
31873182 } else if (offset == 0) {
31883183 return WValue{ .memory = target_sym_index };
......@@ -3281,23 +3276,23 @@ fn lowerConstant(func: *CodeGen, val: Value, ty: Type) InnerError!WValue {
32813276 },
32823277 .error_union => |error_union| {
32833278 const err_int_ty = try mod.errorIntType();
3284 const err_tv: TypedValue = switch (error_union.val) {
3279 const err_ty, const err_val = switch (error_union.val) {
32853280 .err_name => |err_name| .{
3286 .ty = ty.errorUnionSet(mod),
3287 .val = Value.fromInterned((try mod.intern(.{ .err = .{
3281 ty.errorUnionSet(mod),
3282 Value.fromInterned((try mod.intern(.{ .err = .{
32883283 .ty = ty.errorUnionSet(mod).toIntern(),
32893284 .name = err_name,
32903285 } }))),
32913286 },
32923287 .payload => .{
3293 .ty = err_int_ty,
3294 .val = try mod.intValue(err_int_ty, 0),
3288 err_int_ty,
3289 try mod.intValue(err_int_ty, 0),
32953290 },
32963291 };
32973292 const payload_type = ty.errorUnionPayload(mod);
32983293 if (!payload_type.hasRuntimeBitsIgnoreComptime(mod)) {
32993294 // We use the error type directly as the type.
3300 return func.lowerConstant(err_tv.val, err_tv.ty);
3295 return func.lowerConstant(err_val, err_ty);
33013296 }
33023297
33033298 return func.fail("Wasm TODO: lowerConstant error union with non-zero-bit payload type", .{});
......@@ -3321,10 +3316,10 @@ fn lowerConstant(func: *CodeGen, val: Value, ty: Type) InnerError!WValue {
33213316 .elem, .field => |base_index| ptr = ip.indexToKey(base_index.base).ptr,
33223317 .comptime_field, .comptime_alloc => unreachable,
33233318 };
3324 return .{ .memory = try func.bin_file.lowerUnnamedConst(.{ .ty = ty, .val = val }, owner_decl) };
3319 return .{ .memory = try func.bin_file.lowerUnnamedConst(val, owner_decl) };
33253320 },
33263321 .ptr => |ptr| switch (ptr.addr) {
3327 .decl => |decl| return func.lowerDeclRefValue(.{ .ty = ty, .val = val }, decl, 0),
3322 .decl => |decl| return func.lowerDeclRefValue(val, decl, 0),
33283323 .int => |int| return func.lowerConstant(Value.fromInterned(int), Type.fromInterned(ip.typeOf(int))),
33293324 .opt_payload, .elem, .field => return func.lowerParentPtr(val, 0),
33303325 .anon_decl => |ad| return func.lowerAnonDeclRef(ad, 0),
......@@ -7286,7 +7281,7 @@ fn getTagNameFunction(func: *CodeGen, enum_ty: Type) InnerError!u32 {
72867281 .storage = .{ .bytes = tag_name },
72877282 } });
72887283 const tag_sym_index = try func.bin_file.lowerUnnamedConst(
7289 .{ .ty = name_ty, .val = Value.fromInterned(name_val) },
7284 Value.fromInterned(name_val),
72907285 enum_decl_index,
72917286 );
72927287
src/arch/x86_64/CodeGen.zig+42-72
......@@ -32,7 +32,6 @@ const InternPool = @import("../../InternPool.zig");
3232const Alignment = InternPool.Alignment;
3333const Target = std.Target;
3434const Type = @import("../../type.zig").Type;
35const TypedValue = @import("../../TypedValue.zig");
3635const Value = @import("../../Value.zig");
3736const Instruction = @import("encoder.zig").Instruction;
3837
......@@ -808,7 +807,7 @@ pub fn generate(
808807 const func = zcu.funcInfo(func_index);
809808 const fn_owner_decl = zcu.declPtr(func.owner_decl);
810809 assert(fn_owner_decl.has_tv);
811 const fn_type = fn_owner_decl.ty;
810 const fn_type = fn_owner_decl.typeOf(zcu);
812811 const namespace = zcu.namespacePtr(fn_owner_decl.src_namespace);
813812 const mod = namespace.file_scope.mod;
814813
......@@ -2250,7 +2249,7 @@ fn genLazy(self: *Self, lazy_sym: link.File.LazySymbol) InnerError!void {
22502249 for (exitlude_jump_relocs, 0..) |*exitlude_jump_reloc, tag_index| {
22512250 const tag_name_len = ip.stringToSlice(tag_names.get(ip)[tag_index]).len;
22522251 const tag_val = try mod.enumValueFieldIndex(enum_ty, @intCast(tag_index));
2253 const tag_mcv = try self.genTypedValue(.{ .ty = enum_ty, .val = tag_val });
2252 const tag_mcv = try self.genTypedValue(tag_val);
22542253 try self.genBinOpMir(.{ ._, .cmp }, enum_ty, enum_mcv, tag_mcv);
22552254 const skip_reloc = try self.asmJccReloc(.ne, undefined);
22562255
......@@ -3323,7 +3322,7 @@ fn airTrunc(self: *Self, inst: Air.Inst.Index) !void {
33233322 .storage = .{ .repeated_elem = mask_val.ip_index },
33243323 } });
33253324
3326 const splat_mcv = try self.genTypedValue(.{ .ty = splat_ty, .val = Value.fromInterned(splat_val) });
3325 const splat_mcv = try self.genTypedValue(Value.fromInterned(splat_val));
33273326 const splat_addr_mcv: MCValue = switch (splat_mcv) {
33283327 .memory, .indirect, .load_frame => splat_mcv.address(),
33293328 else => .{ .register = try self.copyToTmpRegister(Type.usize, splat_mcv.address()) },
......@@ -4992,17 +4991,14 @@ fn airShlShrBinOp(self: *Self, inst: Air.Inst.Index) !void {
49924991 defer self.register_manager.unlockReg(shift_lock);
49934992
49944993 const mask_ty = try mod.vectorType(.{ .len = 16, .child = .u8_type });
4995 const mask_mcv = try self.genTypedValue(.{
4996 .ty = mask_ty,
4997 .val = Value.fromInterned((try mod.intern(.{ .aggregate = .{
4998 .ty = mask_ty.toIntern(),
4999 .storage = .{ .elems = &([1]InternPool.Index{
5000 (try rhs_ty.childType(mod).maxIntScalar(mod, Type.u8)).toIntern(),
5001 } ++ [1]InternPool.Index{
5002 (try mod.intValue(Type.u8, 0)).toIntern(),
5003 } ** 15) },
5004 } }))),
5005 });
4994 const mask_mcv = try self.genTypedValue(Value.fromInterned(try mod.intern(.{ .aggregate = .{
4995 .ty = mask_ty.toIntern(),
4996 .storage = .{ .elems = &([1]InternPool.Index{
4997 (try rhs_ty.childType(mod).maxIntScalar(mod, Type.u8)).toIntern(),
4998 } ++ [1]InternPool.Index{
4999 (try mod.intValue(Type.u8, 0)).toIntern(),
5000 } ** 15) },
5001 } })));
50065002 const mask_addr_reg =
50075003 try self.copyToTmpRegister(Type.usize, mask_mcv.address());
50085004 const mask_addr_lock = self.register_manager.lockRegAssumeUnused(mask_addr_reg);
......@@ -6860,11 +6856,11 @@ fn floatSign(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, ty: Type)
68606856 .child = (try mod.intType(.signed, scalar_bits)).ip_index,
68616857 });
68626858
6863 const sign_mcv = try self.genTypedValue(.{ .ty = vec_ty, .val = switch (tag) {
6859 const sign_mcv = try self.genTypedValue(switch (tag) {
68646860 .neg => try vec_ty.minInt(mod, vec_ty),
68656861 .abs => try vec_ty.maxInt(mod, vec_ty),
68666862 else => unreachable,
6867 } });
6863 });
68686864 const sign_mem: Memory = if (sign_mcv.isMemory())
68696865 try sign_mcv.mem(self, Memory.Size.fromSize(abi_size))
68706866 else
......@@ -11130,10 +11126,7 @@ fn genBinOp(
1113011126 .cmp_neq,
1113111127 => {
1113211128 const unsigned_ty = try lhs_ty.toUnsigned(mod);
11133 const not_mcv = try self.genTypedValue(.{
11134 .ty = lhs_ty,
11135 .val = try unsigned_ty.maxInt(mod, unsigned_ty),
11136 });
11129 const not_mcv = try self.genTypedValue(try unsigned_ty.maxInt(mod, unsigned_ty));
1113711130 const not_mem: Memory = if (not_mcv.isMemory())
1113811131 try not_mcv.mem(self, Memory.Size.fromSize(abi_size))
1113911132 else
......@@ -12258,12 +12251,11 @@ fn genCall(self: *Self, info: union(enum) {
1225812251 switch (switch (func_key) {
1225912252 else => func_key,
1226012253 .ptr => |ptr| switch (ptr.addr) {
12261 .decl => |decl| mod.intern_pool.indexToKey(try mod.declPtr(decl).internValue(mod)),
12254 .decl => |decl| mod.intern_pool.indexToKey(mod.declPtr(decl).val.toIntern()),
1226212255 else => func_key,
1226312256 },
1226412257 }) {
1226512258 .func => |func| {
12266 try mod.markDeclAlive(mod.declPtr(func.owner_decl));
1226712259 if (self.bin_file.cast(link.File.Elf)) |elf_file| {
1226812260 const sym_index = try elf_file.zigObjectPtr().?.getOrCreateMetadataForDecl(elf_file, func.owner_decl);
1226912261 const sym = elf_file.symbol(sym_index);
......@@ -12323,7 +12315,6 @@ fn genCall(self: *Self, info: union(enum) {
1232312315 },
1232412316 .extern_func => |extern_func| {
1232512317 const owner_decl = mod.declPtr(extern_func.decl);
12326 try mod.markDeclAlive(owner_decl);
1232712318 const lib_name = mod.intern_pool.stringToSliceUnwrap(extern_func.lib_name);
1232812319 const decl_name = mod.intern_pool.stringToSlice(owner_decl.name);
1232912320 try self.genExternSymbolRef(.call, lib_name, decl_name);
......@@ -14694,10 +14685,7 @@ fn genSetReg(
1469414685 ),
1469514686 else => unreachable,
1469614687 },
14697 .segment, .x87, .mmx, .sse => try self.genSetReg(dst_reg, ty, try self.genTypedValue(.{
14698 .ty = ty,
14699 .val = try mod.undefValue(ty),
14700 }), opts),
14688 .segment, .x87, .mmx, .sse => try self.genSetReg(dst_reg, ty, try self.genTypedValue(try mod.undefValue(ty)), opts),
1470114689 },
1470214690 .eflags => |cc| try self.asmSetccRegister(cc, dst_reg.to8()),
1470314691 .immediate => |imm| {
......@@ -16895,13 +16883,10 @@ fn airSelect(self: *Self, inst: Air.Inst.Index) !void {
1689516883 .ty = mask_elem_ty.toIntern(),
1689616884 .storage = .{ .u64 = bit / elem_bits },
1689716885 } });
16898 const mask_mcv = try self.genTypedValue(.{
16899 .ty = mask_ty,
16900 .val = Value.fromInterned(try mod.intern(.{ .aggregate = .{
16901 .ty = mask_ty.toIntern(),
16902 .storage = .{ .elems = mask_elems[0..vec_len] },
16903 } })),
16904 });
16886 const mask_mcv = try self.genTypedValue(Value.fromInterned(try mod.intern(.{ .aggregate = .{
16887 .ty = mask_ty.toIntern(),
16888 .storage = .{ .elems = mask_elems[0..vec_len] },
16889 } })));
1690516890 const mask_mem: Memory = .{
1690616891 .base = .{ .reg = try self.copyToTmpRegister(Type.usize, mask_mcv.address()) },
1690716892 .mod = .{ .rm = .{ .size = self.memSize(ty) } },
......@@ -16923,13 +16908,10 @@ fn airSelect(self: *Self, inst: Air.Inst.Index) !void {
1692316908 .ty = mask_elem_ty.toIntern(),
1692416909 .storage = .{ .u64 = @as(u32, 1) << @intCast(bit & (elem_bits - 1)) },
1692516910 } });
16926 const mask_mcv = try self.genTypedValue(.{
16927 .ty = mask_ty,
16928 .val = Value.fromInterned(try mod.intern(.{ .aggregate = .{
16929 .ty = mask_ty.toIntern(),
16930 .storage = .{ .elems = mask_elems[0..vec_len] },
16931 } })),
16932 });
16911 const mask_mcv = try self.genTypedValue(Value.fromInterned(try mod.intern(.{ .aggregate = .{
16912 .ty = mask_ty.toIntern(),
16913 .storage = .{ .elems = mask_elems[0..vec_len] },
16914 } })));
1693316915 const mask_mem: Memory = .{
1693416916 .base = .{ .reg = try self.copyToTmpRegister(Type.usize, mask_mcv.address()) },
1693516917 .mod = .{ .rm = .{ .size = self.memSize(ty) } },
......@@ -17660,13 +17642,10 @@ fn airShuffle(self: *Self, inst: Air.Inst.Index) !void {
1766017642 else
1766117643 try select_mask_elem_ty.minIntScalar(mod, select_mask_elem_ty)).toIntern();
1766217644 }
17663 const select_mask_mcv = try self.genTypedValue(.{
17664 .ty = select_mask_ty,
17665 .val = Value.fromInterned(try mod.intern(.{ .aggregate = .{
17666 .ty = select_mask_ty.toIntern(),
17667 .storage = .{ .elems = select_mask_elems[0..mask_elems.len] },
17668 } })),
17669 });
17645 const select_mask_mcv = try self.genTypedValue(Value.fromInterned(try mod.intern(.{ .aggregate = .{
17646 .ty = select_mask_ty.toIntern(),
17647 .storage = .{ .elems = select_mask_elems[0..mask_elems.len] },
17648 } })));
1767017649
1767117650 if (self.hasFeature(.sse4_1)) {
1767217651 const mir_tag: Mir.Inst.FixedTag = .{
......@@ -17811,13 +17790,10 @@ fn airShuffle(self: *Self, inst: Air.Inst.Index) !void {
1781117790 } });
1781217791 }
1781317792 const lhs_mask_ty = try mod.vectorType(.{ .len = max_abi_size, .child = .u8_type });
17814 const lhs_mask_mcv = try self.genTypedValue(.{
17815 .ty = lhs_mask_ty,
17816 .val = Value.fromInterned(try mod.intern(.{ .aggregate = .{
17817 .ty = lhs_mask_ty.toIntern(),
17818 .storage = .{ .elems = lhs_mask_elems[0..max_abi_size] },
17819 } })),
17820 });
17793 const lhs_mask_mcv = try self.genTypedValue(Value.fromInterned(try mod.intern(.{ .aggregate = .{
17794 .ty = lhs_mask_ty.toIntern(),
17795 .storage = .{ .elems = lhs_mask_elems[0..max_abi_size] },
17796 } })));
1782117797 const lhs_mask_mem: Memory = .{
1782217798 .base = .{ .reg = try self.copyToTmpRegister(Type.usize, lhs_mask_mcv.address()) },
1782317799 .mod = .{ .rm = .{ .size = Memory.Size.fromSize(@max(max_abi_size, 16)) } },
......@@ -17848,13 +17824,10 @@ fn airShuffle(self: *Self, inst: Air.Inst.Index) !void {
1784817824 } });
1784917825 }
1785017826 const rhs_mask_ty = try mod.vectorType(.{ .len = max_abi_size, .child = .u8_type });
17851 const rhs_mask_mcv = try self.genTypedValue(.{
17852 .ty = rhs_mask_ty,
17853 .val = Value.fromInterned(try mod.intern(.{ .aggregate = .{
17854 .ty = rhs_mask_ty.toIntern(),
17855 .storage = .{ .elems = rhs_mask_elems[0..max_abi_size] },
17856 } })),
17857 });
17827 const rhs_mask_mcv = try self.genTypedValue(Value.fromInterned(try mod.intern(.{ .aggregate = .{
17828 .ty = rhs_mask_ty.toIntern(),
17829 .storage = .{ .elems = rhs_mask_elems[0..max_abi_size] },
17830 } })));
1785817831 const rhs_mask_mem: Memory = .{
1785917832 .base = .{ .reg = try self.copyToTmpRegister(Type.usize, rhs_mask_mcv.address()) },
1786017833 .mod = .{ .rm = .{ .size = Memory.Size.fromSize(@max(max_abi_size, 16)) } },
......@@ -17903,11 +17876,8 @@ fn airShuffle(self: *Self, inst: Air.Inst.Index) !void {
1790317876
1790417877 break :result null;
1790517878 }) orelse return self.fail("TODO implement airShuffle from {} and {} to {} with {}", .{
17906 lhs_ty.fmt(mod), rhs_ty.fmt(mod), dst_ty.fmt(mod),
17907 Value.fromInterned(extra.mask).fmtValue(
17908 Type.fromInterned(mod.intern_pool.typeOf(extra.mask)),
17909 mod,
17910 ),
17879 lhs_ty.fmt(mod), rhs_ty.fmt(mod), dst_ty.fmt(mod),
17880 Value.fromInterned(extra.mask).fmtValue(mod),
1791117881 });
1791217882 return self.finishAir(inst, result, .{ extra.a, extra.b, .none });
1791317883}
......@@ -18140,7 +18110,7 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {
1814018110 .{ .frame = frame_index },
1814118111 @intCast(elem_size * elements.len),
1814218112 elem_ty,
18143 try self.genTypedValue(.{ .ty = elem_ty, .val = sentinel }),
18113 try self.genTypedValue(sentinel),
1814418114 .{},
1814518115 );
1814618116 break :result .{ .load_frame = .{ .index = frame_index } };
......@@ -18664,7 +18634,7 @@ fn resolveInst(self: *Self, ref: Air.Inst.Ref) InnerError!MCValue {
1866418634 const ip_index = ref.toInterned().?;
1866518635 const gop = try self.const_tracking.getOrPut(self.gpa, ip_index);
1866618636 if (!gop.found_existing) gop.value_ptr.* = InstTracking.init(init: {
18667 const const_mcv = try self.genTypedValue(.{ .ty = ty, .val = Value.fromInterned(ip_index) });
18637 const const_mcv = try self.genTypedValue(Value.fromInterned(ip_index));
1866818638 switch (const_mcv) {
1866918639 .lea_tlv => |tlv_sym| switch (self.bin_file.tag) {
1867018640 .elf, .macho => {
......@@ -18729,9 +18699,9 @@ fn limitImmediateType(self: *Self, operand: Air.Inst.Ref, comptime T: type) !MCV
1872918699 return mcv;
1873018700}
1873118701
18732fn genTypedValue(self: *Self, arg_tv: TypedValue) InnerError!MCValue {
18702fn genTypedValue(self: *Self, val: Value) InnerError!MCValue {
1873318703 const mod = self.bin_file.comp.module.?;
18734 return switch (try codegen.genTypedValue(self.bin_file, self.src_loc, arg_tv, self.owner.getDecl(mod))) {
18704 return switch (try codegen.genTypedValue(self.bin_file, self.src_loc, val, self.owner.getDecl(mod))) {
1873518705 .mcv => |mcv| switch (mcv) {
1873618706 .none => .none,
1873718707 .undef => .undef,
src/codegen.zig+123-177
......@@ -19,7 +19,6 @@ const Liveness = @import("Liveness.zig");
1919const Module = @import("Module.zig");
2020const Target = std.Target;
2121const Type = @import("type.zig").Type;
22const TypedValue = @import("TypedValue.zig");
2322const Value = @import("Value.zig");
2423const Zir = std.zig.Zir;
2524const Alignment = InternPool.Alignment;
......@@ -171,7 +170,7 @@ pub fn generateLazySymbol(
171170pub fn generateSymbol(
172171 bin_file: *link.File,
173172 src_loc: Module.SrcLoc,
174 arg_tv: TypedValue,
173 val: Value,
175174 code: *std.ArrayList(u8),
176175 debug_output: DebugInfoOutput,
177176 reloc_info: RelocInfo,
......@@ -181,23 +180,20 @@ pub fn generateSymbol(
181180
182181 const mod = bin_file.comp.module.?;
183182 const ip = &mod.intern_pool;
184 const typed_value = arg_tv;
183 const ty = val.typeOf(mod);
185184
186185 const target = mod.getTarget();
187186 const endian = target.cpu.arch.endian();
188187
189 log.debug("generateSymbol: ty = {}, val = {}", .{
190 typed_value.ty.fmt(mod),
191 typed_value.val.fmtValue(typed_value.ty, mod),
192 });
188 log.debug("generateSymbol: val = {}", .{val.fmtValue(mod)});
193189
194 if (typed_value.val.isUndefDeep(mod)) {
195 const abi_size = math.cast(usize, typed_value.ty.abiSize(mod)) orelse return error.Overflow;
190 if (val.isUndefDeep(mod)) {
191 const abi_size = math.cast(usize, ty.abiSize(mod)) orelse return error.Overflow;
196192 try code.appendNTimes(0xaa, abi_size);
197193 return .ok;
198194 }
199195
200 switch (ip.indexToKey(typed_value.val.toIntern())) {
196 switch (ip.indexToKey(val.toIntern())) {
201197 .int_type,
202198 .ptr_type,
203199 .array_type,
......@@ -238,17 +234,17 @@ pub fn generateSymbol(
238234 .empty_enum_value,
239235 => unreachable, // non-runtime values
240236 .int => {
241 const abi_size = math.cast(usize, typed_value.ty.abiSize(mod)) orelse return error.Overflow;
237 const abi_size = math.cast(usize, ty.abiSize(mod)) orelse return error.Overflow;
242238 var space: Value.BigIntSpace = undefined;
243 const val = typed_value.val.toBigInt(&space, mod);
244 val.writeTwosComplement(try code.addManyAsSlice(abi_size), endian);
239 const int_val = val.toBigInt(&space, mod);
240 int_val.writeTwosComplement(try code.addManyAsSlice(abi_size), endian);
245241 },
246242 .err => |err| {
247243 const int = try mod.getErrorValue(err.name);
248244 try code.writer().writeInt(u16, @as(u16, @intCast(int)), endian);
249245 },
250246 .error_union => |error_union| {
251 const payload_ty = typed_value.ty.errorUnionPayload(mod);
247 const payload_ty = ty.errorUnionPayload(mod);
252248 const err_val = switch (error_union.val) {
253249 .err_name => |err_name| @as(u16, @intCast(try mod.getErrorValue(err_name))),
254250 .payload => @as(u16, 0),
......@@ -261,7 +257,7 @@ pub fn generateSymbol(
261257
262258 const payload_align = payload_ty.abiAlignment(mod);
263259 const error_align = Type.anyerror.abiAlignment(mod);
264 const abi_align = typed_value.ty.abiAlignment(mod);
260 const abi_align = ty.abiAlignment(mod);
265261
266262 // error value first when its type is larger than the error union's payload
267263 if (error_align.order(payload_align) == .gt) {
......@@ -271,13 +267,10 @@ pub fn generateSymbol(
271267 // emit payload part of the error union
272268 {
273269 const begin = code.items.len;
274 switch (try generateSymbol(bin_file, src_loc, .{
275 .ty = payload_ty,
276 .val = Value.fromInterned(switch (error_union.val) {
277 .err_name => try mod.intern(.{ .undef = payload_ty.toIntern() }),
278 .payload => |payload| payload,
279 }),
280 }, code, debug_output, reloc_info)) {
270 switch (try generateSymbol(bin_file, src_loc, Value.fromInterned(switch (error_union.val) {
271 .err_name => try mod.intern(.{ .undef = payload_ty.toIntern() }),
272 .payload => |payload| payload,
273 }), code, debug_output, reloc_info)) {
281274 .ok => {},
282275 .fail => |em| return .{ .fail = em },
283276 }
......@@ -304,11 +297,8 @@ pub fn generateSymbol(
304297 }
305298 },
306299 .enum_tag => |enum_tag| {
307 const int_tag_ty = typed_value.ty.intTagType(mod);
308 switch (try generateSymbol(bin_file, src_loc, .{
309 .ty = int_tag_ty,
310 .val = try mod.getCoerced(Value.fromInterned(enum_tag.int), int_tag_ty),
311 }, code, debug_output, reloc_info)) {
300 const int_tag_ty = ty.intTagType(mod);
301 switch (try generateSymbol(bin_file, src_loc, try mod.getCoerced(Value.fromInterned(enum_tag.int), int_tag_ty), code, debug_output, reloc_info)) {
312302 .ok => {},
313303 .fail => |em| return .{ .fail = em },
314304 }
......@@ -319,42 +309,33 @@ pub fn generateSymbol(
319309 .f64 => |f64_val| writeFloat(f64, f64_val, target, endian, try code.addManyAsArray(8)),
320310 .f80 => |f80_val| {
321311 writeFloat(f80, f80_val, target, endian, try code.addManyAsArray(10));
322 const abi_size = math.cast(usize, typed_value.ty.abiSize(mod)) orelse return error.Overflow;
312 const abi_size = math.cast(usize, ty.abiSize(mod)) orelse return error.Overflow;
323313 try code.appendNTimes(0, abi_size - 10);
324314 },
325315 .f128 => |f128_val| writeFloat(f128, f128_val, target, endian, try code.addManyAsArray(16)),
326316 },
327 .ptr => switch (try lowerParentPtr(bin_file, src_loc, typed_value.val.toIntern(), code, debug_output, reloc_info)) {
317 .ptr => switch (try lowerParentPtr(bin_file, src_loc, val.toIntern(), code, debug_output, reloc_info)) {
328318 .ok => {},
329319 .fail => |em| return .{ .fail = em },
330320 },
331321 .slice => |slice| {
332 switch (try generateSymbol(bin_file, src_loc, .{
333 .ty = typed_value.ty.slicePtrFieldType(mod),
334 .val = Value.fromInterned(slice.ptr),
335 }, code, debug_output, reloc_info)) {
322 switch (try generateSymbol(bin_file, src_loc, Value.fromInterned(slice.ptr), code, debug_output, reloc_info)) {
336323 .ok => {},
337324 .fail => |em| return .{ .fail = em },
338325 }
339 switch (try generateSymbol(bin_file, src_loc, .{
340 .ty = Type.usize,
341 .val = Value.fromInterned(slice.len),
342 }, code, debug_output, reloc_info)) {
326 switch (try generateSymbol(bin_file, src_loc, Value.fromInterned(slice.len), code, debug_output, reloc_info)) {
343327 .ok => {},
344328 .fail => |em| return .{ .fail = em },
345329 }
346330 },
347331 .opt => {
348 const payload_type = typed_value.ty.optionalChild(mod);
349 const payload_val = typed_value.val.optionalValue(mod);
350 const abi_size = math.cast(usize, typed_value.ty.abiSize(mod)) orelse return error.Overflow;
332 const payload_type = ty.optionalChild(mod);
333 const payload_val = val.optionalValue(mod);
334 const abi_size = math.cast(usize, ty.abiSize(mod)) orelse return error.Overflow;
351335
352 if (typed_value.ty.optionalReprIsPayload(mod)) {
336 if (ty.optionalReprIsPayload(mod)) {
353337 if (payload_val) |value| {
354 switch (try generateSymbol(bin_file, src_loc, .{
355 .ty = payload_type,
356 .val = value,
357 }, code, debug_output, reloc_info)) {
338 switch (try generateSymbol(bin_file, src_loc, value, code, debug_output, reloc_info)) {
358339 .ok => {},
359340 .fail => |em| return Result{ .fail = em },
360341 }
......@@ -365,10 +346,7 @@ pub fn generateSymbol(
365346 const padding = abi_size - (math.cast(usize, payload_type.abiSize(mod)) orelse return error.Overflow) - 1;
366347 if (payload_type.hasRuntimeBits(mod)) {
367348 const value = payload_val orelse Value.fromInterned((try mod.intern(.{ .undef = payload_type.toIntern() })));
368 switch (try generateSymbol(bin_file, src_loc, .{
369 .ty = payload_type,
370 .val = value,
371 }, code, debug_output, reloc_info)) {
349 switch (try generateSymbol(bin_file, src_loc, value, code, debug_output, reloc_info)) {
372350 .ok => {},
373351 .fail => |em| return Result{ .fail = em },
374352 }
......@@ -377,7 +355,7 @@ pub fn generateSymbol(
377355 try code.appendNTimes(0, padding);
378356 }
379357 },
380 .aggregate => |aggregate| switch (ip.indexToKey(typed_value.ty.toIntern())) {
358 .aggregate => |aggregate| switch (ip.indexToKey(ty.toIntern())) {
381359 .array_type => |array_type| switch (aggregate.storage) {
382360 .bytes => |bytes| try code.appendSlice(bytes),
383361 .elems, .repeated_elem => {
......@@ -385,17 +363,14 @@ pub fn generateSymbol(
385363 const len_including_sentinel =
386364 array_type.len + @intFromBool(array_type.sentinel != .none);
387365 while (index < len_including_sentinel) : (index += 1) {
388 switch (try generateSymbol(bin_file, src_loc, .{
389 .ty = Type.fromInterned(array_type.child),
390 .val = Value.fromInterned(switch (aggregate.storage) {
391 .bytes => unreachable,
392 .elems => |elems| elems[@as(usize, @intCast(index))],
393 .repeated_elem => |elem| if (index < array_type.len)
394 elem
395 else
396 array_type.sentinel,
397 }),
398 }, code, debug_output, reloc_info)) {
366 switch (try generateSymbol(bin_file, src_loc, Value.fromInterned(switch (aggregate.storage) {
367 .bytes => unreachable,
368 .elems => |elems| elems[@as(usize, @intCast(index))],
369 .repeated_elem => |elem| if (index < array_type.len)
370 elem
371 else
372 array_type.sentinel,
373 }), code, debug_output, reloc_info)) {
399374 .ok => {},
400375 .fail => |em| return .{ .fail = em },
401376 }
......@@ -403,7 +378,7 @@ pub fn generateSymbol(
403378 },
404379 },
405380 .vector_type => |vector_type| {
406 const abi_size = math.cast(usize, typed_value.ty.abiSize(mod)) orelse
381 const abi_size = math.cast(usize, ty.abiSize(mod)) orelse
407382 return error.Overflow;
408383 if (vector_type.child == .bool_type) {
409384 const bytes = try code.addManyAsSlice(abi_size);
......@@ -449,16 +424,13 @@ pub fn generateSymbol(
449424 .elems, .repeated_elem => {
450425 var index: u64 = 0;
451426 while (index < vector_type.len) : (index += 1) {
452 switch (try generateSymbol(bin_file, src_loc, .{
453 .ty = Type.fromInterned(vector_type.child),
454 .val = Value.fromInterned(switch (aggregate.storage) {
455 .bytes => unreachable,
456 .elems => |elems| elems[
457 math.cast(usize, index) orelse return error.Overflow
458 ],
459 .repeated_elem => |elem| elem,
460 }),
461 }, code, debug_output, reloc_info)) {
427 switch (try generateSymbol(bin_file, src_loc, Value.fromInterned(switch (aggregate.storage) {
428 .bytes => unreachable,
429 .elems => |elems| elems[
430 math.cast(usize, index) orelse return error.Overflow
431 ],
432 .repeated_elem => |elem| elem,
433 }), code, debug_output, reloc_info)) {
462434 .ok => {},
463435 .fail => |em| return .{ .fail = em },
464436 }
......@@ -491,17 +463,14 @@ pub fn generateSymbol(
491463 .repeated_elem => |elem| elem,
492464 };
493465
494 switch (try generateSymbol(bin_file, src_loc, .{
495 .ty = Type.fromInterned(field_ty),
496 .val = Value.fromInterned(field_val),
497 }, code, debug_output, reloc_info)) {
466 switch (try generateSymbol(bin_file, src_loc, Value.fromInterned(field_val), code, debug_output, reloc_info)) {
498467 .ok => {},
499468 .fail => |em| return Result{ .fail = em },
500469 }
501470 const unpadded_field_end = code.items.len - struct_begin;
502471
503472 // Pad struct members if required
504 const padded_field_end = typed_value.ty.structFieldOffset(index + 1, mod);
473 const padded_field_end = ty.structFieldOffset(index + 1, mod);
505474 const padding = math.cast(usize, padded_field_end - unpadded_field_end) orelse
506475 return error.Overflow;
507476
......@@ -511,10 +480,10 @@ pub fn generateSymbol(
511480 }
512481 },
513482 .struct_type => {
514 const struct_type = ip.loadStructType(typed_value.ty.toIntern());
483 const struct_type = ip.loadStructType(ty.toIntern());
515484 switch (struct_type.layout) {
516485 .@"packed" => {
517 const abi_size = math.cast(usize, typed_value.ty.abiSize(mod)) orelse
486 const abi_size = math.cast(usize, ty.abiSize(mod)) orelse
518487 return error.Overflow;
519488 const current_pos = code.items.len;
520489 try code.resize(current_pos + abi_size);
......@@ -537,10 +506,7 @@ pub fn generateSymbol(
537506 return error.Overflow;
538507 var tmp_list = try std.ArrayList(u8).initCapacity(code.allocator, field_size);
539508 defer tmp_list.deinit();
540 switch (try generateSymbol(bin_file, src_loc, .{
541 .ty = Type.fromInterned(field_ty),
542 .val = Value.fromInterned(field_val),
543 }, &tmp_list, debug_output, reloc_info)) {
509 switch (try generateSymbol(bin_file, src_loc, Value.fromInterned(field_val), &tmp_list, debug_output, reloc_info)) {
544510 .ok => @memcpy(code.items[current_pos..][0..tmp_list.items.len], tmp_list.items),
545511 .fail => |em| return Result{ .fail = em },
546512 }
......@@ -560,7 +526,7 @@ pub fn generateSymbol(
560526 const field_ty = field_types[field_index];
561527 if (!Type.fromInterned(field_ty).hasRuntimeBits(mod)) continue;
562528
563 const field_val = switch (ip.indexToKey(typed_value.val.toIntern()).aggregate.storage) {
529 const field_val = switch (ip.indexToKey(val.toIntern()).aggregate.storage) {
564530 .bytes => |bytes| try ip.get(mod.gpa, .{ .int = .{
565531 .ty = field_ty,
566532 .storage = .{ .u64 = bytes[field_index] },
......@@ -575,10 +541,7 @@ pub fn generateSymbol(
575541 ) orelse return error.Overflow;
576542 if (padding > 0) try code.appendNTimes(0, padding);
577543
578 switch (try generateSymbol(bin_file, src_loc, .{
579 .ty = Type.fromInterned(field_ty),
580 .val = Value.fromInterned(field_val),
581 }, code, debug_output, reloc_info)) {
544 switch (try generateSymbol(bin_file, src_loc, Value.fromInterned(field_val), code, debug_output, reloc_info)) {
582545 .ok => {},
583546 .fail => |em| return Result{ .fail = em },
584547 }
......@@ -599,37 +562,28 @@ pub fn generateSymbol(
599562 else => unreachable,
600563 },
601564 .un => |un| {
602 const layout = typed_value.ty.unionGetLayout(mod);
565 const layout = ty.unionGetLayout(mod);
603566
604567 if (layout.payload_size == 0) {
605 return generateSymbol(bin_file, src_loc, .{
606 .ty = typed_value.ty.unionTagTypeSafety(mod).?,
607 .val = Value.fromInterned(un.tag),
608 }, code, debug_output, reloc_info);
568 return generateSymbol(bin_file, src_loc, Value.fromInterned(un.tag), code, debug_output, reloc_info);
609569 }
610570
611571 // Check if we should store the tag first.
612572 if (layout.tag_size > 0 and layout.tag_align.compare(.gte, layout.payload_align)) {
613 switch (try generateSymbol(bin_file, src_loc, .{
614 .ty = typed_value.ty.unionTagTypeSafety(mod).?,
615 .val = Value.fromInterned(un.tag),
616 }, code, debug_output, reloc_info)) {
573 switch (try generateSymbol(bin_file, src_loc, Value.fromInterned(un.tag), code, debug_output, reloc_info)) {
617574 .ok => {},
618575 .fail => |em| return Result{ .fail = em },
619576 }
620577 }
621578
622 const union_obj = mod.typeToUnion(typed_value.ty).?;
579 const union_obj = mod.typeToUnion(ty).?;
623580 if (un.tag != .none) {
624 const field_index = typed_value.ty.unionTagFieldIndex(Value.fromInterned(un.tag), mod).?;
581 const field_index = ty.unionTagFieldIndex(Value.fromInterned(un.tag), mod).?;
625582 const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_index]);
626583 if (!field_ty.hasRuntimeBits(mod)) {
627584 try code.appendNTimes(0xaa, math.cast(usize, layout.payload_size) orelse return error.Overflow);
628585 } else {
629 switch (try generateSymbol(bin_file, src_loc, .{
630 .ty = field_ty,
631 .val = Value.fromInterned(un.val),
632 }, code, debug_output, reloc_info)) {
586 switch (try generateSymbol(bin_file, src_loc, Value.fromInterned(un.val), code, debug_output, reloc_info)) {
633587 .ok => {},
634588 .fail => |em| return Result{ .fail = em },
635589 }
......@@ -640,20 +594,14 @@ pub fn generateSymbol(
640594 }
641595 }
642596 } else {
643 switch (try generateSymbol(bin_file, src_loc, .{
644 .ty = Type.fromInterned(ip.typeOf(un.val)),
645 .val = Value.fromInterned(un.val),
646 }, code, debug_output, reloc_info)) {
597 switch (try generateSymbol(bin_file, src_loc, Value.fromInterned(un.val), code, debug_output, reloc_info)) {
647598 .ok => {},
648599 .fail => |em| return Result{ .fail = em },
649600 }
650601 }
651602
652603 if (layout.tag_size > 0 and layout.tag_align.compare(.lt, layout.payload_align)) {
653 switch (try generateSymbol(bin_file, src_loc, .{
654 .ty = Type.fromInterned(union_obj.enum_tag_ty),
655 .val = Value.fromInterned(un.tag),
656 }, code, debug_output, reloc_info)) {
604 switch (try generateSymbol(bin_file, src_loc, Value.fromInterned(un.tag), code, debug_output, reloc_info)) {
657605 .ok => {},
658606 .fail => |em| return Result{ .fail = em },
659607 }
......@@ -681,10 +629,7 @@ fn lowerParentPtr(
681629 return switch (ptr.addr) {
682630 .decl => |decl| try lowerDeclRef(bin_file, src_loc, decl, code, debug_output, reloc_info),
683631 .anon_decl => |ad| try lowerAnonDeclRef(bin_file, src_loc, ad, code, debug_output, reloc_info),
684 .int => |int| try generateSymbol(bin_file, src_loc, .{
685 .ty = Type.usize,
686 .val = Value.fromInterned(int),
687 }, code, debug_output, reloc_info),
632 .int => |int| try generateSymbol(bin_file, src_loc, Value.fromInterned(int), code, debug_output, reloc_info),
688633 .eu_payload => |eu_payload| try lowerParentPtr(
689634 bin_file,
690635 src_loc,
......@@ -829,14 +774,12 @@ fn lowerDeclRef(
829774 const target = namespace.file_scope.mod.resolved_target.result;
830775
831776 const ptr_width = target.ptrBitWidth();
832 const is_fn_body = decl.ty.zigTypeTag(zcu) == .Fn;
833 if (!is_fn_body and !decl.ty.hasRuntimeBits(zcu)) {
777 const is_fn_body = decl.typeOf(zcu).zigTypeTag(zcu) == .Fn;
778 if (!is_fn_body and !decl.typeOf(zcu).hasRuntimeBits(zcu)) {
834779 try code.appendNTimes(0xaa, @divExact(ptr_width, 8));
835780 return Result.ok;
836781 }
837782
838 try zcu.markDeclAlive(decl);
839
840783 const vaddr = try lf.getDeclVAddr(decl_index, .{
841784 .parent_atom_index = reloc_info.parent_atom_index,
842785 .offset = code.items.len,
......@@ -912,11 +855,12 @@ pub const GenResult = union(enum) {
912855fn genDeclRef(
913856 lf: *link.File,
914857 src_loc: Module.SrcLoc,
915 tv: TypedValue,
858 val: Value,
916859 ptr_decl_index: InternPool.DeclIndex,
917860) CodeGenError!GenResult {
918861 const zcu = lf.comp.module.?;
919 log.debug("genDeclRef: ty = {}, val = {}", .{ tv.ty.fmt(zcu), tv.val.fmtValue(tv.ty, zcu) });
862 const ty = val.typeOf(zcu);
863 log.debug("genDeclRef: val = {}", .{val.fmtValue(zcu)});
920864
921865 const ptr_decl = zcu.declPtr(ptr_decl_index);
922866 const namespace = zcu.namespacePtr(ptr_decl.src_namespace);
......@@ -925,14 +869,14 @@ fn genDeclRef(
925869 const ptr_bits = target.ptrBitWidth();
926870 const ptr_bytes: u64 = @divExact(ptr_bits, 8);
927871
928 const decl_index = switch (zcu.intern_pool.indexToKey(try ptr_decl.internValue(zcu))) {
872 const decl_index = switch (zcu.intern_pool.indexToKey(ptr_decl.val.toIntern())) {
929873 .func => |func| func.owner_decl,
930874 .extern_func => |extern_func| extern_func.decl,
931875 else => ptr_decl_index,
932876 };
933877 const decl = zcu.declPtr(decl_index);
934878
935 if (!decl.ty.isFnOrHasRuntimeBitsIgnoreComptime(zcu)) {
879 if (!decl.typeOf(zcu).isFnOrHasRuntimeBitsIgnoreComptime(zcu)) {
936880 const imm: u64 = switch (ptr_bytes) {
937881 1 => 0xaa,
938882 2 => 0xaaaa,
......@@ -947,22 +891,20 @@ fn genDeclRef(
947891 const gpa = comp.gpa;
948892
949893 // TODO this feels clunky. Perhaps we should check for it in `genTypedValue`?
950 if (tv.ty.castPtrToFn(zcu)) |fn_ty| {
894 if (ty.castPtrToFn(zcu)) |fn_ty| {
951895 if (zcu.typeToFunc(fn_ty).?.is_generic) {
952896 return GenResult.mcv(.{ .immediate = fn_ty.abiAlignment(zcu).toByteUnitsOptional().? });
953897 }
954 } else if (tv.ty.zigTypeTag(zcu) == .Pointer) {
955 const elem_ty = tv.ty.elemType2(zcu);
898 } else if (ty.zigTypeTag(zcu) == .Pointer) {
899 const elem_ty = ty.elemType2(zcu);
956900 if (!elem_ty.hasRuntimeBits(zcu)) {
957901 return GenResult.mcv(.{ .immediate = elem_ty.abiAlignment(zcu).toByteUnitsOptional().? });
958902 }
959903 }
960904
961 try zcu.markDeclAlive(decl);
962
963905 const decl_namespace = zcu.namespacePtr(decl.src_namespace);
964906 const single_threaded = decl_namespace.file_scope.mod.single_threaded;
965 const is_threadlocal = tv.val.isPtrToThreadLocal(zcu) and !single_threaded;
907 const is_threadlocal = val.isPtrToThreadLocal(zcu) and !single_threaded;
966908 const is_extern = decl.isExtern(zcu);
967909
968910 if (lf.cast(link.File.Elf)) |elf_file| {
......@@ -1027,14 +969,14 @@ fn genDeclRef(
1027969fn genUnnamedConst(
1028970 lf: *link.File,
1029971 src_loc: Module.SrcLoc,
1030 tv: TypedValue,
972 val: Value,
1031973 owner_decl_index: InternPool.DeclIndex,
1032974) CodeGenError!GenResult {
1033975 const zcu = lf.comp.module.?;
1034976 const gpa = lf.comp.gpa;
1035 log.debug("genUnnamedConst: ty = {}, val = {}", .{ tv.ty.fmt(zcu), tv.val.fmtValue(tv.ty, zcu) });
977 log.debug("genUnnamedConst: val = {}", .{val.fmtValue(zcu)});
1036978
1037 const local_sym_index = lf.lowerUnnamedConst(tv, owner_decl_index) catch |err| {
979 const local_sym_index = lf.lowerUnnamedConst(val, owner_decl_index) catch |err| {
1038980 return GenResult.fail(gpa, src_loc, "lowering unnamed constant failed: {s}", .{@errorName(err)});
1039981 };
1040982 switch (lf.tag) {
......@@ -1066,18 +1008,15 @@ fn genUnnamedConst(
10661008pub fn genTypedValue(
10671009 lf: *link.File,
10681010 src_loc: Module.SrcLoc,
1069 arg_tv: TypedValue,
1011 val: Value,
10701012 owner_decl_index: InternPool.DeclIndex,
10711013) CodeGenError!GenResult {
10721014 const zcu = lf.comp.module.?;
1073 const typed_value = arg_tv;
1015 const ty = val.typeOf(zcu);
10741016
1075 log.debug("genTypedValue: ty = {}, val = {}", .{
1076 typed_value.ty.fmt(zcu),
1077 typed_value.val.fmtValue(typed_value.ty, zcu),
1078 });
1017 log.debug("genTypedValue: val = {}", .{val.fmtValue(zcu)});
10791018
1080 if (typed_value.val.isUndef(zcu))
1019 if (val.isUndef(zcu))
10811020 return GenResult.mcv(.undef);
10821021
10831022 const owner_decl = zcu.declPtr(owner_decl_index);
......@@ -1085,85 +1024,92 @@ pub fn genTypedValue(
10851024 const target = namespace.file_scope.mod.resolved_target.result;
10861025 const ptr_bits = target.ptrBitWidth();
10871026
1088 if (!typed_value.ty.isSlice(zcu)) switch (zcu.intern_pool.indexToKey(typed_value.val.toIntern())) {
1027 if (!ty.isSlice(zcu)) switch (zcu.intern_pool.indexToKey(val.toIntern())) {
10891028 .ptr => |ptr| switch (ptr.addr) {
1090 .decl => |decl| return genDeclRef(lf, src_loc, typed_value, decl),
1029 .decl => |decl| return genDeclRef(lf, src_loc, val, decl),
10911030 else => {},
10921031 },
10931032 else => {},
10941033 };
10951034
1096 switch (typed_value.ty.zigTypeTag(zcu)) {
1035 switch (ty.zigTypeTag(zcu)) {
10971036 .Void => return GenResult.mcv(.none),
1098 .Pointer => switch (typed_value.ty.ptrSize(zcu)) {
1037 .Pointer => switch (ty.ptrSize(zcu)) {
10991038 .Slice => {},
1100 else => switch (typed_value.val.toIntern()) {
1039 else => switch (val.toIntern()) {
11011040 .null_value => {
11021041 return GenResult.mcv(.{ .immediate = 0 });
11031042 },
11041043 .none => {},
1105 else => switch (zcu.intern_pool.indexToKey(typed_value.val.toIntern())) {
1044 else => switch (zcu.intern_pool.indexToKey(val.toIntern())) {
11061045 .int => {
1107 return GenResult.mcv(.{ .immediate = typed_value.val.toUnsignedInt(zcu) });
1046 return GenResult.mcv(.{ .immediate = val.toUnsignedInt(zcu) });
11081047 },
11091048 else => {},
11101049 },
11111050 },
11121051 },
11131052 .Int => {
1114 const info = typed_value.ty.intInfo(zcu);
1053 const info = ty.intInfo(zcu);
11151054 if (info.bits <= ptr_bits) {
11161055 const unsigned = switch (info.signedness) {
1117 .signed => @as(u64, @bitCast(typed_value.val.toSignedInt(zcu))),
1118 .unsigned => typed_value.val.toUnsignedInt(zcu),
1056 .signed => @as(u64, @bitCast(val.toSignedInt(zcu))),
1057 .unsigned => val.toUnsignedInt(zcu),
11191058 };
11201059 return GenResult.mcv(.{ .immediate = unsigned });
11211060 }
11221061 },
11231062 .Bool => {
1124 return GenResult.mcv(.{ .immediate = @intFromBool(typed_value.val.toBool()) });
1063 return GenResult.mcv(.{ .immediate = @intFromBool(val.toBool()) });
11251064 },
11261065 .Optional => {
1127 if (typed_value.ty.isPtrLikeOptional(zcu)) {
1128 return genTypedValue(lf, src_loc, .{
1129 .ty = typed_value.ty.optionalChild(zcu),
1130 .val = typed_value.val.optionalValue(zcu) orelse return GenResult.mcv(.{ .immediate = 0 }),
1131 }, owner_decl_index);
1132 } else if (typed_value.ty.abiSize(zcu) == 1) {
1133 return GenResult.mcv(.{ .immediate = @intFromBool(!typed_value.val.isNull(zcu)) });
1066 if (ty.isPtrLikeOptional(zcu)) {
1067 return genTypedValue(
1068 lf,
1069 src_loc,
1070 val.optionalValue(zcu) orelse return GenResult.mcv(.{ .immediate = 0 }),
1071 owner_decl_index,
1072 );
1073 } else if (ty.abiSize(zcu) == 1) {
1074 return GenResult.mcv(.{ .immediate = @intFromBool(!val.isNull(zcu)) });
11341075 }
11351076 },
11361077 .Enum => {
1137 const enum_tag = zcu.intern_pool.indexToKey(typed_value.val.toIntern()).enum_tag;
1138 const int_tag_ty = zcu.intern_pool.typeOf(enum_tag.int);
1139 return genTypedValue(lf, src_loc, .{
1140 .ty = Type.fromInterned(int_tag_ty),
1141 .val = Value.fromInterned(enum_tag.int),
1142 }, owner_decl_index);
1078 const enum_tag = zcu.intern_pool.indexToKey(val.toIntern()).enum_tag;
1079 return genTypedValue(
1080 lf,
1081 src_loc,
1082 Value.fromInterned(enum_tag.int),
1083 owner_decl_index,
1084 );
11431085 },
11441086 .ErrorSet => {
1145 const err_name = zcu.intern_pool.indexToKey(typed_value.val.toIntern()).err.name;
1087 const err_name = zcu.intern_pool.indexToKey(val.toIntern()).err.name;
11461088 const error_index = zcu.global_error_set.getIndex(err_name).?;
11471089 return GenResult.mcv(.{ .immediate = error_index });
11481090 },
11491091 .ErrorUnion => {
1150 const err_type = typed_value.ty.errorUnionSet(zcu);
1151 const payload_type = typed_value.ty.errorUnionPayload(zcu);
1092 const err_type = ty.errorUnionSet(zcu);
1093 const payload_type = ty.errorUnionPayload(zcu);
11521094 if (!payload_type.hasRuntimeBitsIgnoreComptime(zcu)) {
11531095 // We use the error type directly as the type.
11541096 const err_int_ty = try zcu.errorIntType();
1155 switch (zcu.intern_pool.indexToKey(typed_value.val.toIntern()).error_union.val) {
1156 .err_name => |err_name| return genTypedValue(lf, src_loc, .{
1157 .ty = err_type,
1158 .val = Value.fromInterned((try zcu.intern(.{ .err = .{
1097 switch (zcu.intern_pool.indexToKey(val.toIntern()).error_union.val) {
1098 .err_name => |err_name| return genTypedValue(
1099 lf,
1100 src_loc,
1101 Value.fromInterned(try zcu.intern(.{ .err = .{
11591102 .ty = err_type.toIntern(),
11601103 .name = err_name,
1161 } }))),
1162 }, owner_decl_index),
1163 .payload => return genTypedValue(lf, src_loc, .{
1164 .ty = err_int_ty,
1165 .val = try zcu.intValue(err_int_ty, 0),
1166 }, owner_decl_index),
1104 } })),
1105 owner_decl_index,
1106 ),
1107 .payload => return genTypedValue(
1108 lf,
1109 src_loc,
1110 try zcu.intValue(err_int_ty, 0),
1111 owner_decl_index,
1112 ),
11671113 }
11681114 }
11691115 },
......@@ -1180,7 +1126,7 @@ pub fn genTypedValue(
11801126 else => {},
11811127 }
11821128
1183 return genUnnamedConst(lf, src_loc, typed_value, owner_decl_index);
1129 return genUnnamedConst(lf, src_loc, val, owner_decl_index);
11841130}
11851131
11861132pub fn errUnionPayloadOffset(payload_ty: Type, mod: *Module) u64 {
src/codegen/c.zig+37-44
......@@ -9,7 +9,6 @@ const Module = @import("../Module.zig");
99const Compilation = @import("../Compilation.zig");
1010const Value = @import("../Value.zig");
1111const Type = @import("../type.zig").Type;
12const TypedValue = @import("../TypedValue.zig");
1312const C = link.File.C;
1413const Decl = Module.Decl;
1514const trace = @import("../tracy.zig").trace;
......@@ -657,7 +656,7 @@ pub const DeclGen = struct {
657656 assert(decl.has_tv);
658657
659658 // Render an undefined pointer if we have a pointer to a zero-bit or comptime type.
660 if (ty.isPtrAtRuntime(mod) and !decl.ty.isFnOrHasRuntimeBits(mod)) {
659 if (ty.isPtrAtRuntime(mod) and !decl.typeOf(mod).isFnOrHasRuntimeBits(mod)) {
661660 return dg.writeCValue(writer, .{ .undef = ty });
662661 }
663662
......@@ -673,7 +672,7 @@ pub const DeclGen = struct {
673672 // them). The analysis until now should ensure that the C function
674673 // pointers are compatible. If they are not, then there is a bug
675674 // somewhere and we should let the C compiler tell us about it.
676 const need_typecast = if (ty.castPtrToFn(mod)) |_| false else !ty.childType(mod).eql(decl.ty, mod);
675 const need_typecast = if (ty.castPtrToFn(mod)) |_| false else !ty.childType(mod).eql(decl.typeOf(mod), mod);
677676 if (need_typecast) {
678677 try writer.writeAll("((");
679678 try dg.renderType(writer, ty);
......@@ -1588,9 +1587,10 @@ pub const DeclGen = struct {
15881587 const ip = &mod.intern_pool;
15891588
15901589 const fn_decl = mod.declPtr(fn_decl_index);
1591 const fn_cty_idx = try dg.typeToIndex(fn_decl.ty, kind);
1590 const fn_ty = fn_decl.typeOf(mod);
1591 const fn_cty_idx = try dg.typeToIndex(fn_ty, kind);
15921592
1593 const fn_info = mod.typeToFunc(fn_decl.ty).?;
1593 const fn_info = mod.typeToFunc(fn_ty).?;
15941594 if (fn_info.cc == .Naked) {
15951595 switch (kind) {
15961596 .forward => try w.writeAll("zig_naked_decl "),
......@@ -1876,9 +1876,9 @@ pub const DeclGen = struct {
18761876 try renderTypeSuffix(dg.pass, store.*, mod, w, cty_idx, .suffix, .{});
18771877 }
18781878
1879 fn declIsGlobal(dg: *DeclGen, tv: TypedValue) bool {
1879 fn declIsGlobal(dg: *DeclGen, val: Value) bool {
18801880 const mod = dg.module;
1881 return switch (mod.intern_pool.indexToKey(tv.val.ip_index)) {
1881 return switch (mod.intern_pool.indexToKey(val.ip_index)) {
18821882 .variable => |variable| mod.decl_exports.contains(variable.decl),
18831883 .extern_func => true,
18841884 .func => |func| mod.decl_exports.contains(func.owner_decl),
......@@ -1971,7 +1971,7 @@ pub const DeclGen = struct {
19711971 ) !void {
19721972 const decl = dg.module.declPtr(decl_index);
19731973 const fwd = dg.fwdDeclWriter();
1974 const is_global = variable.is_extern or dg.declIsGlobal(.{ .ty = decl.ty, .val = decl.val });
1974 const is_global = variable.is_extern or dg.declIsGlobal(decl.val);
19751975 try fwd.writeAll(if (is_global) "zig_extern " else "static ");
19761976 const maybe_exports = dg.module.decl_exports.get(decl_index);
19771977 const export_weak_linkage = if (maybe_exports) |exports|
......@@ -1982,7 +1982,7 @@ pub const DeclGen = struct {
19821982 if (variable.is_threadlocal) try fwd.writeAll("zig_threadlocal ");
19831983 try dg.renderTypeAndName(
19841984 fwd,
1985 decl.ty,
1985 decl.typeOf(dg.module),
19861986 .{ .decl = decl_index },
19871987 CQualifiers.init(.{ .@"const" = variable.is_const }),
19881988 decl.alignment,
......@@ -2009,7 +2009,6 @@ pub const DeclGen = struct {
20092009 fn renderDeclName(dg: *DeclGen, writer: anytype, decl_index: InternPool.DeclIndex, export_index: u32) !void {
20102010 const mod = dg.module;
20112011 const decl = mod.declPtr(decl_index);
2012 try mod.markDeclAlive(decl);
20132012
20142013 if (mod.decl_exports.get(decl_index)) |exports| {
20152014 try writer.print("{ }", .{
......@@ -2656,13 +2655,12 @@ fn genExports(o: *Object) !void {
26562655 .anon, .flush => return,
26572656 };
26582657 const decl = mod.declPtr(decl_index);
2659 const tv: TypedValue = .{ .ty = decl.ty, .val = Value.fromInterned((try decl.internValue(mod))) };
26602658 const fwd = o.dg.fwdDeclWriter();
26612659
26622660 const exports = mod.decl_exports.get(decl_index) orelse return;
26632661 if (exports.items.len < 2) return;
26642662
2665 const is_variable_const = switch (ip.indexToKey(tv.val.toIntern())) {
2663 const is_variable_const = switch (ip.indexToKey(decl.val.toIntern())) {
26662664 .func => return for (exports.items[1..], 1..) |@"export", i| {
26672665 try fwd.writeAll("zig_extern ");
26682666 if (@"export".opts.linkage == .weak) try fwd.writeAll("zig_weak_linkage_fn ");
......@@ -2687,7 +2685,7 @@ fn genExports(o: *Object) !void {
26872685 const export_name = ip.stringToSlice(@"export".opts.name);
26882686 try o.dg.renderTypeAndName(
26892687 fwd,
2690 decl.ty,
2688 decl.typeOf(mod),
26912689 .{ .identifier = export_name },
26922690 CQualifiers.init(.{ .@"const" = is_variable_const }),
26932691 decl.alignment,
......@@ -2769,7 +2767,7 @@ pub fn genLazyFn(o: *Object, lazy_fn: LazyFnMap.Entry) !void {
27692767 },
27702768 .never_tail, .never_inline => |fn_decl_index| {
27712769 const fn_decl = mod.declPtr(fn_decl_index);
2772 const fn_cty = try o.dg.typeToCType(fn_decl.ty, .complete);
2770 const fn_cty = try o.dg.typeToCType(fn_decl.typeOf(mod), .complete);
27732771 const fn_info = fn_cty.cast(CType.Payload.Function).?.data;
27742772
27752773 const fwd_decl_writer = o.dg.fwdDeclWriter();
......@@ -2805,15 +2803,11 @@ pub fn genFunc(f: *Function) !void {
28052803 const gpa = o.dg.gpa;
28062804 const decl_index = o.dg.pass.decl;
28072805 const decl = mod.declPtr(decl_index);
2808 const tv: TypedValue = .{
2809 .ty = decl.ty,
2810 .val = decl.val,
2811 };
28122806
28132807 o.code_header = std.ArrayList(u8).init(gpa);
28142808 defer o.code_header.deinit();
28152809
2816 const is_global = o.dg.declIsGlobal(tv);
2810 const is_global = o.dg.declIsGlobal(decl.val);
28172811 const fwd_decl_writer = o.dg.fwdDeclWriter();
28182812 try fwd_decl_writer.writeAll(if (is_global) "zig_extern " else "static ");
28192813
......@@ -2893,22 +2887,23 @@ pub fn genDecl(o: *Object) !void {
28932887 const mod = o.dg.module;
28942888 const decl_index = o.dg.pass.decl;
28952889 const decl = mod.declPtr(decl_index);
2896 const tv: TypedValue = .{ .ty = decl.ty, .val = Value.fromInterned((try decl.internValue(mod))) };
2890 const decl_val = decl.val;
2891 const decl_ty = decl_val.typeOf(mod);
28972892
2898 if (!tv.ty.isFnOrHasRuntimeBitsIgnoreComptime(mod)) return;
2899 if (tv.val.getExternFunc(mod)) |_| {
2893 if (!decl_ty.isFnOrHasRuntimeBitsIgnoreComptime(mod)) return;
2894 if (decl_val.getExternFunc(mod)) |_| {
29002895 const fwd_decl_writer = o.dg.fwdDeclWriter();
29012896 try fwd_decl_writer.writeAll("zig_extern ");
29022897 try o.dg.renderFunctionSignature(fwd_decl_writer, decl_index, .forward, .{ .export_index = 0 });
29032898 try fwd_decl_writer.writeAll(";\n");
29042899 try genExports(o);
2905 } else if (tv.val.getVariable(mod)) |variable| {
2900 } else if (decl_val.getVariable(mod)) |variable| {
29062901 try o.dg.renderFwdDecl(decl_index, variable, .final);
29072902 try genExports(o);
29082903
29092904 if (variable.is_extern) return;
29102905
2911 const is_global = variable.is_extern or o.dg.declIsGlobal(tv);
2906 const is_global = variable.is_extern or o.dg.declIsGlobal(decl_val);
29122907 const w = o.writer();
29132908 if (!is_global) try w.writeAll("static ");
29142909 if (variable.is_weak_linkage) try w.writeAll("zig_weak_linkage ");
......@@ -2916,22 +2911,22 @@ pub fn genDecl(o: *Object) !void {
29162911 if (mod.intern_pool.stringToSliceUnwrap(decl.@"linksection")) |s|
29172912 try w.print("zig_linksection(\"{s}\", ", .{s});
29182913 const decl_c_value = .{ .decl = decl_index };
2919 try o.dg.renderTypeAndName(w, tv.ty, decl_c_value, .{}, decl.alignment, .complete);
2914 try o.dg.renderTypeAndName(w, decl_ty, decl_c_value, .{}, decl.alignment, .complete);
29202915 if (decl.@"linksection" != .none) try w.writeAll(", read, write)");
29212916 try w.writeAll(" = ");
2922 try o.dg.renderValue(w, tv.ty, Value.fromInterned(variable.init), .StaticInitializer);
2917 try o.dg.renderValue(w, decl_ty, Value.fromInterned(variable.init), .StaticInitializer);
29232918 try w.writeByte(';');
29242919 try o.indent_writer.insertNewline();
29252920 } else {
29262921 const is_global = o.dg.module.decl_exports.contains(decl_index);
29272922 const decl_c_value = .{ .decl = decl_index };
2928 try genDeclValue(o, tv, is_global, decl_c_value, decl.alignment, decl.@"linksection");
2923 try genDeclValue(o, decl_val, is_global, decl_c_value, decl.alignment, decl.@"linksection");
29292924 }
29302925}
29312926
29322927pub fn genDeclValue(
29332928 o: *Object,
2934 tv: TypedValue,
2929 val: Value,
29352930 is_global: bool,
29362931 decl_c_value: CValue,
29372932 alignment: Alignment,
......@@ -2940,8 +2935,10 @@ pub fn genDeclValue(
29402935 const mod = o.dg.module;
29412936 const fwd_decl_writer = o.dg.fwdDeclWriter();
29422937
2938 const ty = val.typeOf(mod);
2939
29432940 try fwd_decl_writer.writeAll(if (is_global) "zig_extern " else "static ");
2944 try o.dg.renderTypeAndName(fwd_decl_writer, tv.ty, decl_c_value, Const, alignment, .complete);
2941 try o.dg.renderTypeAndName(fwd_decl_writer, ty, decl_c_value, Const, alignment, .complete);
29452942 switch (o.dg.pass) {
29462943 .decl => |decl_index| {
29472944 if (mod.decl_exports.get(decl_index)) |exports| {
......@@ -2964,10 +2961,10 @@ pub fn genDeclValue(
29642961
29652962 if (mod.intern_pool.stringToSliceUnwrap(link_section)) |s|
29662963 try w.print("zig_linksection(\"{s}\", ", .{s});
2967 try o.dg.renderTypeAndName(w, tv.ty, decl_c_value, Const, alignment, .complete);
2964 try o.dg.renderTypeAndName(w, ty, decl_c_value, Const, alignment, .complete);
29682965 if (link_section != .none) try w.writeAll(", read)");
29692966 try w.writeAll(" = ");
2970 try o.dg.renderValue(w, tv.ty, tv.val, .StaticInitializer);
2967 try o.dg.renderValue(w, ty, val, .StaticInitializer);
29712968 try w.writeAll(";\n");
29722969}
29732970
......@@ -2978,14 +2975,10 @@ pub fn genHeader(dg: *DeclGen) error{ AnalysisFail, OutOfMemory }!void {
29782975 const mod = dg.module;
29792976 const decl_index = dg.pass.decl;
29802977 const decl = mod.declPtr(decl_index);
2981 const tv: TypedValue = .{
2982 .ty = decl.ty,
2983 .val = decl.val,
2984 };
29852978 const writer = dg.fwdDeclWriter();
29862979
2987 switch (tv.ty.zigTypeTag(mod)) {
2988 .Fn => if (dg.declIsGlobal(tv)) {
2980 switch (decl.val.typeOf(mod).zigTypeTag(mod)) {
2981 .Fn => if (dg.declIsGlobal(decl.val)) {
29892982 try writer.writeAll("zig_extern ");
29902983 try dg.renderFunctionSignature(writer, dg.pass.decl, .complete, .{ .export_index = 0 });
29912984 try dg.fwd_decl.appendSlice(";\n");
......@@ -5304,25 +5297,25 @@ fn airIsNull(
53045297 const err_int_ty = try mod.errorIntType();
53055298
53065299 const rhs = if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod))
5307 TypedValue{ .ty = Type.bool, .val = Value.true }
5300 Value.true
53085301 else if (optional_ty.isPtrLikeOptional(mod))
53095302 // operand is a regular pointer, test `operand !=/== NULL`
5310 TypedValue{ .ty = optional_ty, .val = try mod.getCoerced(Value.null, optional_ty) }
5303 try mod.getCoerced(Value.null, optional_ty)
53115304 else if (payload_ty.zigTypeTag(mod) == .ErrorSet)
5312 TypedValue{ .ty = err_int_ty, .val = try mod.intValue(err_int_ty, 0) }
5305 try mod.intValue(err_int_ty, 0)
53135306 else if (payload_ty.isSlice(mod) and optional_ty.optionalReprIsPayload(mod)) rhs: {
53145307 try writer.writeAll(".ptr");
53155308 const slice_ptr_ty = payload_ty.slicePtrFieldType(mod);
53165309 const opt_slice_ptr_ty = try mod.optionalType(slice_ptr_ty.toIntern());
5317 break :rhs TypedValue{ .ty = opt_slice_ptr_ty, .val = try mod.nullValue(opt_slice_ptr_ty) };
5310 break :rhs try mod.nullValue(opt_slice_ptr_ty);
53185311 } else rhs: {
53195312 try writer.writeAll(".is_null");
5320 break :rhs TypedValue{ .ty = Type.bool, .val = Value.true };
5313 break :rhs Value.true;
53215314 };
53225315 try writer.writeByte(' ');
53235316 try writer.writeAll(operator);
53245317 try writer.writeByte(' ');
5325 try f.object.dg.renderValue(writer, rhs.ty, rhs.val, .Other);
5318 try f.object.dg.renderValue(writer, rhs.typeOf(mod), rhs, .Other);
53265319 try writer.writeAll(";\n");
53275320 return local;
53285321}
......@@ -7392,7 +7385,7 @@ fn airCVaStart(f: *Function, inst: Air.Inst.Index) !CValue {
73927385 const inst_ty = f.typeOfIndex(inst);
73937386 const decl_index = f.object.dg.pass.decl;
73947387 const decl = mod.declPtr(decl_index);
7395 const fn_cty = try f.typeToCType(decl.ty, .complete);
7388 const fn_cty = try f.typeToCType(decl.typeOf(mod), .complete);
73967389 const param_len = fn_cty.castTag(.varargs_function).?.data.param_types.len;
73977390
73987391 const writer = f.object.writer();
src/codegen/llvm.zig+27-40
......@@ -18,7 +18,6 @@ const Module = @import("../Module.zig");
1818const Zcu = Module;
1919const InternPool = @import("../InternPool.zig");
2020const Package = @import("../Package.zig");
21const TypedValue = @import("../TypedValue.zig");
2221const Air = @import("../Air.zig");
2322const Liveness = @import("../Liveness.zig");
2423const Value = @import("../Value.zig");
......@@ -1384,7 +1383,7 @@ pub const Object = struct {
13841383 const decl = zcu.declPtr(decl_index);
13851384 const namespace = zcu.namespacePtr(decl.src_namespace);
13861385 const owner_mod = namespace.file_scope.mod;
1387 const fn_info = zcu.typeToFunc(decl.ty).?;
1386 const fn_info = zcu.typeToFunc(decl.typeOf(zcu)).?;
13881387 const target = zcu.getTarget();
13891388 const ip = &zcu.intern_pool;
13901389
......@@ -1659,7 +1658,7 @@ pub const Object = struct {
16591658 const line_number = decl.src_line + 1;
16601659 const is_internal_linkage = decl.val.getExternFunc(zcu) == null and
16611660 !zcu.decl_exports.contains(decl_index);
1662 const debug_decl_type = try o.lowerDebugType(decl.ty);
1661 const debug_decl_type = try o.lowerDebugType(decl.typeOf(zcu));
16631662
16641663 const subprogram = try o.builder.debugSubprogram(
16651664 file,
......@@ -1762,7 +1761,7 @@ pub const Object = struct {
17621761 const decl_name = decl_name: {
17631762 const decl_name = mod.intern_pool.stringToSlice(decl.name);
17641763
1765 if (mod.getTarget().isWasm() and try decl.isFunction(mod)) {
1764 if (mod.getTarget().isWasm() and decl.val.typeOf(mod).zigTypeTag(mod) == .Fn) {
17661765 if (mod.intern_pool.stringToSliceUnwrap(decl.getOwnedExternFunc(mod).?.lib_name)) |lib_name| {
17671766 if (!std.mem.eql(u8, lib_name, "c")) {
17681767 break :decl_name try self.builder.strtabStringFmt("{s}|{s}", .{ decl_name, lib_name });
......@@ -2881,7 +2880,7 @@ pub const Object = struct {
28812880 const decl = zcu.declPtr(decl_index);
28822881 const namespace = zcu.namespacePtr(decl.src_namespace);
28832882 const owner_mod = namespace.file_scope.mod;
2884 const zig_fn_type = decl.ty;
2883 const zig_fn_type = decl.typeOf(zcu);
28852884 const gop = try o.decl_map.getOrPut(gpa, decl_index);
28862885 if (gop.found_existing) return gop.value_ptr.ptr(&o.builder).kind.function;
28872886
......@@ -3112,7 +3111,7 @@ pub const Object = struct {
31123111 try o.builder.strtabString(mod.intern_pool.stringToSlice(
31133112 if (is_extern) decl.name else try decl.fullyQualifiedName(mod),
31143113 )),
3115 try o.lowerType(decl.ty),
3114 try o.lowerType(decl.typeOf(mod)),
31163115 toLlvmGlobalAddressSpace(decl.@"addrspace", mod.getTarget()),
31173116 );
31183117 gop.value_ptr.* = variable_index.ptrConst(&o.builder).global;
......@@ -3722,15 +3721,11 @@ pub const Object = struct {
37223721 => unreachable, // non-runtime values
37233722 .extern_func => |extern_func| {
37243723 const fn_decl_index = extern_func.decl;
3725 const fn_decl = mod.declPtr(fn_decl_index);
3726 try mod.markDeclAlive(fn_decl);
37273724 const function_index = try o.resolveLlvmFunction(fn_decl_index);
37283725 return function_index.ptrConst(&o.builder).global.toConst();
37293726 },
37303727 .func => |func| {
37313728 const fn_decl_index = func.owner_decl;
3732 const fn_decl = mod.declPtr(fn_decl_index);
3733 try mod.markDeclAlive(fn_decl);
37343729 const function_index = try o.resolveLlvmFunction(fn_decl_index);
37353730 return function_index.ptrConst(&o.builder).global.toConst();
37363731 },
......@@ -4262,8 +4257,7 @@ pub const Object = struct {
42624257 fn lowerParentPtrDecl(o: *Object, decl_index: InternPool.DeclIndex) Allocator.Error!Builder.Constant {
42634258 const mod = o.module;
42644259 const decl = mod.declPtr(decl_index);
4265 try mod.markDeclAlive(decl);
4266 const ptr_ty = try mod.singleMutPtrType(decl.ty);
4260 const ptr_ty = try mod.singleMutPtrType(decl.typeOf(mod));
42674261 return o.lowerDeclRefValue(ptr_ty, decl_index);
42684262 }
42694263
......@@ -4450,11 +4444,10 @@ pub const Object = struct {
44504444 }
44514445 }
44524446
4453 const is_fn_body = decl.ty.zigTypeTag(mod) == .Fn;
4454 if ((!is_fn_body and !decl.ty.hasRuntimeBits(mod)) or
4455 (is_fn_body and mod.typeToFunc(decl.ty).?.is_generic)) return o.lowerPtrToVoid(ty);
4456
4457 try mod.markDeclAlive(decl);
4447 const decl_ty = decl.typeOf(mod);
4448 const is_fn_body = decl_ty.zigTypeTag(mod) == .Fn;
4449 if ((!is_fn_body and !decl_ty.hasRuntimeBits(mod)) or
4450 (is_fn_body and mod.typeToFunc(decl_ty).?.is_generic)) return o.lowerPtrToVoid(ty);
44584451
44594452 const llvm_global = if (is_fn_body)
44604453 (try o.resolveLlvmFunction(decl_index)).ptrConst(&o.builder).global
......@@ -4740,7 +4733,7 @@ pub const DeclGen = struct {
47404733 debug_file, // File
47414734 debug_file, // Scope
47424735 line_number,
4743 try o.lowerDebugType(decl.ty),
4736 try o.lowerDebugType(decl.typeOf(zcu)),
47444737 variable_index,
47454738 .{ .local = is_internal_linkage },
47464739 );
......@@ -4829,19 +4822,17 @@ pub const FuncGen = struct {
48294822
48304823 const o = self.dg.object;
48314824 const mod = o.module;
4832 const llvm_val = try self.resolveValue(.{
4833 .ty = self.typeOf(inst),
4834 .val = (try self.air.value(inst, mod)).?,
4835 });
4825 const llvm_val = try self.resolveValue((try self.air.value(inst, mod)).?);
48364826 gop.value_ptr.* = llvm_val.toValue();
48374827 return llvm_val.toValue();
48384828 }
48394829
4840 fn resolveValue(self: *FuncGen, tv: TypedValue) Error!Builder.Constant {
4830 fn resolveValue(self: *FuncGen, val: Value) Error!Builder.Constant {
48414831 const o = self.dg.object;
48424832 const mod = o.module;
4843 const llvm_val = try o.lowerValue(tv.val.toIntern());
4844 if (!isByRef(tv.ty, mod)) return llvm_val;
4833 const ty = val.typeOf(mod);
4834 const llvm_val = try o.lowerValue(val.toIntern());
4835 if (!isByRef(ty, mod)) return llvm_val;
48454836
48464837 // We have an LLVM value but we need to create a global constant and
48474838 // set the value as its initializer, and then return a pointer to the global.
......@@ -4855,7 +4846,7 @@ pub const FuncGen = struct {
48554846 variable_index.setLinkage(.private, &o.builder);
48564847 variable_index.setMutability(.constant, &o.builder);
48574848 variable_index.setUnnamedAddr(.unnamed_addr, &o.builder);
4858 variable_index.setAlignment(tv.ty.abiAlignment(mod).toLlvm(), &o.builder);
4849 variable_index.setAlignment(ty.abiAlignment(mod).toLlvm(), &o.builder);
48594850 return o.builder.convConst(
48604851 .unneeded,
48614852 variable_index.toConst(&o.builder),
......@@ -4867,11 +4858,10 @@ pub const FuncGen = struct {
48674858 const o = self.dg.object;
48684859 const mod = o.module;
48694860 if (o.null_opt_usize == .no_init) {
4870 const ty = try mod.intern(.{ .opt_type = .usize_type });
4871 o.null_opt_usize = try self.resolveValue(.{
4872 .ty = Type.fromInterned(ty),
4873 .val = Value.fromInterned((try mod.intern(.{ .opt = .{ .ty = ty, .val = .none } }))),
4874 });
4861 o.null_opt_usize = try self.resolveValue(Value.fromInterned(try mod.intern(.{ .opt = .{
4862 .ty = try mod.intern(.{ .opt_type = .usize_type }),
4863 .val = .none,
4864 } })));
48754865 }
48764866 return o.null_opt_usize;
48774867 }
......@@ -5530,8 +5520,8 @@ pub const FuncGen = struct {
55305520 const mod = o.module;
55315521 const msg_decl_index = mod.panic_messages[@intFromEnum(panic_id)].unwrap().?;
55325522 const msg_decl = mod.declPtr(msg_decl_index);
5533 const msg_len = msg_decl.ty.childType(mod).arrayLen(mod);
5534 const msg_ptr = try o.lowerValue(try msg_decl.internValue(mod));
5523 const msg_len = msg_decl.typeOf(mod).childType(mod).arrayLen(mod);
5524 const msg_ptr = try o.lowerValue(msg_decl.val.toIntern());
55355525 const null_opt_addr_global = try fg.resolveNullOptUsize();
55365526 const target = mod.getTarget();
55375527 const llvm_usize = try o.lowerType(Type.usize);
......@@ -5544,7 +5534,7 @@ pub const FuncGen = struct {
55445534 // )
55455535 const panic_func = mod.funcInfo(mod.panic_func_index);
55465536 const panic_decl = mod.declPtr(panic_func.owner_decl);
5547 const fn_info = mod.typeToFunc(panic_decl.ty).?;
5537 const fn_info = mod.typeToFunc(panic_decl.typeOf(mod)).?;
55485538 const panic_global = try o.resolveLlvmFunction(panic_func.owner_decl);
55495539 _ = try fg.wip.call(
55505540 .normal,
......@@ -5612,7 +5602,7 @@ pub const FuncGen = struct {
56125602 _ = try self.wip.retVoid();
56135603 return .none;
56145604 }
5615 const fn_info = mod.typeToFunc(self.dg.decl.ty).?;
5605 const fn_info = mod.typeToFunc(self.dg.decl.typeOf(mod)).?;
56165606 if (!ret_ty.hasRuntimeBitsIgnoreComptime(mod)) {
56175607 if (Type.fromInterned(fn_info.return_type).isError(mod)) {
56185608 // Functions with an empty error set are emitted with an error code
......@@ -5674,7 +5664,7 @@ pub const FuncGen = struct {
56745664 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
56755665 const ptr_ty = self.typeOf(un_op);
56765666 const ret_ty = ptr_ty.childType(mod);
5677 const fn_info = mod.typeToFunc(self.dg.decl.ty).?;
5667 const fn_info = mod.typeToFunc(self.dg.decl.typeOf(mod)).?;
56785668 if (!ret_ty.hasRuntimeBitsIgnoreComptime(mod)) {
56795669 if (Type.fromInterned(fn_info.return_type).isError(mod)) {
56805670 // Functions with an empty error set are emitted with an error code
......@@ -10067,10 +10057,7 @@ pub const FuncGen = struct {
1006710057 const elem_ptr = try self.wip.gep(.inbounds, llvm_result_ty, alloca_inst, &.{
1006810058 usize_zero, try o.builder.intValue(llvm_usize, array_info.len),
1006910059 }, "");
10070 const llvm_elem = try self.resolveValue(.{
10071 .ty = array_info.elem_type,
10072 .val = sent_val,
10073 });
10060 const llvm_elem = try self.resolveValue(sent_val);
1007410061 try self.store(elem_ptr, elem_ptr_ty, llvm_elem.toValue(), .none);
1007510062 }
1007610063
src/codegen/spirv.zig+11-12
......@@ -255,7 +255,6 @@ pub const Object = struct {
255255 pub fn resolveDecl(self: *Object, mod: *Module, decl_index: InternPool.DeclIndex) !SpvModule.Decl.Index {
256256 const decl = mod.declPtr(decl_index);
257257 assert(decl.has_tv); // TODO: Do we need to handle a situation where this is false?
258 try mod.markDeclAlive(decl);
259258
260259 const entry = try self.decl_link.getOrPut(self.gpa, decl_index);
261260 if (!entry.found_existing) {
......@@ -861,7 +860,7 @@ const DeclGen = struct {
861860
862861 const val = arg_val;
863862
864 log.debug("constant: ty = {}, val = {}", .{ ty.fmt(mod), val.fmtValue(ty, mod) });
863 log.debug("constant: ty = {}, val = {}", .{ ty.fmt(mod), val.fmtValue(mod) });
865864 if (val.isUndefDeep(mod)) {
866865 return self.spv.constUndef(result_ty_ref);
867866 }
......@@ -1221,7 +1220,7 @@ const DeclGen = struct {
12211220 else => {},
12221221 }
12231222
1224 if (!decl.ty.isFnOrHasRuntimeBitsIgnoreComptime(mod)) {
1223 if (!decl.typeOf(mod).isFnOrHasRuntimeBitsIgnoreComptime(mod)) {
12251224 // Pointer to nothing - return undefined.
12261225 return self.spv.constUndef(ty_ref);
12271226 }
......@@ -1237,7 +1236,7 @@ const DeclGen = struct {
12371236 const final_storage_class = self.spvStorageClass(decl.@"addrspace");
12381237 try self.addFunctionDep(spv_decl_index, final_storage_class);
12391238
1240 const decl_ptr_ty_ref = try self.ptrType(decl.ty, final_storage_class);
1239 const decl_ptr_ty_ref = try self.ptrType(decl.typeOf(mod), final_storage_class);
12411240
12421241 const ptr_id = switch (final_storage_class) {
12431242 .Generic => try self.castToGeneric(self.typeId(decl_ptr_ty_ref), decl_id),
......@@ -2044,11 +2043,11 @@ const DeclGen = struct {
20442043
20452044 switch (self.spv.declPtr(spv_decl_index).kind) {
20462045 .func => {
2047 assert(decl.ty.zigTypeTag(mod) == .Fn);
2048 const fn_info = mod.typeToFunc(decl.ty).?;
2046 assert(decl.typeOf(mod).zigTypeTag(mod) == .Fn);
2047 const fn_info = mod.typeToFunc(decl.typeOf(mod)).?;
20492048 const return_ty_ref = try self.resolveFnReturnType(Type.fromInterned(fn_info.return_type));
20502049
2051 const prototype_ty_ref = try self.resolveType(decl.ty, .direct);
2050 const prototype_ty_ref = try self.resolveType(decl.typeOf(mod), .direct);
20522051 try self.func.prologue.emit(self.spv.gpa, .OpFunction, .{
20532052 .id_result_type = self.typeId(return_ty_ref),
20542053 .id_result = result_id,
......@@ -2121,7 +2120,7 @@ const DeclGen = struct {
21212120 const final_storage_class = self.spvStorageClass(decl.@"addrspace");
21222121 assert(final_storage_class != .Generic); // These should be instance globals
21232122
2124 const ptr_ty_ref = try self.ptrType(decl.ty, final_storage_class);
2123 const ptr_ty_ref = try self.ptrType(decl.typeOf(mod), final_storage_class);
21252124
21262125 try self.spv.sections.types_globals_constants.emit(self.spv.gpa, .OpVariable, .{
21272126 .id_result_type = self.typeId(ptr_ty_ref),
......@@ -2144,7 +2143,7 @@ const DeclGen = struct {
21442143
21452144 try self.spv.declareDeclDeps(spv_decl_index, &.{});
21462145
2147 const ptr_ty_ref = try self.ptrType(decl.ty, .Function);
2146 const ptr_ty_ref = try self.ptrType(decl.typeOf(mod), .Function);
21482147
21492148 if (maybe_init_val) |init_val| {
21502149 // TODO: Combine with resolveAnonDecl?
......@@ -2168,7 +2167,7 @@ const DeclGen = struct {
21682167 });
21692168 self.current_block_label = root_block_id;
21702169
2171 const val_id = try self.constant(decl.ty, init_val, .indirect);
2170 const val_id = try self.constant(decl.typeOf(mod), init_val, .indirect);
21722171 try self.func.body.emit(self.spv.gpa, .OpStore, .{
21732172 .pointer = result_id,
21742173 .object = val_id,
......@@ -4785,7 +4784,7 @@ const DeclGen = struct {
47854784 const mod = self.module;
47864785 if (!ret_ty.hasRuntimeBitsIgnoreComptime(mod)) {
47874786 const decl = mod.declPtr(self.decl_index);
4788 const fn_info = mod.typeToFunc(decl.ty).?;
4787 const fn_info = mod.typeToFunc(decl.typeOf(mod)).?;
47894788 if (Type.fromInterned(fn_info.return_type).isError(mod)) {
47904789 // Functions with an empty error set are emitted with an error code
47914790 // return type and return zero so they can be function pointers coerced
......@@ -4810,7 +4809,7 @@ const DeclGen = struct {
48104809
48114810 if (!ret_ty.hasRuntimeBitsIgnoreComptime(mod)) {
48124811 const decl = mod.declPtr(self.decl_index);
4813 const fn_info = mod.typeToFunc(decl.ty).?;
4812 const fn_info = mod.typeToFunc(decl.typeOf(mod)).?;
48144813 if (Type.fromInterned(fn_info.return_type).isError(mod)) {
48154814 // Functions with an empty error set are emitted with an error code
48164815 // return type and return zero so they can be function pointers coerced
src/link.zig+3-3
......@@ -17,7 +17,7 @@ const Liveness = @import("Liveness.zig");
1717const Module = @import("Module.zig");
1818const InternPool = @import("InternPool.zig");
1919const Type = @import("type.zig").Type;
20const TypedValue = @import("TypedValue.zig");
20const Value = @import("Value.zig");
2121const LlvmObject = @import("codegen/llvm.zig").Object;
2222
2323/// When adding a new field, remember to update `hashAddSystemLibs`.
......@@ -376,14 +376,14 @@ pub const File = struct {
376376 /// Called from within the CodeGen to lower a local variable instantion as an unnamed
377377 /// constant. Returns the symbol index of the lowered constant in the read-only section
378378 /// of the final binary.
379 pub fn lowerUnnamedConst(base: *File, tv: TypedValue, decl_index: InternPool.DeclIndex) UpdateDeclError!u32 {
379 pub fn lowerUnnamedConst(base: *File, val: Value, decl_index: InternPool.DeclIndex) UpdateDeclError!u32 {
380380 if (build_options.only_c) @compileError("unreachable");
381381 switch (base.tag) {
382382 .spirv => unreachable,
383383 .c => unreachable,
384384 .nvptx => unreachable,
385385 inline else => |t| {
386 return @fieldParentPtr(t.Type(), "base", base).lowerUnnamedConst(tv, decl_index);
386 return @fieldParentPtr(t.Type(), "base", base).lowerUnnamedConst(val, decl_index);
387387 },
388388 }
389389 }
src/link/C.zig+2-6
......@@ -209,7 +209,7 @@ pub fn updateFunc(
209209 .module = module,
210210 .error_msg = null,
211211 .pass = .{ .decl = decl_index },
212 .is_naked_fn = decl.ty.fnCallingConvention(module) == .Naked,
212 .is_naked_fn = decl.typeOf(module).fnCallingConvention(module) == .Naked,
213213 .fwd_decl = fwd_decl.toManaged(gpa),
214214 .ctypes = ctypes.*,
215215 .anon_decl_deps = self.anon_decls,
......@@ -283,13 +283,9 @@ fn updateAnonDecl(self: *C, module: *Module, i: usize) !void {
283283 code.* = object.code.moveToUnmanaged();
284284 }
285285
286 const tv: @import("../TypedValue.zig") = .{
287 .ty = Type.fromInterned(module.intern_pool.typeOf(anon_decl)),
288 .val = Value.fromInterned(anon_decl),
289 };
290286 const c_value: codegen.CValue = .{ .constant = anon_decl };
291287 const alignment: Alignment = self.aligned_anon_decls.get(anon_decl) orelse .none;
292 codegen.genDeclValue(&object, tv, false, c_value, alignment, .none) catch |err| switch (err) {
288 codegen.genDeclValue(&object, Value.fromInterned(anon_decl), false, c_value, alignment, .none) catch |err| switch (err) {
293289 error.AnalysisFail => {
294290 @panic("TODO: C backend AnalysisFail on anonymous decl");
295291 //try module.failed_decls.put(gpa, decl_index, object.dg.error_msg.?);
src/link/Coff.zig+9-13
......@@ -1167,7 +1167,7 @@ pub fn updateFunc(self: *Coff, mod: *Module, func_index: InternPool.Index, air:
11671167 return self.updateExports(mod, .{ .decl_index = decl_index }, mod.getDeclExports(decl_index));
11681168}
11691169
1170pub fn lowerUnnamedConst(self: *Coff, tv: TypedValue, decl_index: InternPool.DeclIndex) !u32 {
1170pub fn lowerUnnamedConst(self: *Coff, val: Value, decl_index: InternPool.DeclIndex) !u32 {
11711171 const gpa = self.base.comp.gpa;
11721172 const mod = self.base.comp.module.?;
11731173 const decl = mod.declPtr(decl_index);
......@@ -1180,7 +1180,8 @@ pub fn lowerUnnamedConst(self: *Coff, tv: TypedValue, decl_index: InternPool.Dec
11801180 const index = unnamed_consts.items.len;
11811181 const sym_name = try std.fmt.allocPrint(gpa, "__unnamed_{s}_{d}", .{ decl_name, index });
11821182 defer gpa.free(sym_name);
1183 const atom_index = switch (try self.lowerConst(sym_name, tv, tv.ty.abiAlignment(mod), self.rdata_section_index.?, decl.srcLoc(mod))) {
1183 const ty = val.typeOf(mod);
1184 const atom_index = switch (try self.lowerConst(sym_name, val, ty.abiAlignment(mod), self.rdata_section_index.?, decl.srcLoc(mod))) {
11841185 .ok => |atom_index| atom_index,
11851186 .fail => |em| {
11861187 decl.analysis = .codegen_failure;
......@@ -1198,7 +1199,7 @@ const LowerConstResult = union(enum) {
11981199 fail: *Module.ErrorMsg,
11991200};
12001201
1201fn lowerConst(self: *Coff, name: []const u8, tv: TypedValue, required_alignment: InternPool.Alignment, sect_id: u16, src_loc: Module.SrcLoc) !LowerConstResult {
1202fn lowerConst(self: *Coff, name: []const u8, val: Value, required_alignment: InternPool.Alignment, sect_id: u16, src_loc: Module.SrcLoc) !LowerConstResult {
12021203 const gpa = self.base.comp.gpa;
12031204
12041205 var code_buffer = std.ArrayList(u8).init(gpa);
......@@ -1209,7 +1210,7 @@ fn lowerConst(self: *Coff, name: []const u8, tv: TypedValue, required_alignment:
12091210 try self.setSymbolName(sym, name);
12101211 sym.section_number = @as(coff.SectionNumber, @enumFromInt(sect_id + 1));
12111212
1212 const res = try codegen.generateSymbol(&self.base, src_loc, tv, &code_buffer, .none, .{
1213 const res = try codegen.generateSymbol(&self.base, src_loc, val, &code_buffer, .none, .{
12131214 .parent_atom_index = self.getAtom(atom_index).getSymbolIndex().?,
12141215 });
12151216 const code = switch (res) {
......@@ -1271,10 +1272,7 @@ pub fn updateDecl(
12711272 defer code_buffer.deinit();
12721273
12731274 const decl_val = if (decl.val.getVariable(mod)) |variable| Value.fromInterned(variable.init) else decl.val;
1274 const res = try codegen.generateSymbol(&self.base, decl.srcLoc(mod), .{
1275 .ty = decl.ty,
1276 .val = decl_val,
1277 }, &code_buffer, .none, .{
1275 const res = try codegen.generateSymbol(&self.base, decl.srcLoc(mod), decl_val, &code_buffer, .none, .{
12781276 .parent_atom_index = atom.getSymbolIndex().?,
12791277 });
12801278 const code = switch (res) {
......@@ -1399,8 +1397,8 @@ pub fn getOrCreateAtomForDecl(self: *Coff, decl_index: InternPool.DeclIndex) !At
13991397
14001398fn getDeclOutputSection(self: *Coff, decl_index: InternPool.DeclIndex) u16 {
14011399 const decl = self.base.comp.module.?.declPtr(decl_index);
1402 const ty = decl.ty;
14031400 const mod = self.base.comp.module.?;
1401 const ty = decl.typeOf(mod);
14041402 const zig_ty = ty.zigTypeTag(mod);
14051403 const val = decl.val;
14061404 const index: u16 = blk: {
......@@ -1535,7 +1533,7 @@ pub fn updateExports(
15351533 .x86 => std.builtin.CallingConvention.Stdcall,
15361534 else => std.builtin.CallingConvention.C,
15371535 };
1538 const decl_cc = exported_decl.ty.fnCallingConvention(mod);
1536 const decl_cc = exported_decl.typeOf(mod).fnCallingConvention(mod);
15391537 if (decl_cc == .C and ip.stringEqlSlice(exp.opts.name, "main") and
15401538 comp.config.link_libc)
15411539 {
......@@ -1887,14 +1885,13 @@ pub fn lowerAnonDecl(
18871885 }
18881886
18891887 const val = Value.fromInterned(decl_val);
1890 const tv = TypedValue{ .ty = ty, .val = val };
18911888 var name_buf: [32]u8 = undefined;
18921889 const name = std.fmt.bufPrint(&name_buf, "__anon_{d}", .{
18931890 @intFromEnum(decl_val),
18941891 }) catch unreachable;
18951892 const res = self.lowerConst(
18961893 name,
1897 tv,
1894 val,
18981895 decl_alignment,
18991896 self.rdata_section_index.?,
19001897 src_loc,
......@@ -2754,7 +2751,6 @@ const TableSection = @import("table_section.zig").TableSection;
27542751const StringTable = @import("StringTable.zig");
27552752const Type = @import("../type.zig").Type;
27562753const Value = @import("../Value.zig");
2757const TypedValue = @import("../TypedValue.zig");
27582754
27592755pub const base_tag: link.File.Tag = .coff;
27602756
src/link/Dwarf.zig+3-3
......@@ -1109,7 +1109,7 @@ pub fn initDeclState(self: *Dwarf, mod: *Module, decl_index: InternPool.DeclInde
11091109
11101110 assert(decl.has_tv);
11111111
1112 switch (decl.ty.zigTypeTag(mod)) {
1112 switch (decl.typeOf(mod).zigTypeTag(mod)) {
11131113 .Fn => {
11141114 _ = try self.getOrCreateAtomForDecl(.src_fn, decl_index);
11151115
......@@ -1162,7 +1162,7 @@ pub fn initDeclState(self: *Dwarf, mod: *Module, decl_index: InternPool.DeclInde
11621162 try dbg_info_buffer.ensureUnusedCapacity(1 + ptr_width_bytes + 4 + 4 +
11631163 (decl_name_slice.len + 1) + (decl_linkage_name_slice.len + 1));
11641164
1165 const fn_ret_type = decl.ty.fnReturnType(mod);
1165 const fn_ret_type = decl.typeOf(mod).fnReturnType(mod);
11661166 const fn_ret_has_bits = fn_ret_type.hasRuntimeBits(mod);
11671167 dbg_info_buffer.appendAssumeCapacity(@intFromEnum(
11681168 @as(AbbrevCode, if (fn_ret_has_bits) .subprogram else .subprogram_retvoid),
......@@ -1215,7 +1215,7 @@ pub fn commitDeclState(
12151215 var dbg_info_buffer = &decl_state.dbg_info;
12161216
12171217 assert(decl.has_tv);
1218 switch (decl.ty.zigTypeTag(zcu)) {
1218 switch (decl.typeOf(zcu).zigTypeTag(zcu)) {
12191219 .Fn => {
12201220 try decl_state.setInlineFunc(decl.val.toIntern());
12211221
src/link/Elf.zig+3-3
......@@ -3039,8 +3039,8 @@ pub fn updateDecl(
30393039 return self.zigObjectPtr().?.updateDecl(self, mod, decl_index);
30403040}
30413041
3042pub fn lowerUnnamedConst(self: *Elf, typed_value: TypedValue, decl_index: InternPool.DeclIndex) !u32 {
3043 return self.zigObjectPtr().?.lowerUnnamedConst(self, typed_value, decl_index);
3042pub fn lowerUnnamedConst(self: *Elf, val: Value, decl_index: InternPool.DeclIndex) !u32 {
3043 return self.zigObjectPtr().?.lowerUnnamedConst(self, val, decl_index);
30443044}
30453045
30463046pub fn updateExports(
......@@ -6260,7 +6260,7 @@ const SharedObject = @import("Elf/SharedObject.zig");
62606260const Symbol = @import("Elf/Symbol.zig");
62616261const StringTable = @import("StringTable.zig");
62626262const Thunk = thunks.Thunk;
6263const TypedValue = @import("../TypedValue.zig");
6263const Value = @import("../Value.zig");
62646264const VerneedSection = synthetic_sections.VerneedSection;
62656265const ZigGotSection = synthetic_sections.ZigGotSection;
62666266const ZigObject = @import("Elf/ZigObject.zig");
src/link/Elf/ZigObject.zig+10-17
......@@ -702,7 +702,6 @@ pub fn lowerAnonDecl(
702702 }
703703
704704 const val = Value.fromInterned(decl_val);
705 const tv = TypedValue{ .ty = ty, .val = val };
706705 var name_buf: [32]u8 = undefined;
707706 const name = std.fmt.bufPrint(&name_buf, "__anon_{d}", .{
708707 @intFromEnum(decl_val),
......@@ -710,7 +709,7 @@ pub fn lowerAnonDecl(
710709 const res = self.lowerConst(
711710 elf_file,
712711 name,
713 tv,
712 val,
714713 decl_alignment,
715714 elf_file.zig_data_rel_ro_section_index.?,
716715 src_loc,
......@@ -846,7 +845,7 @@ fn getDeclShdrIndex(
846845 _ = self;
847846 const mod = elf_file.base.comp.module.?;
848847 const any_non_single_threaded = elf_file.base.comp.config.any_non_single_threaded;
849 const shdr_index = switch (decl.ty.zigTypeTag(mod)) {
848 const shdr_index = switch (decl.typeOf(mod).zigTypeTag(mod)) {
850849 .Fn => elf_file.zig_text_section_index.?,
851850 else => blk: {
852851 if (decl.getOwnedVariable(mod)) |variable| {
......@@ -1157,19 +1156,13 @@ pub fn updateDecl(
11571156 // TODO implement .debug_info for global variables
11581157 const decl_val = if (decl.val.getVariable(mod)) |variable| Value.fromInterned(variable.init) else decl.val;
11591158 const res = if (decl_state) |*ds|
1160 try codegen.generateSymbol(&elf_file.base, decl.srcLoc(mod), .{
1161 .ty = decl.ty,
1162 .val = decl_val,
1163 }, &code_buffer, .{
1159 try codegen.generateSymbol(&elf_file.base, decl.srcLoc(mod), decl_val, &code_buffer, .{
11641160 .dwarf = ds,
11651161 }, .{
11661162 .parent_atom_index = sym_index,
11671163 })
11681164 else
1169 try codegen.generateSymbol(&elf_file.base, decl.srcLoc(mod), .{
1170 .ty = decl.ty,
1171 .val = decl_val,
1172 }, &code_buffer, .none, .{
1165 try codegen.generateSymbol(&elf_file.base, decl.srcLoc(mod), decl_val, &code_buffer, .none, .{
11731166 .parent_atom_index = sym_index,
11741167 });
11751168
......@@ -1289,7 +1282,7 @@ fn updateLazySymbol(
12891282pub fn lowerUnnamedConst(
12901283 self: *ZigObject,
12911284 elf_file: *Elf,
1292 typed_value: TypedValue,
1285 val: Value,
12931286 decl_index: InternPool.DeclIndex,
12941287) !u32 {
12951288 const gpa = elf_file.base.comp.gpa;
......@@ -1304,11 +1297,12 @@ pub fn lowerUnnamedConst(
13041297 const index = unnamed_consts.items.len;
13051298 const name = try std.fmt.allocPrint(gpa, "__unnamed_{s}_{d}", .{ decl_name, index });
13061299 defer gpa.free(name);
1300 const ty = val.typeOf(mod);
13071301 const sym_index = switch (try self.lowerConst(
13081302 elf_file,
13091303 name,
1310 typed_value,
1311 typed_value.ty.abiAlignment(mod),
1304 val,
1305 ty.abiAlignment(mod),
13121306 elf_file.zig_data_rel_ro_section_index.?,
13131307 decl.srcLoc(mod),
13141308 )) {
......@@ -1334,7 +1328,7 @@ fn lowerConst(
13341328 self: *ZigObject,
13351329 elf_file: *Elf,
13361330 name: []const u8,
1337 tv: TypedValue,
1331 val: Value,
13381332 required_alignment: InternPool.Alignment,
13391333 output_section_index: u32,
13401334 src_loc: Module.SrcLoc,
......@@ -1346,7 +1340,7 @@ fn lowerConst(
13461340
13471341 const sym_index = try self.addAtom(elf_file);
13481342
1349 const res = try codegen.generateSymbol(&elf_file.base, src_loc, tv, &code_buffer, .{
1343 const res = try codegen.generateSymbol(&elf_file.base, src_loc, val, &code_buffer, .{
13501344 .none = {},
13511345 }, .{
13521346 .parent_atom_index = sym_index,
......@@ -1657,5 +1651,4 @@ const Symbol = @import("Symbol.zig");
16571651const StringTable = @import("../StringTable.zig");
16581652const Type = @import("../../type.zig").Type;
16591653const Value = @import("../../Value.zig");
1660const TypedValue = @import("../../TypedValue.zig");
16611654const ZigObject = @This();
src/link/MachO.zig+3-3
......@@ -3127,8 +3127,8 @@ pub fn updateFunc(self: *MachO, mod: *Module, func_index: InternPool.Index, air:
31273127 return self.getZigObject().?.updateFunc(self, mod, func_index, air, liveness);
31283128}
31293129
3130pub fn lowerUnnamedConst(self: *MachO, typed_value: TypedValue, decl_index: InternPool.DeclIndex) !u32 {
3131 return self.getZigObject().?.lowerUnnamedConst(self, typed_value, decl_index);
3130pub fn lowerUnnamedConst(self: *MachO, val: Value, decl_index: InternPool.DeclIndex) !u32 {
3131 return self.getZigObject().?.lowerUnnamedConst(self, val, decl_index);
31323132}
31333133
31343134pub fn updateDecl(self: *MachO, mod: *Module, decl_index: InternPool.DeclIndex) !void {
......@@ -4689,7 +4689,7 @@ const StubsHelperSection = synthetic.StubsHelperSection;
46894689const Symbol = @import("MachO/Symbol.zig");
46904690const Thunk = thunks.Thunk;
46914691const TlvPtrSection = synthetic.TlvPtrSection;
4692const TypedValue = @import("../TypedValue.zig");
4692const Value = @import("../Value.zig");
46934693const UnwindInfo = @import("MachO/UnwindInfo.zig");
46944694const WeakBindSection = synthetic.WeakBindSection;
46954695const ZigGotSection = synthetic.ZigGotSection;
src/link/MachO/ZigObject.zig+8-15
......@@ -567,8 +567,6 @@ pub fn lowerAnonDecl(
567567 return .ok;
568568 }
569569
570 const val = Value.fromInterned(decl_val);
571 const tv = TypedValue{ .ty = ty, .val = val };
572570 var name_buf: [32]u8 = undefined;
573571 const name = std.fmt.bufPrint(&name_buf, "__anon_{d}", .{
574572 @intFromEnum(decl_val),
......@@ -576,7 +574,7 @@ pub fn lowerAnonDecl(
576574 const res = self.lowerConst(
577575 macho_file,
578576 name,
579 tv,
577 Value.fromInterned(decl_val),
580578 decl_alignment,
581579 macho_file.zig_const_sect_index.?,
582580 src_loc,
......@@ -738,11 +736,7 @@ pub fn updateDecl(
738736
739737 const decl_val = if (decl.val.getVariable(mod)) |variable| Value.fromInterned(variable.init) else decl.val;
740738 const dio: codegen.DebugInfoOutput = if (decl_state) |*ds| .{ .dwarf = ds } else .none;
741 const res =
742 try codegen.generateSymbol(&macho_file.base, decl.srcLoc(mod), .{
743 .ty = decl.ty,
744 .val = decl_val,
745 }, &code_buffer, dio, .{
739 const res = try codegen.generateSymbol(&macho_file.base, decl.srcLoc(mod), decl_val, &code_buffer, dio, .{
746740 .parent_atom_index = sym_index,
747741 });
748742
......@@ -1021,7 +1015,7 @@ fn getDeclOutputSection(
10211015 _ = self;
10221016 const mod = macho_file.base.comp.module.?;
10231017 const any_non_single_threaded = macho_file.base.comp.config.any_non_single_threaded;
1024 const sect_id: u8 = switch (decl.ty.zigTypeTag(mod)) {
1018 const sect_id: u8 = switch (decl.typeOf(mod).zigTypeTag(mod)) {
10251019 .Fn => macho_file.zig_text_sect_index.?,
10261020 else => blk: {
10271021 if (decl.getOwnedVariable(mod)) |variable| {
......@@ -1068,7 +1062,7 @@ fn getDeclOutputSection(
10681062pub fn lowerUnnamedConst(
10691063 self: *ZigObject,
10701064 macho_file: *MachO,
1071 typed_value: TypedValue,
1065 val: Value,
10721066 decl_index: InternPool.DeclIndex,
10731067) !u32 {
10741068 const gpa = macho_file.base.comp.gpa;
......@@ -1086,8 +1080,8 @@ pub fn lowerUnnamedConst(
10861080 const sym_index = switch (try self.lowerConst(
10871081 macho_file,
10881082 name,
1089 typed_value,
1090 typed_value.ty.abiAlignment(mod),
1083 val,
1084 val.typeOf(mod).abiAlignment(mod),
10911085 macho_file.zig_const_sect_index.?,
10921086 decl.srcLoc(mod),
10931087 )) {
......@@ -1113,7 +1107,7 @@ fn lowerConst(
11131107 self: *ZigObject,
11141108 macho_file: *MachO,
11151109 name: []const u8,
1116 tv: TypedValue,
1110 val: Value,
11171111 required_alignment: Atom.Alignment,
11181112 output_section_index: u8,
11191113 src_loc: Module.SrcLoc,
......@@ -1125,7 +1119,7 @@ fn lowerConst(
11251119
11261120 const sym_index = try self.addAtom(macho_file);
11271121
1128 const res = try codegen.generateSymbol(&macho_file.base, src_loc, tv, &code_buffer, .{
1122 const res = try codegen.generateSymbol(&macho_file.base, src_loc, val, &code_buffer, .{
11291123 .none = {},
11301124 }, .{
11311125 .parent_atom_index = sym_index,
......@@ -1580,5 +1574,4 @@ const Symbol = @import("Symbol.zig");
15801574const StringTable = @import("../StringTable.zig");
15811575const Type = @import("../../type.zig").Type;
15821576const Value = @import("../../Value.zig");
1583const TypedValue = @import("../../TypedValue.zig");
15841577const ZigObject = @This();
src/link/Plan9.zig+6-13
......@@ -15,7 +15,6 @@ const Air = @import("../Air.zig");
1515const Liveness = @import("../Liveness.zig");
1616const Type = @import("../type.zig").Type;
1717const Value = @import("../Value.zig");
18const TypedValue = @import("../TypedValue.zig");
1918
2019const std = @import("std");
2120const builtin = @import("builtin");
......@@ -177,7 +176,7 @@ pub const Atom = struct {
177176 return if (self.code_ptr) |p| p[0..self.other.code_len] else blk: {
178177 const decl_index = self.other.decl_index;
179178 const decl = mod.declPtr(decl_index);
180 if (decl.ty.zigTypeTag(mod) == .Fn) {
179 if (decl.typeOf(mod).zigTypeTag(mod) == .Fn) {
181180 const table = plan9.fn_decl_table.get(decl.getFileScope(mod)).?.functions;
182181 const output = table.get(decl_index).?;
183182 break :blk output.code;
......@@ -463,7 +462,7 @@ pub fn updateFunc(self: *Plan9, mod: *Module, func_index: InternPool.Index, air:
463462 return self.updateFinish(decl_index);
464463}
465464
466pub fn lowerUnnamedConst(self: *Plan9, tv: TypedValue, decl_index: InternPool.DeclIndex) !u32 {
465pub fn lowerUnnamedConst(self: *Plan9, val: Value, decl_index: InternPool.DeclIndex) !u32 {
467466 const gpa = self.base.comp.gpa;
468467 _ = try self.seeDecl(decl_index);
469468 var code_buffer = std.ArrayList(u8).init(gpa);
......@@ -500,7 +499,7 @@ pub fn lowerUnnamedConst(self: *Plan9, tv: TypedValue, decl_index: InternPool.De
500499 };
501500 self.syms.items[info.sym_index.?] = sym;
502501
503 const res = try codegen.generateSymbol(&self.base, decl.srcLoc(mod), tv, &code_buffer, .{
502 const res = try codegen.generateSymbol(&self.base, decl.srcLoc(mod), val, &code_buffer, .{
504503 .none = {},
505504 }, .{
506505 .parent_atom_index = new_atom_idx,
......@@ -539,10 +538,7 @@ pub fn updateDecl(self: *Plan9, mod: *Module, decl_index: InternPool.DeclIndex)
539538 defer code_buffer.deinit();
540539 const decl_val = if (decl.val.getVariable(mod)) |variable| Value.fromInterned(variable.init) else decl.val;
541540 // TODO we need the symbol index for symbol in the table of locals for the containing atom
542 const res = try codegen.generateSymbol(&self.base, decl.srcLoc(mod), .{
543 .ty = decl.ty,
544 .val = decl_val,
545 }, &code_buffer, .{ .none = {} }, .{
541 const res = try codegen.generateSymbol(&self.base, decl.srcLoc(mod), decl_val, &code_buffer, .{ .none = {} }, .{
546542 .parent_atom_index = @as(Atom.Index, @intCast(atom_idx)),
547543 });
548544 const code = switch (res) {
......@@ -566,7 +562,7 @@ fn updateFinish(self: *Plan9, decl_index: InternPool.DeclIndex) !void {
566562 const gpa = self.base.comp.gpa;
567563 const mod = self.base.comp.module.?;
568564 const decl = mod.declPtr(decl_index);
569 const is_fn = (decl.ty.zigTypeTag(mod) == .Fn);
565 const is_fn = (decl.typeOf(mod).zigTypeTag(mod) == .Fn);
570566 const sym_t: aout.Sym.Type = if (is_fn) .t else .d;
571567
572568 const atom = self.getAtomPtr(self.decls.get(decl_index).?.index);
......@@ -1545,11 +1541,8 @@ pub fn lowerAnonDecl(
15451541 // ...
15461542 const gpa = self.base.comp.gpa;
15471543 const gop = try self.anon_decls.getOrPut(gpa, decl_val);
1548 const mod = self.base.comp.module.?;
15491544 if (!gop.found_existing) {
1550 const ty = Type.fromInterned(mod.intern_pool.typeOf(decl_val));
15511545 const val = Value.fromInterned(decl_val);
1552 const tv = TypedValue{ .ty = ty, .val = val };
15531546 const name = try std.fmt.allocPrint(gpa, "__anon_{d}", .{@intFromEnum(decl_val)});
15541547
15551548 const index = try self.createAtom();
......@@ -1557,7 +1550,7 @@ pub fn lowerAnonDecl(
15571550 gop.value_ptr.* = index;
15581551 // we need to free name latex
15591552 var code_buffer = std.ArrayList(u8).init(gpa);
1560 const res = try codegen.generateSymbol(&self.base, src_loc, tv, &code_buffer, .{ .none = {} }, .{ .parent_atom_index = index });
1553 const res = try codegen.generateSymbol(&self.base, src_loc, val, &code_buffer, .{ .none = {} }, .{ .parent_atom_index = index });
15611554 const code = switch (res) {
15621555 .ok => code_buffer.items,
15631556 .fail => |em| return .{ .fail = em },
src/link/SpirV.zig+1-1
......@@ -163,7 +163,7 @@ pub fn updateExports(
163163 if (decl.val.isFuncBody(mod)) {
164164 const target = mod.getTarget();
165165 const spv_decl_index = try self.object.resolveDecl(mod, decl_index);
166 const execution_model = switch (decl.ty.fnCallingConvention(mod)) {
166 const execution_model = switch (decl.typeOf(mod).fnCallingConvention(mod)) {
167167 .Vertex => spec.ExecutionModel.Vertex,
168168 .Fragment => spec.ExecutionModel.Fragment,
169169 .Kernel => spec.ExecutionModel.Kernel,
src/link/Wasm.zig+3-3
......@@ -32,7 +32,7 @@ const Module = @import("../Module.zig");
3232const Object = @import("Wasm/Object.zig");
3333const Symbol = @import("Wasm/Symbol.zig");
3434const Type = @import("../type.zig").Type;
35const TypedValue = @import("../TypedValue.zig");
35const Value = @import("../Value.zig");
3636const ZigObject = @import("Wasm/ZigObject.zig");
3737
3838pub const Atom = @import("Wasm/Atom.zig");
......@@ -1504,8 +1504,8 @@ fn getFunctionSignature(wasm: *const Wasm, loc: SymbolLoc) std.wasm.Type {
15041504/// Lowers a constant typed value to a local symbol and atom.
15051505/// Returns the symbol index of the local
15061506/// The given `decl` is the parent decl whom owns the constant.
1507pub fn lowerUnnamedConst(wasm: *Wasm, tv: TypedValue, decl_index: InternPool.DeclIndex) !u32 {
1508 return wasm.zigObjectPtr().?.lowerUnnamedConst(wasm, tv, decl_index);
1507pub fn lowerUnnamedConst(wasm: *Wasm, val: Value, decl_index: InternPool.DeclIndex) !u32 {
1508 return wasm.zigObjectPtr().?.lowerUnnamedConst(wasm, val, decl_index);
15091509}
15101510
15111511/// Returns the symbol index from a symbol of which its flag is set global,
src/link/Wasm/ZigObject.zig+14-16
......@@ -270,7 +270,7 @@ pub fn updateDecl(
270270 const res = try codegen.generateSymbol(
271271 &wasm_file.base,
272272 decl.srcLoc(mod),
273 .{ .ty = decl.ty, .val = val },
273 val,
274274 &code_writer,
275275 .none,
276276 .{ .parent_atom_index = @intFromEnum(atom.sym_index) },
......@@ -346,7 +346,7 @@ fn finishUpdateDecl(
346346 try atom.code.appendSlice(gpa, code);
347347 atom.size = @intCast(code.len);
348348
349 switch (decl.ty.zigTypeTag(mod)) {
349 switch (decl.typeOf(mod).zigTypeTag(mod)) {
350350 .Fn => {
351351 sym.index = try zig_object.appendFunction(gpa, .{ .type_index = zig_object.atom_types.get(atom_index).? });
352352 sym.tag = .function;
......@@ -444,15 +444,12 @@ pub fn lowerAnonDecl(
444444 const gpa = wasm_file.base.comp.gpa;
445445 const gop = try zig_object.anon_decls.getOrPut(gpa, decl_val);
446446 if (!gop.found_existing) {
447 const mod = wasm_file.base.comp.module.?;
448 const ty = Type.fromInterned(mod.intern_pool.typeOf(decl_val));
449 const tv: TypedValue = .{ .ty = ty, .val = Value.fromInterned(decl_val) };
450447 var name_buf: [32]u8 = undefined;
451448 const name = std.fmt.bufPrint(&name_buf, "__anon_{d}", .{
452449 @intFromEnum(decl_val),
453450 }) catch unreachable;
454451
455 switch (try zig_object.lowerConst(wasm_file, name, tv, src_loc)) {
452 switch (try zig_object.lowerConst(wasm_file, name, Value.fromInterned(decl_val), src_loc)) {
456453 .ok => |atom_index| zig_object.anon_decls.values()[gop.index] = atom_index,
457454 .fail => |em| return .{ .fail = em },
458455 }
......@@ -472,10 +469,10 @@ pub fn lowerAnonDecl(
472469/// Lowers a constant typed value to a local symbol and atom.
473470/// Returns the symbol index of the local
474471/// The given `decl` is the parent decl whom owns the constant.
475pub fn lowerUnnamedConst(zig_object: *ZigObject, wasm_file: *Wasm, tv: TypedValue, decl_index: InternPool.DeclIndex) !u32 {
472pub fn lowerUnnamedConst(zig_object: *ZigObject, wasm_file: *Wasm, val: Value, decl_index: InternPool.DeclIndex) !u32 {
476473 const gpa = wasm_file.base.comp.gpa;
477474 const mod = wasm_file.base.comp.module.?;
478 std.debug.assert(tv.ty.zigTypeTag(mod) != .Fn); // cannot create local symbols for functions
475 std.debug.assert(val.typeOf(mod).zigTypeTag(mod) != .Fn); // cannot create local symbols for functions
479476 const decl = mod.declPtr(decl_index);
480477
481478 const parent_atom_index = try zig_object.getOrCreateAtomForDecl(wasm_file, decl_index);
......@@ -487,7 +484,7 @@ pub fn lowerUnnamedConst(zig_object: *ZigObject, wasm_file: *Wasm, tv: TypedValu
487484 });
488485 defer gpa.free(name);
489486
490 switch (try zig_object.lowerConst(wasm_file, name, tv, decl.srcLoc(mod))) {
487 switch (try zig_object.lowerConst(wasm_file, name, val, decl.srcLoc(mod))) {
491488 .ok => |atom_index| {
492489 try wasm_file.getAtomPtr(parent_atom_index).locals.append(gpa, atom_index);
493490 return @intFromEnum(wasm_file.getAtom(atom_index).sym_index);
......@@ -505,10 +502,12 @@ const LowerConstResult = union(enum) {
505502 fail: *Module.ErrorMsg,
506503};
507504
508fn lowerConst(zig_object: *ZigObject, wasm_file: *Wasm, name: []const u8, tv: TypedValue, src_loc: Module.SrcLoc) !LowerConstResult {
505fn lowerConst(zig_object: *ZigObject, wasm_file: *Wasm, name: []const u8, val: Value, src_loc: Module.SrcLoc) !LowerConstResult {
509506 const gpa = wasm_file.base.comp.gpa;
510507 const mod = wasm_file.base.comp.module.?;
511508
509 const ty = val.typeOf(mod);
510
512511 // Create and initialize a new local symbol and atom
513512 const sym_index = try zig_object.allocateSymbol(gpa);
514513 const atom_index = try wasm_file.createAtom(sym_index, zig_object.index);
......@@ -517,7 +516,7 @@ fn lowerConst(zig_object: *ZigObject, wasm_file: *Wasm, name: []const u8, tv: Ty
517516
518517 const code = code: {
519518 const atom = wasm_file.getAtomPtr(atom_index);
520 atom.alignment = tv.ty.abiAlignment(mod);
519 atom.alignment = ty.abiAlignment(mod);
521520 const segment_name = try std.mem.concat(gpa, u8, &.{ ".rodata.", name });
522521 errdefer gpa.free(segment_name);
523522 zig_object.symbol(sym_index).* = .{
......@@ -527,7 +526,7 @@ fn lowerConst(zig_object: *ZigObject, wasm_file: *Wasm, name: []const u8, tv: Ty
527526 .index = try zig_object.createDataSegment(
528527 gpa,
529528 segment_name,
530 tv.ty.abiAlignment(mod),
529 ty.abiAlignment(mod),
531530 ),
532531 .virtual_address = undefined,
533532 };
......@@ -535,7 +534,7 @@ fn lowerConst(zig_object: *ZigObject, wasm_file: *Wasm, name: []const u8, tv: Ty
535534 const result = try codegen.generateSymbol(
536535 &wasm_file.base,
537536 src_loc,
538 tv,
537 val,
539538 &value_bytes,
540539 .none,
541540 .{
......@@ -764,7 +763,7 @@ pub fn getDeclVAddr(
764763 const atom_index = wasm_file.symbol_atom.get(.{ .file = zig_object.index, .index = @enumFromInt(reloc_info.parent_atom_index) }).?;
765764 const atom = wasm_file.getAtomPtr(atom_index);
766765 const is_wasm32 = target.cpu.arch == .wasm32;
767 if (decl.ty.zigTypeTag(mod) == .Fn) {
766 if (decl.typeOf(mod).zigTypeTag(mod) == .Fn) {
768767 std.debug.assert(reloc_info.addend == 0); // addend not allowed for function relocations
769768 try atom.relocs.append(gpa, .{
770769 .index = target_symbol_index,
......@@ -964,7 +963,7 @@ pub fn freeDecl(zig_object: *ZigObject, wasm_file: *Wasm, decl_index: InternPool
964963 if (sym.isGlobal()) {
965964 std.debug.assert(zig_object.global_syms.remove(atom.sym_index));
966965 }
967 switch (decl.ty.zigTypeTag(mod)) {
966 switch (decl.typeOf(mod).zigTypeTag(mod)) {
968967 .Fn => {
969968 zig_object.functions_free_list.append(gpa, sym.index) catch {};
970969 std.debug.assert(zig_object.atom_types.remove(atom_index));
......@@ -1242,7 +1241,6 @@ const Module = @import("../../Module.zig");
12421241const StringTable = @import("../StringTable.zig");
12431242const Symbol = @import("Symbol.zig");
12441243const Type = @import("../../type.zig").Type;
1245const TypedValue = @import("../../TypedValue.zig");
12461244const Value = @import("../../Value.zig");
12471245const Wasm = @import("../Wasm.zig");
12481246const ZigObject = @This();
src/mutable_value.zig created+508
......@@ -0,0 +1,508 @@
1const std = @import("std");
2const assert = std.debug.assert;
3const Allocator = std.mem.Allocator;
4const Zcu = @import("Module.zig");
5const InternPool = @import("InternPool.zig");
6const Type = @import("type.zig").Type;
7const Value = @import("Value.zig");
8
9/// We use a tagged union here because while it wastes a few bytes for some tags, having a fixed
10/// size for the type makes the common `aggregate` representation more efficient.
11/// For aggregates, the sentinel value, if any, *is* stored.
12pub const MutableValue = union(enum) {
13 /// An interned value.
14 interned: InternPool.Index,
15 /// An error union value which is a payload (not an error).
16 eu_payload: SubValue,
17 /// An optional value which is a payload (not `null`).
18 opt_payload: SubValue,
19 /// An aggregate consisting of a single repeated value.
20 repeated: SubValue,
21 /// An aggregate of `u8` consisting of "plain" bytes (no lazy or undefined elements).
22 bytes: Bytes,
23 /// An aggregate with arbitrary sub-values.
24 aggregate: Aggregate,
25 /// A slice, containing a pointer and length.
26 slice: Slice,
27 /// An instance of a union.
28 un: Union,
29
30 pub const SubValue = struct {
31 ty: InternPool.Index,
32 child: *MutableValue,
33 };
34 pub const Bytes = struct {
35 ty: InternPool.Index,
36 data: []u8,
37 };
38 pub const Aggregate = struct {
39 ty: InternPool.Index,
40 elems: []MutableValue,
41 };
42 pub const Slice = struct {
43 ty: InternPool.Index,
44 /// Must have the appropriate many-ptr type.
45 /// TODO: we want this to be an `InternPool.Index`, but `Sema.beginComptimePtrMutation` doesn't support it.
46 ptr: *MutableValue,
47 /// Must be of type `usize`.
48 /// TODO: we want this to be an `InternPool.Index`, but `Sema.beginComptimePtrMutation` doesn't support it.
49 len: *MutableValue,
50 };
51 pub const Union = struct {
52 ty: InternPool.Index,
53 tag: InternPool.Index,
54 payload: *MutableValue,
55 };
56
57 pub fn intern(mv: MutableValue, zcu: *Zcu, arena: Allocator) Allocator.Error!InternPool.Index {
58 const ip = &zcu.intern_pool;
59 const gpa = zcu.gpa;
60 return switch (mv) {
61 .interned => |ip_index| ip_index,
62 .eu_payload => |sv| try ip.get(gpa, .{ .error_union = .{
63 .ty = sv.ty,
64 .val = .{ .payload = try sv.child.intern(zcu, arena) },
65 } }),
66 .opt_payload => |sv| try ip.get(gpa, .{ .opt = .{
67 .ty = sv.ty,
68 .val = try sv.child.intern(zcu, arena),
69 } }),
70 .repeated => |sv| try ip.get(gpa, .{ .aggregate = .{
71 .ty = sv.ty,
72 .storage = .{ .repeated_elem = try sv.child.intern(zcu, arena) },
73 } }),
74 .bytes => |b| try ip.get(gpa, .{ .aggregate = .{
75 .ty = b.ty,
76 .storage = .{ .bytes = b.data },
77 } }),
78 .aggregate => |a| {
79 const elems = try arena.alloc(InternPool.Index, a.elems.len);
80 for (a.elems, elems) |mut_elem, *interned_elem| {
81 interned_elem.* = try mut_elem.intern(zcu, arena);
82 }
83 return ip.get(gpa, .{ .aggregate = .{
84 .ty = a.ty,
85 .storage = .{ .elems = elems },
86 } });
87 },
88 .slice => |s| try ip.get(gpa, .{ .slice = .{
89 .ty = s.ty,
90 .ptr = try s.ptr.intern(zcu, arena),
91 .len = try s.len.intern(zcu, arena),
92 } }),
93 .un => |u| try ip.get(gpa, .{ .un = .{
94 .ty = u.ty,
95 .tag = u.tag,
96 .val = try u.payload.intern(zcu, arena),
97 } }),
98 };
99 }
100
101 /// Un-interns the top level of this `MutableValue`, if applicable.
102 /// * Non-error error unions use `eu_payload`
103 /// * Non-null optionals use `eu_payload
104 /// * Slices use `slice`
105 /// * Unions use `un`
106 /// * Aggregates use `repeated` or `bytes` or `aggregate`
107 /// If `!allow_bytes`, the `bytes` representation will not be used.
108 /// If `!allow_repeated`, the `repeated` representation will not be used.
109 pub fn unintern(
110 mv: *MutableValue,
111 zcu: *Zcu,
112 arena: Allocator,
113 allow_bytes: bool,
114 allow_repeated: bool,
115 ) Allocator.Error!void {
116 const ip = &zcu.intern_pool;
117 const gpa = zcu.gpa;
118 switch (mv.*) {
119 .interned => |ip_index| switch (ip.indexToKey(ip_index)) {
120 .opt => |opt| if (opt.val != .none) {
121 const mut_payload = try arena.create(MutableValue);
122 mut_payload.* = .{ .interned = opt.val };
123 mv.* = .{ .opt_payload = .{
124 .ty = opt.ty,
125 .child = mut_payload,
126 } };
127 },
128 .error_union => |eu| switch (eu.val) {
129 .err_name => {},
130 .payload => |payload| {
131 const mut_payload = try arena.create(MutableValue);
132 mut_payload.* = .{ .interned = payload };
133 mv.* = .{ .eu_payload = .{
134 .ty = eu.ty,
135 .child = mut_payload,
136 } };
137 },
138 },
139 .slice => |slice| {
140 const ptr = try arena.create(MutableValue);
141 const len = try arena.create(MutableValue);
142 ptr.* = .{ .interned = slice.ptr };
143 len.* = .{ .interned = slice.len };
144 mv.* = .{ .slice = .{
145 .ty = slice.ty,
146 .ptr = ptr,
147 .len = len,
148 } };
149 },
150 .un => |un| {
151 const payload = try arena.create(MutableValue);
152 payload.* = .{ .interned = un.val };
153 mv.* = .{ .un = .{
154 .ty = un.ty,
155 .tag = un.tag,
156 .payload = payload,
157 } };
158 },
159 .aggregate => |agg| switch (agg.storage) {
160 .bytes => |bytes| {
161 assert(bytes.len == ip.aggregateTypeLenIncludingSentinel(agg.ty));
162 assert(ip.childType(agg.ty) == .u8_type);
163 if (allow_bytes) {
164 const arena_bytes = try arena.alloc(u8, bytes.len);
165 @memcpy(arena_bytes, bytes);
166 mv.* = .{ .bytes = .{
167 .ty = agg.ty,
168 .data = arena_bytes,
169 } };
170 } else {
171 const mut_elems = try arena.alloc(MutableValue, bytes.len);
172 for (bytes, mut_elems) |b, *mut_elem| {
173 mut_elem.* = .{ .interned = try ip.get(gpa, .{ .int = .{
174 .ty = .u8_type,
175 .storage = .{ .u64 = b },
176 } }) };
177 }
178 mv.* = .{ .aggregate = .{
179 .ty = agg.ty,
180 .elems = mut_elems,
181 } };
182 }
183 },
184 .elems => |elems| {
185 assert(elems.len == ip.aggregateTypeLenIncludingSentinel(agg.ty));
186 const mut_elems = try arena.alloc(MutableValue, elems.len);
187 for (elems, mut_elems) |interned_elem, *mut_elem| {
188 mut_elem.* = .{ .interned = interned_elem };
189 }
190 mv.* = .{ .aggregate = .{
191 .ty = agg.ty,
192 .elems = mut_elems,
193 } };
194 },
195 .repeated_elem => |val| {
196 if (allow_repeated) {
197 const repeated_val = try arena.create(MutableValue);
198 repeated_val.* = .{ .interned = val };
199 mv.* = .{ .repeated = .{
200 .ty = agg.ty,
201 .child = repeated_val,
202 } };
203 } else {
204 const len = ip.aggregateTypeLenIncludingSentinel(agg.ty);
205 const mut_elems = try arena.alloc(MutableValue, @intCast(len));
206 @memset(mut_elems, .{ .interned = val });
207 mv.* = .{ .aggregate = .{
208 .ty = agg.ty,
209 .elems = mut_elems,
210 } };
211 }
212 },
213 },
214 .undef => |ty_ip| switch (Type.fromInterned(ty_ip).zigTypeTag(zcu)) {
215 .Struct, .Array, .Vector => |type_tag| {
216 const ty = Type.fromInterned(ty_ip);
217 const opt_sent = ty.sentinel(zcu);
218 if (type_tag == .Struct or opt_sent != null or !allow_repeated) {
219 const len_no_sent = ip.aggregateTypeLen(ty_ip);
220 const elems = try arena.alloc(MutableValue, @intCast(len_no_sent + @intFromBool(opt_sent != null)));
221 switch (type_tag) {
222 .Array, .Vector => {
223 const elem_ty = ip.childType(ty_ip);
224 const undef_elem = try ip.get(gpa, .{ .undef = elem_ty });
225 @memset(elems[0..@intCast(len_no_sent)], .{ .interned = undef_elem });
226 },
227 .Struct => for (elems[0..@intCast(len_no_sent)], 0..) |*mut_elem, i| {
228 const field_ty = ty.structFieldType(i, zcu).toIntern();
229 mut_elem.* = .{ .interned = try ip.get(gpa, .{ .undef = field_ty }) };
230 },
231 else => unreachable,
232 }
233 if (opt_sent) |s| elems[@intCast(len_no_sent)] = .{ .interned = s.toIntern() };
234 mv.* = .{ .aggregate = .{
235 .ty = ty_ip,
236 .elems = elems,
237 } };
238 } else {
239 const repeated_val = try arena.create(MutableValue);
240 repeated_val.* = .{
241 .interned = try ip.get(gpa, .{ .undef = ip.childType(ty_ip) }),
242 };
243 mv.* = .{ .repeated = .{
244 .ty = ty_ip,
245 .child = repeated_val,
246 } };
247 }
248 },
249 .Union => {
250 const payload = try arena.create(MutableValue);
251 // HACKHACK: this logic is silly, but Sema detects it and reverts the change where needed.
252 // See comment at the top of `Sema.beginComptimePtrMutationInner`.
253 payload.* = .{ .interned = .undef };
254 mv.* = .{ .un = .{
255 .ty = ty_ip,
256 .tag = .none,
257 .payload = payload,
258 } };
259 },
260 .Pointer => {
261 const ptr_ty = ip.indexToKey(ty_ip).ptr_type;
262 if (ptr_ty.flags.size != .Slice) return;
263 const ptr = try arena.create(MutableValue);
264 const len = try arena.create(MutableValue);
265 ptr.* = .{ .interned = try ip.get(gpa, .{ .undef = ip.slicePtrType(ty_ip) }) };
266 len.* = .{ .interned = try ip.get(gpa, .{ .undef = .usize_type }) };
267 mv.* = .{ .slice = .{
268 .ty = ty_ip,
269 .ptr = ptr,
270 .len = len,
271 } };
272 },
273 else => {},
274 },
275 else => {},
276 },
277 .bytes => |bytes| if (!allow_bytes) {
278 const elems = try arena.alloc(MutableValue, bytes.data.len);
279 for (bytes.data, elems) |byte, *interned_byte| {
280 interned_byte.* = .{ .interned = try ip.get(gpa, .{ .int = .{
281 .ty = .u8_type,
282 .storage = .{ .u64 = byte },
283 } }) };
284 }
285 mv.* = .{ .aggregate = .{
286 .ty = bytes.ty,
287 .elems = elems,
288 } };
289 },
290 else => {},
291 }
292 }
293
294 /// Get a pointer to the `MutableValue` associated with a field/element.
295 /// The returned pointer can be safety mutated through to modify the field value.
296 /// The returned pointer is valid until the representation of `mv` changes.
297 /// This function does *not* support accessing the ptr/len field of slices.
298 pub fn elem(
299 mv: *MutableValue,
300 zcu: *Zcu,
301 arena: Allocator,
302 field_idx: usize,
303 ) Allocator.Error!*MutableValue {
304 const ip = &zcu.intern_pool;
305 const gpa = zcu.gpa;
306 // Convert to the `aggregate` representation.
307 switch (mv) {
308 .eu_payload, .opt_payload, .slice, .un => unreachable,
309 .interned => {
310 try mv.unintern(zcu, arena, false, false);
311 },
312 .bytes => |bytes| {
313 const elems = try arena.alloc(MutableValue, bytes.data.len);
314 for (bytes.data, elems) |byte, interned_byte| {
315 interned_byte.* = try ip.get(gpa, .{ .int = .{
316 .ty = .u8_type,
317 .storage = .{ .u64 = byte },
318 } });
319 }
320 mv.* = .{ .aggregate = .{
321 .ty = bytes.ty,
322 .elems = elems,
323 } };
324 },
325 .repeated => |repeated| {
326 const len = ip.aggregateTypeLenIncludingSentinel(repeated.ty);
327 const elems = try arena.alloc(MutableValue, @intCast(len));
328 @memset(elems, repeated.child.*);
329 mv.* = .{ .aggregate = .{
330 .ty = repeated.ty,
331 .elems = elems,
332 } };
333 },
334 .aggregate => {},
335 }
336 return &mv.aggregate.elems[field_idx];
337 }
338
339 /// Modify a single field of a `MutableValue` which represents an aggregate or slice, leaving others
340 /// untouched. When an entire field must be modified, this should be used in preference to `elemPtr`
341 /// to allow for an optimal representation.
342 /// For slices, uses `Value.slice_ptr_index` and `Value.slice_len_index`.
343 pub fn setElem(
344 mv: *MutableValue,
345 zcu: *Zcu,
346 arena: Allocator,
347 field_idx: usize,
348 field_val: MutableValue,
349 ) Allocator.Error!void {
350 const ip = &zcu.intern_pool;
351 const is_trivial_int = field_val.isTrivialInt(zcu);
352 try mv.unintern(arena, is_trivial_int, true);
353 switch (mv) {
354 .interned,
355 .eu_payload,
356 .opt_payload,
357 .un,
358 => unreachable,
359 .slice => |*s| switch (field_idx) {
360 Value.slice_ptr_index => s.ptr = field_val,
361 Value.slice_len_index => s.len = field_val,
362 },
363 .bytes => |b| {
364 assert(is_trivial_int);
365 assert(field_val.typeOf() == Type.u8);
366 b.data[field_idx] = Value.fromInterned(field_val.interned).toUnsignedInt(zcu);
367 },
368 .repeated => |r| {
369 if (field_val.eqlTrivial(r.child.*)) return;
370 // We must switch to either the `aggregate` or the `bytes` representation.
371 const len_inc_sent = ip.aggregateTypeLenIncludingSentinel(r.ty);
372 if (ip.zigTypeTag(r.ty) != .Struct and
373 is_trivial_int and
374 Type.fromInterned(r.ty).childType(zcu) == .u8_type and
375 r.child.isTrivialInt(zcu))
376 {
377 // We can use the `bytes` representation.
378 const bytes = try arena.alloc(u8, @intCast(len_inc_sent));
379 const repeated_byte = Value.fromInterned(r.child.interned).getUnsignedInt(zcu);
380 @memset(bytes, repeated_byte);
381 bytes[field_idx] = Value.fromInterned(field_val.interned).getUnsignedInt(zcu);
382 mv.* = .{ .bytes = .{
383 .ty = r.ty,
384 .data = bytes,
385 } };
386 } else {
387 // We must use the `aggregate` representation.
388 const mut_elems = try arena.alloc(u8, @intCast(len_inc_sent));
389 @memset(mut_elems, r.child.*);
390 mut_elems[field_idx] = field_val;
391 mv.* = .{ .aggregate = .{
392 .ty = r.ty,
393 .elems = mut_elems,
394 } };
395 }
396 },
397 .aggregate => |a| {
398 a.elems[field_idx] = field_val;
399 const is_struct = ip.zigTypeTag(a.ty) == .Struct;
400 // Attempt to switch to a more efficient representation.
401 const is_repeated = for (a.elems) |e| {
402 if (!e.eqlTrivial(field_val)) break false;
403 } else true;
404 if (is_repeated) {
405 // Switch to `repeated` repr
406 const mut_repeated = try arena.create(MutableValue);
407 mut_repeated.* = field_val;
408 mv.* = .{ .repeated = .{
409 .ty = a.ty,
410 .child = mut_repeated,
411 } };
412 } else if (!is_struct and is_trivial_int and Type.fromInterned(a.ty).childType(zcu).toIntern() == .u8_type) {
413 // See if we can switch to `bytes` repr
414 for (a.elems) |e| {
415 switch (e) {
416 else => break,
417 .interned => |ip_index| switch (ip.indexToKey(ip_index)) {
418 else => break,
419 .int => |int| switch (int.storage) {
420 .u64, .i64, .big_int => {},
421 .lazy_align, .lazy_size => break,
422 },
423 },
424 }
425 } else {
426 const bytes = try arena.alloc(u8, a.elems.len);
427 for (a.elems, bytes) |elem_val, *b| {
428 b.* = Value.fromInterned(elem_val.interned).toUnsignedInt(zcu);
429 }
430 mv.* = .{ .bytes = .{
431 .ty = a.ty,
432 .data = bytes,
433 } };
434 }
435 }
436 },
437 }
438 }
439
440 /// Get the value of a single field of a `MutableValue` which represents an aggregate or slice.
441 /// For slices, uses `Value.slice_ptr_index` and `Value.slice_len_index`.
442 pub fn getElem(
443 mv: MutableValue,
444 zcu: *Zcu,
445 field_idx: usize,
446 ) Allocator.Error!MutableValue {
447 return switch (mv) {
448 .eu_payload,
449 .opt_payload,
450 => unreachable,
451 .interned => |ip_index| {
452 const ty = Type.fromInterned(zcu.intern_pool.typeOf(ip_index));
453 switch (ty.zigTypeTag(zcu)) {
454 .Array, .Vector => return .{ .interned = (try Value.fromInterned(ip_index).elemValue(zcu, field_idx)).toIntern() },
455 .Struct, .Union => return .{ .interned = (try Value.fromInterned(ip_index).fieldValue(zcu, field_idx)).toIntern() },
456 .Pointer => {
457 assert(ty.isSlice(zcu));
458 return switch (field_idx) {
459 Value.slice_ptr_index => .{ .interned = Value.fromInterned(ip_index).slicePtr(zcu).toIntern() },
460 Value.slice_len_index => .{ .interned = switch (zcu.intern_pool.indexToKey(ip_index)) {
461 .undef => try zcu.intern(.{ .undef = .usize_type }),
462 .slice => |s| s.len,
463 else => unreachable,
464 } },
465 else => unreachable,
466 };
467 },
468 else => unreachable,
469 }
470 },
471 .un => |un| {
472 // TODO assert the tag is correct
473 return un.payload.*;
474 },
475 .slice => |s| switch (field_idx) {
476 Value.slice_ptr_index => s.ptr.*,
477 Value.slice_len_index => s.len.*,
478 else => unreachable,
479 },
480 .bytes => |b| .{ .interned = try zcu.intern(.{ .int = .{
481 .ty = .u8_type,
482 .storage = .{ .u64 = b.data[field_idx] },
483 } }) },
484 .repeated => |r| r.child.*,
485 .aggregate => |a| a.elems[field_idx],
486 };
487 }
488
489 fn isTrivialInt(mv: MutableValue, zcu: *Zcu) bool {
490 return switch (mv) {
491 else => false,
492 .interned => |ip_index| switch (zcu.intern_pool.indexToKey(ip_index)) {
493 else => false,
494 .int => |int| switch (int.storage) {
495 .u64, .i64, .big_int => true,
496 .lazy_align, .lazy_size => false,
497 },
498 },
499 };
500 }
501
502 pub fn typeOf(mv: MutableValue, zcu: *Zcu) Type {
503 return switch (mv) {
504 .interned => |ip_index| Type.fromInterned(zcu.intern_pool.typeOf(ip_index)),
505 inline else => |x| Type.fromInterned(x.ty),
506 };
507 }
508};
src/print_air.zig+1-1
......@@ -951,7 +951,7 @@ const Writer = struct {
951951 const ty = Type.fromInterned(mod.intern_pool.indexToKey(ip_index).typeOf());
952952 try s.print("<{}, {}>", .{
953953 ty.fmt(mod),
954 Value.fromInterned(ip_index).fmtValue(ty, mod),
954 Value.fromInterned(ip_index).fmtValue(mod),
955955 });
956956 } else {
957957 return w.writeInstIndex(s, operand.toIndex().?, dies);
src/print_value.zig created+354
......@@ -0,0 +1,354 @@
1//! This type exists only for legacy purposes, and will be removed in the future.
2//! It is a thin wrapper around a `Value` which also, redundantly, stores its `Type`.
3
4const std = @import("std");
5const Type = @import("type.zig").Type;
6const Value = @import("Value.zig");
7const Zcu = @import("Module.zig");
8const Module = Zcu;
9const Sema = @import("Sema.zig");
10const InternPool = @import("InternPool.zig");
11const Allocator = std.mem.Allocator;
12const Target = std.Target;
13
14const max_aggregate_items = 100;
15const max_string_len = 256;
16
17const FormatContext = struct {
18 val: Value,
19 mod: *Module,
20};
21
22pub fn format(
23 ctx: FormatContext,
24 comptime fmt: []const u8,
25 options: std.fmt.FormatOptions,
26 writer: anytype,
27) !void {
28 _ = options;
29 comptime std.debug.assert(fmt.len == 0);
30 return print(ctx.val, writer, 3, ctx.mod, null) catch |err| switch (err) {
31 error.OutOfMemory => @panic("OOM"), // We're not allowed to return this from a format function
32 error.ComptimeBreak, error.ComptimeReturn => unreachable,
33 error.AnalysisFail, error.NeededSourceLocation => unreachable, // TODO: re-evaluate when we actually pass `opt_sema`
34 else => |e| return e,
35 };
36}
37
38pub fn print(
39 val: Value,
40 writer: anytype,
41 level: u8,
42 mod: *Module,
43 /// If this `Sema` is provided, we will recurse through pointers where possible to provide friendly output.
44 opt_sema: ?*Sema,
45) (@TypeOf(writer).Error || Module.CompileError)!void {
46 const ip = &mod.intern_pool;
47 switch (ip.indexToKey(val.toIntern())) {
48 .int_type,
49 .ptr_type,
50 .array_type,
51 .vector_type,
52 .opt_type,
53 .anyframe_type,
54 .error_union_type,
55 .simple_type,
56 .struct_type,
57 .anon_struct_type,
58 .union_type,
59 .opaque_type,
60 .enum_type,
61 .func_type,
62 .error_set_type,
63 .inferred_error_set_type,
64 => try Type.print(val.toType(), writer, mod),
65 .undef => try writer.writeAll("undefined"),
66 .simple_value => |simple_value| switch (simple_value) {
67 .void => try writer.writeAll("{}"),
68 .empty_struct => try writer.writeAll(".{}"),
69 .generic_poison => try writer.writeAll("(generic poison)"),
70 else => try writer.writeAll(@tagName(simple_value)),
71 },
72 .variable => try writer.writeAll("(variable)"),
73 .extern_func => |extern_func| try writer.print("(extern function '{}')", .{
74 mod.declPtr(extern_func.decl).name.fmt(ip),
75 }),
76 .func => |func| try writer.print("(function '{}')", .{
77 mod.declPtr(func.owner_decl).name.fmt(ip),
78 }),
79 .int => |int| switch (int.storage) {
80 inline .u64, .i64, .big_int => |x| try writer.print("{}", .{x}),
81 .lazy_align => |ty| if (opt_sema) |sema| {
82 const a = (try Type.fromInterned(ty).abiAlignmentAdvanced(mod, .{ .sema = sema })).scalar;
83 try writer.print("{}", .{a.toByteUnits(0)});
84 } else try writer.print("@alignOf({})", .{Type.fromInterned(ty).fmt(mod)}),
85 .lazy_size => |ty| if (opt_sema) |sema| {
86 const s = (try Type.fromInterned(ty).abiSizeAdvanced(mod, .{ .sema = sema })).scalar;
87 try writer.print("{}", .{s});
88 } else try writer.print("@sizeOf({})", .{Type.fromInterned(ty).fmt(mod)}),
89 },
90 .err => |err| try writer.print("error.{}", .{
91 err.name.fmt(ip),
92 }),
93 .error_union => |error_union| switch (error_union.val) {
94 .err_name => |err_name| try writer.print("error.{}", .{
95 err_name.fmt(ip),
96 }),
97 .payload => |payload| try print(Value.fromInterned(payload), writer, level, mod, opt_sema),
98 },
99 .enum_literal => |enum_literal| try writer.print(".{}", .{
100 enum_literal.fmt(ip),
101 }),
102 .enum_tag => |enum_tag| {
103 const enum_type = ip.loadEnumType(val.typeOf(mod).toIntern());
104 if (enum_type.tagValueIndex(ip, val.toIntern())) |tag_index| {
105 return writer.print(".{i}", .{enum_type.names.get(ip)[tag_index].fmt(ip)});
106 }
107 if (level == 0) {
108 return writer.writeAll("@enumFromInt(...)");
109 }
110 try writer.writeAll("@enumFromInt(");
111 try print(Value.fromInterned(enum_tag.int), writer, level - 1, mod, opt_sema);
112 try writer.writeAll(")");
113 },
114 .empty_enum_value => try writer.writeAll("(empty enum value)"),
115 .float => |float| switch (float.storage) {
116 inline else => |x| try writer.print("{d}", .{@as(f64, @floatCast(x))}),
117 },
118 .slice => |slice| {
119 const print_contents = switch (ip.getBackingAddrTag(slice.ptr).?) {
120 .field, .elem, .eu_payload, .opt_payload => unreachable,
121 .anon_decl, .comptime_alloc, .comptime_field => true,
122 .decl, .int => false,
123 };
124 if (print_contents) {
125 // TODO: eventually we want to load the slice as an array with `opt_sema`, but that's
126 // currently not possible without e.g. triggering compile errors.
127 }
128 try printPtr(slice.ptr, writer, false, false, 0, level, mod, opt_sema);
129 try writer.writeAll("[0..");
130 if (level == 0) {
131 try writer.writeAll("(...)");
132 } else {
133 try print(Value.fromInterned(slice.len), writer, level - 1, mod, opt_sema);
134 }
135 try writer.writeAll("]");
136 },
137 .ptr => {
138 const print_contents = switch (ip.getBackingAddrTag(val.toIntern()).?) {
139 .field, .elem, .eu_payload, .opt_payload => unreachable,
140 .anon_decl, .comptime_alloc, .comptime_field => true,
141 .decl, .int => false,
142 };
143 if (print_contents) {
144 // TODO: eventually we want to load the pointer with `opt_sema`, but that's
145 // currently not possible without e.g. triggering compile errors.
146 }
147 try printPtr(val.toIntern(), writer, false, false, 0, level, mod, opt_sema);
148 },
149 .opt => |opt| switch (opt.val) {
150 .none => try writer.writeAll("null"),
151 else => |payload| try print(Value.fromInterned(payload), writer, level, mod, opt_sema),
152 },
153 .aggregate => |aggregate| try printAggregate(val, aggregate, writer, level, false, mod, opt_sema),
154 .un => |un| {
155 if (level == 0) {
156 try writer.writeAll(".{ ... }");
157 return;
158 }
159 if (un.tag == .none) {
160 const backing_ty = try val.typeOf(mod).unionBackingType(mod);
161 try writer.print("@bitCast(@as({}, ", .{backing_ty.fmt(mod)});
162 try print(Value.fromInterned(un.val), writer, level - 1, mod, opt_sema);
163 try writer.writeAll("))");
164 } else {
165 try writer.writeAll(".{ ");
166 try print(Value.fromInterned(un.tag), writer, level - 1, mod, opt_sema);
167 try writer.writeAll(" = ");
168 try print(Value.fromInterned(un.val), writer, level - 1, mod, opt_sema);
169 try writer.writeAll(" }");
170 }
171 },
172 .memoized_call => unreachable,
173 }
174}
175
176fn printAggregate(
177 val: Value,
178 aggregate: InternPool.Key.Aggregate,
179 writer: anytype,
180 level: u8,
181 is_ref: bool,
182 zcu: *Zcu,
183 opt_sema: ?*Sema,
184) (@TypeOf(writer).Error || Module.CompileError)!void {
185 if (level == 0) {
186 return writer.writeAll(".{ ... }");
187 }
188 const ip = &zcu.intern_pool;
189 const ty = Type.fromInterned(aggregate.ty);
190 switch (ty.zigTypeTag(zcu)) {
191 .Struct => if (!ty.isTuple(zcu)) {
192 if (is_ref) try writer.writeByte('&');
193 if (ty.structFieldCount(zcu) == 0) {
194 return writer.writeAll(".{}");
195 }
196 try writer.writeAll(".{ ");
197 const max_len = @min(ty.structFieldCount(zcu), max_aggregate_items);
198 for (0..max_len) |i| {
199 if (i != 0) try writer.writeAll(", ");
200 const field_name = ty.structFieldName(@intCast(i), zcu).unwrap().?;
201 try writer.print(".{i} = ", .{field_name.fmt(ip)});
202 try print(try val.fieldValue(zcu, i), writer, level - 1, zcu, opt_sema);
203 }
204 try writer.writeAll(" }");
205 return;
206 },
207 .Array => if (aggregate.storage == .bytes and aggregate.storage.bytes.len > 0) {
208 const skip_terminator = aggregate.storage.bytes[aggregate.storage.bytes.len - 1] == 0;
209 const bytes = if (skip_terminator) b: {
210 break :b aggregate.storage.bytes[0 .. aggregate.storage.bytes.len - 1];
211 } else aggregate.storage.bytes;
212 try writer.print("\"{}\"", .{std.zig.fmtEscapes(bytes)});
213 if (!is_ref) try writer.writeAll(".*");
214 return;
215 } else if (ty.arrayLen(zcu) == 0) {
216 if (is_ref) try writer.writeByte('&');
217 return writer.writeAll(".{}");
218 } else if (ty.arrayLen(zcu) == 1) one_byte_str: {
219 // The repr isn't `bytes`, but we might still be able to print this as a string
220 if (ty.childType(zcu).toIntern() != .u8_type) break :one_byte_str;
221 const elem_val = Value.fromInterned(aggregate.storage.values()[0]);
222 if (elem_val.isUndef(zcu)) break :one_byte_str;
223 const byte = elem_val.toUnsignedInt(zcu);
224 try writer.print("\"{}\"", .{std.zig.fmtEscapes(&.{@intCast(byte)})});
225 if (!is_ref) try writer.writeAll(".*");
226 return;
227 },
228 .Vector => if (ty.arrayLen(zcu) == 0) {
229 if (is_ref) try writer.writeByte('&');
230 return writer.writeAll(".{}");
231 },
232 else => unreachable,
233 }
234
235 const len = ty.arrayLen(zcu);
236
237 if (is_ref) try writer.writeByte('&');
238 try writer.writeAll(".{ ");
239
240 const max_len = @min(len, max_aggregate_items);
241 for (0..max_len) |i| {
242 if (i != 0) try writer.writeAll(", ");
243 try print(try val.fieldValue(zcu, i), writer, level - 1, zcu, opt_sema);
244 }
245 if (len > max_aggregate_items) {
246 try writer.writeAll(", ...");
247 }
248 return writer.writeAll(" }");
249}
250
251fn printPtr(
252 ptr_val: InternPool.Index,
253 writer: anytype,
254 force_type: bool,
255 force_addrof: bool,
256 leading_parens: u32,
257 level: u8,
258 zcu: *Zcu,
259 opt_sema: ?*Sema,
260) (@TypeOf(writer).Error || Module.CompileError)!void {
261 const ip = &zcu.intern_pool;
262 const ptr = switch (ip.indexToKey(ptr_val)) {
263 .undef => |ptr_ty| {
264 if (force_addrof) try writer.writeAll("&");
265 try writer.writeByteNTimes('(', leading_parens);
266 try writer.print("@as({}, undefined)", .{Type.fromInterned(ptr_ty).fmt(zcu)});
267 return;
268 },
269 .ptr => |ptr| ptr,
270 else => unreachable,
271 };
272 if (level == 0) {
273 return writer.writeAll("&...");
274 }
275 switch (ptr.addr) {
276 .int => |int| {
277 if (force_addrof) try writer.writeAll("&");
278 try writer.writeByteNTimes('(', leading_parens);
279 if (force_type) {
280 try writer.print("@as({}, @ptrFromInt(", .{Type.fromInterned(ptr.ty).fmt(zcu)});
281 try print(Value.fromInterned(int), writer, level - 1, zcu, opt_sema);
282 try writer.writeAll("))");
283 } else {
284 try writer.writeAll("@ptrFromInt(");
285 try print(Value.fromInterned(int), writer, level - 1, zcu, opt_sema);
286 try writer.writeAll(")");
287 }
288 },
289 .decl => |index| {
290 try writer.writeAll("&");
291 try zcu.declPtr(index).renderFullyQualifiedName(zcu, writer);
292 },
293 .comptime_alloc => try writer.writeAll("&(comptime alloc)"),
294 .anon_decl => |anon| switch (ip.indexToKey(anon.val)) {
295 .aggregate => |aggregate| try printAggregate(
296 Value.fromInterned(anon.val),
297 aggregate,
298 writer,
299 level - 1,
300 true,
301 zcu,
302 opt_sema,
303 ),
304 else => {
305 const ty = Type.fromInterned(ip.typeOf(anon.val));
306 try writer.print("&@as({}, ", .{ty.fmt(zcu)});
307 try print(Value.fromInterned(anon.val), writer, level - 1, zcu, opt_sema);
308 try writer.writeAll(")");
309 },
310 },
311 .comptime_field => |val| {
312 const ty = Type.fromInterned(ip.typeOf(val));
313 try writer.print("&@as({}, ", .{ty.fmt(zcu)});
314 try print(Value.fromInterned(val), writer, level - 1, zcu, opt_sema);
315 try writer.writeAll(")");
316 },
317 .eu_payload => |base| {
318 try printPtr(base, writer, true, true, leading_parens, level, zcu, opt_sema);
319 try writer.writeAll(".?");
320 },
321 .opt_payload => |base| {
322 try writer.writeAll("(");
323 try printPtr(base, writer, true, true, leading_parens + 1, level, zcu, opt_sema);
324 try writer.writeAll(" catch unreachable");
325 },
326 .elem => |elem| {
327 try printPtr(elem.base, writer, true, true, leading_parens, level, zcu, opt_sema);
328 try writer.print("[{d}]", .{elem.index});
329 },
330 .field => |field| {
331 try printPtr(field.base, writer, true, true, leading_parens, level, zcu, opt_sema);
332 const base_ty = Type.fromInterned(ip.typeOf(field.base)).childType(zcu);
333 switch (base_ty.zigTypeTag(zcu)) {
334 .Struct => if (base_ty.isTuple(zcu)) {
335 try writer.print("[{d}]", .{field.index});
336 } else {
337 const field_name = base_ty.structFieldName(@intCast(field.index), zcu).unwrap().?;
338 try writer.print(".{i}", .{field_name.fmt(ip)});
339 },
340 .Union => {
341 const tag_ty = base_ty.unionTagTypeHypothetical(zcu);
342 const field_name = tag_ty.enumFieldName(@intCast(field.index), zcu);
343 try writer.print(".{i}", .{field_name.fmt(ip)});
344 },
345 .Pointer => switch (field.index) {
346 Value.slice_ptr_index => try writer.writeAll(".ptr"),
347 Value.slice_len_index => try writer.writeAll(".len"),
348 else => unreachable,
349 },
350 else => unreachable,
351 }
352 },
353 }
354}
src/type.zig+5-6
......@@ -7,7 +7,6 @@ const Module = @import("Module.zig");
77const Zcu = Module;
88const log = std.log.scoped(.Type);
99const target_util = @import("target.zig");
10const TypedValue = @import("TypedValue.zig");
1110const Sema = @import("Sema.zig");
1211const InternPool = @import("InternPool.zig");
1312const Alignment = InternPool.Alignment;
......@@ -188,8 +187,8 @@ pub const Type = struct {
188187
189188 if (info.sentinel != .none) switch (info.flags.size) {
190189 .One, .C => unreachable,
191 .Many => try writer.print("[*:{}]", .{Value.fromInterned(info.sentinel).fmtValue(Type.fromInterned(info.child), mod)}),
192 .Slice => try writer.print("[:{}]", .{Value.fromInterned(info.sentinel).fmtValue(Type.fromInterned(info.child), mod)}),
190 .Many => try writer.print("[*:{}]", .{Value.fromInterned(info.sentinel).fmtValue(mod)}),
191 .Slice => try writer.print("[:{}]", .{Value.fromInterned(info.sentinel).fmtValue(mod)}),
193192 } else switch (info.flags.size) {
194193 .One => try writer.writeAll("*"),
195194 .Many => try writer.writeAll("[*]"),
......@@ -235,7 +234,7 @@ pub const Type = struct {
235234 } else {
236235 try writer.print("[{d}:{}]", .{
237236 array_type.len,
238 Value.fromInterned(array_type.sentinel).fmtValue(Type.fromInterned(array_type.child), mod),
237 Value.fromInterned(array_type.sentinel).fmtValue(mod),
239238 });
240239 try print(Type.fromInterned(array_type.child), writer, mod);
241240 }
......@@ -353,7 +352,7 @@ pub const Type = struct {
353352 try print(Type.fromInterned(field_ty), writer, mod);
354353
355354 if (val != .none) {
356 try writer.print(" = {}", .{Value.fromInterned(val).fmtValue(Type.fromInterned(field_ty), mod)});
355 try writer.print(" = {}", .{Value.fromInterned(val).fmtValue(mod)});
357356 }
358357 }
359358 try writer.writeAll("}");
......@@ -2481,7 +2480,7 @@ pub const Type = struct {
24812480 }
24822481 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]);
24832482 if (try field_ty.onePossibleValue(mod)) |field_opv| {
2484 field_val.* = try field_opv.intern(field_ty, mod);
2483 field_val.* = field_opv.toIntern();
24852484 } else return null;
24862485 }
24872486
test/behavior/basic.zig-25
......@@ -693,31 +693,6 @@ test "string concatenation" {
693693 try expect(b[len] == 0);
694694}
695695
696fn manyptrConcat(comptime s: [*:0]const u8) [*:0]const u8 {
697 return "very " ++ s;
698}
699
700test "comptime manyptr concatenation" {
701 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
702 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
703 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
704
705 const s = "epic";
706 const actual = manyptrConcat(s);
707 const expected = "very epic";
708
709 const len = mem.len(actual);
710 const len_with_null = len + 1;
711 {
712 var i: u32 = 0;
713 while (i < len_with_null) : (i += 1) {
714 try expect(actual[i] == expected[i]);
715 }
716 }
717 try expect(actual[len] == 0);
718 try expect(expected[len] == 0);
719}
720
721696test "result location is optional inside error union" {
722697 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
723698 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
test/cases/compile_errors/compile_log.zig+1-1
......@@ -21,7 +21,7 @@ export fn baz() void {
2121//
2222// Compile Log Output:
2323// @as(*const [5:0]u8, "begin")
24// @as(*const [1:0]u8, "a"), @as(i32, 12), @as(*const [1:0]u8, "b"), @as([]const u8, "hi")
24// @as(*const [1:0]u8, "a"), @as(i32, 12), @as(*const [1:0]u8, "b"), @as([]const u8, "hi"[0..2])
2525// @as(*const [3:0]u8, "end")
2626// @as(comptime_int, 4)
2727// @as(*const [5:0]u8, "begin")
test/cases/compile_errors/compile_log_a_pointer_to_an_opaque_value.zig+1-1
......@@ -9,4 +9,4 @@ export fn entry() void {
99// :2:5: error: found compile log statement
1010//
1111// Compile Log Output:
12// @as(*const anyopaque, (function 'entry'))
12// @as(*const anyopaque, &tmp.entry)
test/cases/compile_errors/reify_type_for_exhaustive_enum_with_undefined_tag_type.zig+1-1
......@@ -14,4 +14,4 @@ export fn entry() void {
1414// backend=stage2
1515// target=native
1616//
17// :1:13: error: use of undefined value here causes undefined behavior
17// :1:20: error: use of undefined value here causes undefined behavior
test/cases/compile_errors/reify_type_union_payload_is_undefined.zig+1-1
......@@ -9,4 +9,4 @@ comptime {
99// backend=stage2
1010// target=native
1111//
12// :1:13: error: use of undefined value here causes undefined behavior
12// :1:20: error: use of undefined value here causes undefined behavior
test/cases/compile_errors/reify_type_with_undefined.zig+3-3
......@@ -28,6 +28,6 @@ comptime {
2828// backend=stage2
2929// target=native
3030//
31// :2:9: error: use of undefined value here causes undefined behavior
32// :5:9: error: use of undefined value here causes undefined behavior
33// :17:9: error: use of undefined value here causes undefined behavior
31// :2:16: error: use of undefined value here causes undefined behavior
32// :5:16: error: use of undefined value here causes undefined behavior
33// :17:16: error: use of undefined value here causes undefined behavior
test/cases/comptime_aggregate_print.zig+2-2
......@@ -31,5 +31,5 @@ pub fn main() !void {}
3131// :20:5: error: found compile log statement
3232//
3333// Compile Log Output:
34// @as([]i32, .{ (reinterpreted data) })
35// @as([]i32, .{ (reinterpreted data) })
34// @as([]i32, &(comptime alloc).buf[0..2])
35// @as([]i32, &(comptime alloc).buf[0..2])