diff options
| -rw-r--r-- | src/Sema.zig | 100 | ||||
| -rw-r--r-- | src/Type.zig | 42 | ||||
| -rw-r--r-- | src/Value.zig | 52 | ||||
| -rw-r--r-- | src/Zcu/PerThread.zig | 4 | ||||
| -rw-r--r-- | src/arch/x86_64/CodeGen.zig | 4 | ||||
| -rw-r--r-- | src/codegen.zig | 8 | ||||
| -rw-r--r-- | src/codegen/spirv.zig | 2 | ||||
| -rw-r--r-- | src/print_air.zig | 2 | ||||
| -rw-r--r-- | src/print_value.zig | 104 |
9 files changed, 183 insertions, 135 deletions
diff --git a/src/Sema.zig b/src/Sema.zig index 63632e9f0f..dd5d09c57d 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -2318,7 +2318,7 @@ fn failWithIntegerOverflow(sema: *Sema, block: *Block, src: LazySrcLoc, int_ty: if (int_ty.zigTypeTag(zcu) == .Vector) { const msg = msg: { const msg = try sema.errMsg(src, "overflow of vector type '{}' with value '{}'", .{ - int_ty.fmt(pt), val.fmtValue(pt, sema), + int_ty.fmt(pt), val.fmtValueSema(pt, sema), }); errdefer msg.destroy(sema.gpa); try sema.errNote(src, msg, "when computing vector element at index '{d}'", .{vector_index}); @@ -2327,7 +2327,7 @@ fn failWithIntegerOverflow(sema: *Sema, block: *Block, src: LazySrcLoc, int_ty: return sema.failWithOwnedErrorMsg(block, msg); } return sema.fail(block, src, "overflow of integer type '{}' with value '{}'", .{ - int_ty.fmt(pt), val.fmtValue(pt, sema), + int_ty.fmt(pt), val.fmtValueSema(pt, sema), }); } @@ -2912,7 +2912,7 @@ fn createAnonymousDeclTypeNamed( // in turn helps to avoid unreasonably long symbol names for namespaced // symbols. Such names should ideally be human-readable, and additionally, // some tooling may not support very long symbol names. - try writer.print("{}", .{Value.fmtValueFull(.{ + try writer.print("{}", .{Value.fmtValueSemaFull(.{ .val = arg_val, .pt = pt, .opt_sema = sema, @@ -3202,7 +3202,7 @@ fn zirEnumDecl( .offset = .{ .container_field_value = conflict.prev_field_idx }, }; const msg = msg: { - const msg = try sema.errMsg(value_src, "enum tag value {} already taken", .{last_tag_val.?.fmtValue(pt, sema)}); + const msg = try sema.errMsg(value_src, "enum tag value {} already taken", .{last_tag_val.?.fmtValueSema(pt, sema)}); errdefer msg.destroy(gpa); try sema.errNote(other_field_src, msg, "other occurrence here", .{}); break :msg msg; @@ -3224,7 +3224,7 @@ fn zirEnumDecl( .offset = .{ .container_field_value = conflict.prev_field_idx }, }; const msg = msg: { - const msg = try sema.errMsg(value_src, "enum tag value {} already taken", .{last_tag_val.?.fmtValue(pt, sema)}); + const msg = try sema.errMsg(value_src, "enum tag value {} already taken", .{last_tag_val.?.fmtValueSema(pt, sema)}); errdefer msg.destroy(gpa); try sema.errNote(other_field_src, msg, "other occurrence here", .{}); break :msg msg; @@ -3242,7 +3242,7 @@ fn zirEnumDecl( if (tag_overflow) { const msg = try sema.errMsg(value_src, "enumeration value '{}' too large for type '{}'", .{ - last_tag_val.?.fmtValue(pt, sema), int_tag_ty.fmt(pt), + last_tag_val.?.fmtValueSema(pt, sema), int_tag_ty.fmt(pt), }); return sema.failWithOwnedErrorMsg(block, msg); } @@ -4430,10 +4430,10 @@ fn zirForLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. .input_index = len_idx, } }); try sema.errNote(a_src, msg, "length {} here", .{ - v.fmtValue(pt, sema), + v.fmtValueSema(pt, sema), }); try sema.errNote(arg_src, msg, "length {} here", .{ - arg_val.fmtValue(pt, sema), + arg_val.fmtValueSema(pt, sema), }); break :msg msg; }; @@ -5853,7 +5853,7 @@ fn zirCompileLog( const arg_ty = sema.typeOf(arg); if (try sema.resolveValueResolveLazy(arg)) |val| { try writer.print("@as({}, {})", .{ - arg_ty.fmt(pt), val.fmtValue(pt, sema), + arg_ty.fmt(pt), val.fmtValueSema(pt, sema), }); } else { try writer.print("@as({}, [runtime value])", .{arg_ty.fmt(pt)}); @@ -8949,7 +8949,7 @@ fn zirEnumFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError return Air.internedToRef((try pt.getCoerced(int_val, dest_ty)).toIntern()); } return sema.fail(block, src, "int value '{}' out of range of non-exhaustive enum '{}'", .{ - int_val.fmtValue(pt, sema), dest_ty.fmt(pt), + int_val.fmtValueSema(pt, sema), dest_ty.fmt(pt), }); } if (int_val.isUndef(mod)) { @@ -8957,7 +8957,7 @@ fn zirEnumFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError } if (!(try sema.enumHasInt(dest_ty, int_val))) { return sema.fail(block, src, "enum '{}' has no tag with value '{}'", .{ - dest_ty.fmt(pt), int_val.fmtValue(pt, sema), + dest_ty.fmt(pt), int_val.fmtValueSema(pt, sema), }); } return Air.internedToRef((try pt.getCoerced(int_val, dest_ty)).toIntern()); @@ -14067,7 +14067,7 @@ fn zirShl( const rhs_elem = try rhs_val.elemValue(pt, i); if (rhs_elem.compareHetero(.gte, bit_value, pt)) { return sema.fail(block, rhs_src, "shift amount '{}' at index '{d}' is too large for operand type '{}'", .{ - rhs_elem.fmtValue(pt, sema), + rhs_elem.fmtValueSema(pt, sema), i, scalar_ty.fmt(pt), }); @@ -14075,7 +14075,7 @@ fn zirShl( } } else if (rhs_val.compareHetero(.gte, bit_value, pt)) { return sema.fail(block, rhs_src, "shift amount '{}' is too large for operand type '{}'", .{ - rhs_val.fmtValue(pt, sema), + rhs_val.fmtValueSema(pt, sema), scalar_ty.fmt(pt), }); } @@ -14086,14 +14086,14 @@ fn zirShl( const rhs_elem = try rhs_val.elemValue(pt, i); if (rhs_elem.compareHetero(.lt, try pt.intValue(scalar_rhs_ty, 0), pt)) { return sema.fail(block, rhs_src, "shift by negative amount '{}' at index '{d}'", .{ - rhs_elem.fmtValue(pt, sema), + rhs_elem.fmtValueSema(pt, sema), i, }); } } } else if (rhs_val.compareHetero(.lt, try pt.intValue(rhs_ty, 0), pt)) { return sema.fail(block, rhs_src, "shift by negative amount '{}'", .{ - rhs_val.fmtValue(pt, sema), + rhs_val.fmtValueSema(pt, sema), }); } } @@ -14233,7 +14233,7 @@ fn zirShr( const rhs_elem = try rhs_val.elemValue(pt, i); if (rhs_elem.compareHetero(.gte, bit_value, pt)) { return sema.fail(block, rhs_src, "shift amount '{}' at index '{d}' is too large for operand type '{}'", .{ - rhs_elem.fmtValue(pt, sema), + rhs_elem.fmtValueSema(pt, sema), i, scalar_ty.fmt(pt), }); @@ -14241,7 +14241,7 @@ fn zirShr( } } else if (rhs_val.compareHetero(.gte, bit_value, pt)) { return sema.fail(block, rhs_src, "shift amount '{}' is too large for operand type '{}'", .{ - rhs_val.fmtValue(pt, sema), + rhs_val.fmtValueSema(pt, sema), scalar_ty.fmt(pt), }); } @@ -14252,14 +14252,14 @@ fn zirShr( const rhs_elem = try rhs_val.elemValue(pt, i); if (rhs_elem.compareHetero(.lt, try pt.intValue(rhs_ty.childType(mod), 0), pt)) { return sema.fail(block, rhs_src, "shift by negative amount '{}' at index '{d}'", .{ - rhs_elem.fmtValue(pt, sema), + rhs_elem.fmtValueSema(pt, sema), i, }); } } } else if (rhs_val.compareHetero(.lt, try pt.intValue(rhs_ty, 0), pt)) { return sema.fail(block, rhs_src, "shift by negative amount '{}'", .{ - rhs_val.fmtValue(pt, sema), + rhs_val.fmtValueSema(pt, sema), }); } if (maybe_lhs_val) |lhs_val| { @@ -15190,7 +15190,7 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins block, src, "ambiguous coercion of division operands '{}' and '{}'; non-zero remainder '{}'", - .{ lhs_ty.fmt(pt), rhs_ty.fmt(pt), rem.fmtValue(pt, sema) }, + .{ lhs_ty.fmt(pt), rhs_ty.fmt(pt), rem.fmtValueSema(pt, sema) }, ); } } @@ -21359,7 +21359,7 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air const field_index = enum_ty.enumTagFieldIndex(val, mod) orelse { const msg = msg: { const msg = try sema.errMsg(src, "no field with value '{}' in enum '{}'", .{ - val.fmtValue(pt, sema), mod.declPtr(enum_decl_index).name.fmt(ip), + val.fmtValueSema(pt, sema), mod.declPtr(enum_decl_index).name.fmt(ip), }); errdefer msg.destroy(sema.gpa); try sema.errNote(enum_ty.srcLoc(mod), msg, "declared here", .{}); @@ -22005,7 +22005,7 @@ fn reifyEnum( // TODO: better source location return sema.fail(block, src, "field '{}' with enumeration value '{}' is too large for backing int type '{}'", .{ field_name.fmt(ip), - field_value_val.fmtValue(pt, sema), + field_value_val.fmtValueSema(pt, sema), tag_ty.fmt(pt), }); } @@ -22021,7 +22021,7 @@ fn reifyEnum( break :msg msg; }, .value => msg: { - const msg = try sema.errMsg(src, "enum tag value {} already taken", .{field_value_val.fmtValue(pt, sema)}); + const msg = try sema.errMsg(src, "enum tag value {} already taken", .{field_value_val.fmtValueSema(pt, sema)}); errdefer msg.destroy(gpa); _ = conflict.prev_field_idx; // TODO: this note is incorrect try sema.errNote(src, msg, "other enum tag value here", .{}); @@ -23194,12 +23194,12 @@ fn ptrCastFull( return sema.failWithOwnedErrorMsg(block, msg: { const msg = if (src_info.sentinel == .none) blk: { break :blk try sema.errMsg(src, "destination pointer requires '{}' sentinel", .{ - Value.fromInterned(dest_info.sentinel).fmtValue(pt, sema), + Value.fromInterned(dest_info.sentinel).fmtValueSema(pt, sema), }); } else blk: { break :blk try sema.errMsg(src, "pointer sentinel '{}' cannot coerce into pointer sentinel '{}'", .{ - Value.fromInterned(src_info.sentinel).fmtValue(pt, sema), - Value.fromInterned(dest_info.sentinel).fmtValue(pt, sema), + Value.fromInterned(src_info.sentinel).fmtValueSema(pt, sema), + Value.fromInterned(dest_info.sentinel).fmtValueSema(pt, sema), }); }; errdefer msg.destroy(sema.gpa); @@ -25692,10 +25692,10 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void const msg = try sema.errMsg(src, "non-matching @memcpy lengths", .{}); errdefer msg.destroy(sema.gpa); try sema.errNote(dest_src, msg, "length {} here", .{ - dest_len_val.fmtValue(pt, sema), + dest_len_val.fmtValueSema(pt, sema), }); try sema.errNote(src_src, msg, "length {} here", .{ - src_len_val.fmtValue(pt, sema), + src_len_val.fmtValueSema(pt, sema), }); break :msg msg; }; @@ -29563,7 +29563,7 @@ fn coerceExtra( // comptime-known integer to other number if (!(try sema.intFitsInType(val, dest_ty, null))) { if (!opts.report_err) return error.NotCoercible; - return sema.fail(block, inst_src, "type '{}' cannot represent integer value '{}'", .{ dest_ty.fmt(pt), val.fmtValue(pt, sema) }); + return sema.fail(block, inst_src, "type '{}' cannot represent integer value '{}'", .{ dest_ty.fmt(pt), val.fmtValueSema(pt, sema) }); } return switch (zcu.intern_pool.indexToKey(val.toIntern())) { .undef => try pt.undefRef(dest_ty), @@ -29608,7 +29608,7 @@ fn coerceExtra( block, inst_src, "type '{}' cannot represent float value '{}'", - .{ dest_ty.fmt(pt), val.fmtValue(pt, sema) }, + .{ dest_ty.fmt(pt), val.fmtValueSema(pt, sema) }, ); } return Air.internedToRef(result_val.toIntern()); @@ -30026,11 +30026,11 @@ const InMemoryCoercionResult = union(enum) { .array_sentinel => |sentinel| { if (sentinel.actual.toIntern() != .unreachable_value) { try sema.errNote(src, msg, "array sentinel '{}' cannot cast into array sentinel '{}'", .{ - sentinel.actual.fmtValue(pt, sema), sentinel.wanted.fmtValue(pt, sema), + sentinel.actual.fmtValueSema(pt, sema), sentinel.wanted.fmtValueSema(pt, sema), }); } else { try sema.errNote(src, msg, "destination array requires '{}' sentinel", .{ - sentinel.wanted.fmtValue(pt, sema), + sentinel.wanted.fmtValueSema(pt, sema), }); } break; @@ -30152,11 +30152,11 @@ const InMemoryCoercionResult = union(enum) { .ptr_sentinel => |sentinel| { if (sentinel.actual.toIntern() != .unreachable_value) { try sema.errNote(src, msg, "pointer sentinel '{}' cannot cast into pointer sentinel '{}'", .{ - sentinel.actual.fmtValue(pt, sema), sentinel.wanted.fmtValue(pt, sema), + sentinel.actual.fmtValueSema(pt, sema), sentinel.wanted.fmtValueSema(pt, sema), }); } else { try sema.errNote(src, msg, "destination pointer requires '{}' sentinel", .{ - sentinel.wanted.fmtValue(pt, sema), + sentinel.wanted.fmtValueSema(pt, sema), }); } break; @@ -31412,7 +31412,7 @@ fn coerceEnumToUnion( if (try sema.resolveDefinedValue(block, inst_src, enum_tag)) |val| { const field_index = union_ty.unionTagFieldIndex(val, pt.zcu) orelse { return sema.fail(block, inst_src, "union '{}' has no tag with value '{}'", .{ - union_ty.fmt(pt), val.fmtValue(pt, sema), + union_ty.fmt(pt), val.fmtValueSema(pt, sema), }); }; @@ -32644,8 +32644,8 @@ fn analyzeSlice( msg, "expected '{}', found '{}'", .{ - Value.zero_comptime_int.fmtValue(pt, sema), - start_value.fmtValue(pt, sema), + Value.zero_comptime_int.fmtValueSema(pt, sema), + start_value.fmtValueSema(pt, sema), }, ); break :msg msg; @@ -32660,8 +32660,8 @@ fn analyzeSlice( msg, "expected '{}', found '{}'", .{ - Value.one_comptime_int.fmtValue(pt, sema), - end_value.fmtValue(pt, sema), + Value.one_comptime_int.fmtValueSema(pt, sema), + end_value.fmtValueSema(pt, sema), }, ); break :msg msg; @@ -32674,7 +32674,7 @@ fn analyzeSlice( block, end_src, "end index {} out of bounds for slice of single-item pointer", - .{end_value.fmtValue(pt, sema)}, + .{end_value.fmtValueSema(pt, sema)}, ); } } @@ -32769,8 +32769,8 @@ fn analyzeSlice( end_src, "end index {} out of bounds for array of length {}{s}", .{ - end_val.fmtValue(pt, sema), - len_val.fmtValue(pt, sema), + end_val.fmtValueSema(pt, sema), + len_val.fmtValueSema(pt, sema), sentinel_label, }, ); @@ -32814,7 +32814,7 @@ fn analyzeSlice( end_src, "end index {} out of bounds for slice of length {d}{s}", .{ - end_val.fmtValue(pt, sema), + end_val.fmtValueSema(pt, sema), try slice_val.sliceLen(pt), sentinel_label, }, @@ -32874,8 +32874,8 @@ fn analyzeSlice( start_src, "start index {} is larger than end index {}", .{ - start_val.fmtValue(pt, sema), - end_val.fmtValue(pt, sema), + start_val.fmtValueSema(pt, sema), + end_val.fmtValueSema(pt, sema), }, ); } @@ -32912,8 +32912,8 @@ fn analyzeSlice( const msg = try sema.errMsg(src, "value in memory does not match slice sentinel", .{}); errdefer msg.destroy(sema.gpa); try sema.errNote(src, msg, "expected '{}', found '{}'", .{ - expected_sentinel.fmtValue(pt, sema), - actual_sentinel.fmtValue(pt, sema), + expected_sentinel.fmtValueSema(pt, sema), + actual_sentinel.fmtValueSema(pt, sema), }); break :msg msg; @@ -36656,7 +36656,7 @@ fn semaUnionFields(pt: Zcu.PerThread, arena: Allocator, union_type: InternPool.L .offset = .{ .container_field_value = @intCast(gop.index) }, }; const msg = msg: { - const msg = try sema.errMsg(value_src, "enum tag value {} already taken", .{enum_tag_val.fmtValue(pt, &sema)}); + const msg = try sema.errMsg(value_src, "enum tag value {} already taken", .{enum_tag_val.fmtValueSema(pt, &sema)}); errdefer msg.destroy(gpa); try sema.errNote(other_value_src, msg, "other occurrence here", .{}); break :msg msg; @@ -37888,7 +37888,7 @@ fn intFromFloatScalar( block, src, "fractional component prevents float value '{}' from coercion to type '{}'", - .{ val.fmtValue(pt, sema), int_ty.fmt(pt) }, + .{ val.fmtValueSema(pt, sema), int_ty.fmt(pt) }, ); const float = val.toFloat(f128, pt); @@ -37910,7 +37910,7 @@ fn intFromFloatScalar( if (!(try sema.intFitsInType(cti_result, int_ty, null))) { return sema.fail(block, src, "float value '{}' cannot be stored in integer type '{}'", .{ - val.fmtValue(pt, sema), int_ty.fmt(pt), + val.fmtValueSema(pt, sema), int_ty.fmt(pt), }); } return pt.getCoerced(cti_result, int_ty); diff --git a/src/Type.zig b/src/Type.zig index 2c3d59ba56..825cc2dc5b 100644 --- a/src/Type.zig +++ b/src/Type.zig @@ -194,8 +194,8 @@ pub fn print(ty: Type, writer: anytype, pt: Zcu.PerThread) @TypeOf(writer).Error if (info.sentinel != .none) switch (info.flags.size) { .One, .C => unreachable, - .Many => try writer.print("[*:{}]", .{Value.fromInterned(info.sentinel).fmtValue(pt, null)}), - .Slice => try writer.print("[:{}]", .{Value.fromInterned(info.sentinel).fmtValue(pt, null)}), + .Many => try writer.print("[*:{}]", .{Value.fromInterned(info.sentinel).fmtValue(pt)}), + .Slice => try writer.print("[:{}]", .{Value.fromInterned(info.sentinel).fmtValue(pt)}), } else switch (info.flags.size) { .One => try writer.writeAll("*"), .Many => try writer.writeAll("[*]"), @@ -241,7 +241,7 @@ pub fn print(ty: Type, writer: anytype, pt: Zcu.PerThread) @TypeOf(writer).Error } else { try writer.print("[{d}:{}]", .{ array_type.len, - Value.fromInterned(array_type.sentinel).fmtValue(pt, null), + Value.fromInterned(array_type.sentinel).fmtValue(pt), }); try print(Type.fromInterned(array_type.child), writer, pt); } @@ -359,7 +359,7 @@ pub fn print(ty: Type, writer: anytype, pt: Zcu.PerThread) @TypeOf(writer).Error try print(Type.fromInterned(field_ty), writer, pt); if (val != .none) { - try writer.print(" = {}", .{Value.fromInterned(val).fmtValue(pt, null)}); + try writer.print(" = {}", .{Value.fromInterned(val).fmtValue(pt)}); } } try writer.writeAll("}"); @@ -478,7 +478,7 @@ pub fn hasRuntimeBitsAdvanced( ty: Type, pt: Zcu.PerThread, ignore_comptime_only: bool, - strat: ResolveStratLazy, + comptime strat: ResolveStratLazy, ) RuntimeBitsError!bool { const mod = pt.zcu; const ip = &mod.intern_pool; @@ -792,7 +792,7 @@ pub fn fnHasRuntimeBits(ty: Type, pt: Zcu.PerThread) bool { /// Determines whether a function type has runtime bits, i.e. whether a /// function with this type can exist at runtime. /// Asserts that `ty` is a function type. -pub fn fnHasRuntimeBitsAdvanced(ty: Type, pt: Zcu.PerThread, strat: ResolveStrat) SemaError!bool { +pub fn fnHasRuntimeBitsAdvanced(ty: Type, pt: Zcu.PerThread, comptime strat: ResolveStrat) SemaError!bool { const fn_info = pt.zcu.typeToFunc(ty).?; if (fn_info.is_generic) return false; if (fn_info.is_var_args) return true; @@ -824,7 +824,7 @@ pub fn ptrAlignment(ty: Type, pt: Zcu.PerThread) Alignment { return ptrAlignmentAdvanced(ty, pt, .normal) catch unreachable; } -pub fn ptrAlignmentAdvanced(ty: Type, pt: Zcu.PerThread, strat: ResolveStrat) !Alignment { +pub fn ptrAlignmentAdvanced(ty: Type, pt: Zcu.PerThread, comptime strat: ResolveStrat) !Alignment { return switch (pt.zcu.intern_pool.indexToKey(ty.toIntern())) { .ptr_type => |ptr_type| { if (ptr_type.flags.alignment != .none) @@ -891,7 +891,7 @@ pub const ResolveStrat = enum { /// This should typically be used from semantic analysis. sema, - pub fn toLazy(strat: ResolveStrat) ResolveStratLazy { + pub inline fn toLazy(strat: ResolveStrat) ResolveStratLazy { return switch (strat) { .normal => .eager, .sema => .sema, @@ -908,7 +908,7 @@ pub const ResolveStrat = enum { pub fn abiAlignmentAdvanced( ty: Type, pt: Zcu.PerThread, - strat: ResolveStratLazy, + comptime strat: ResolveStratLazy, ) SemaError!AbiAlignmentAdvanced { const mod = pt.zcu; const target = mod.getTarget(); @@ -932,7 +932,9 @@ pub fn abiAlignmentAdvanced( if (vector_type.len == 0) return .{ .scalar = .@"1" }; switch (mod.comp.getZigBackend()) { else => { - const elem_bits: u32 = @intCast(try Type.fromInterned(vector_type.child).bitSizeAdvanced(pt, .sema)); + // This is fine because the child type of a vector always has a bit-size known + // without needing any type resolution. + const elem_bits: u32 = @intCast(Type.fromInterned(vector_type.child).bitSize(pt)); if (elem_bits == 0) return .{ .scalar = .@"1" }; const bytes = ((elem_bits * vector_type.len) + 7) / 8; const alignment = std.math.ceilPowerOfTwoAssert(u32, bytes); @@ -1130,7 +1132,7 @@ pub fn abiAlignmentAdvanced( fn abiAlignmentAdvancedErrorUnion( ty: Type, pt: Zcu.PerThread, - strat: ResolveStratLazy, + comptime strat: ResolveStratLazy, payload_ty: Type, ) SemaError!AbiAlignmentAdvanced { // This code needs to be kept in sync with the equivalent switch prong @@ -1167,7 +1169,7 @@ fn abiAlignmentAdvancedErrorUnion( fn abiAlignmentAdvancedOptional( ty: Type, pt: Zcu.PerThread, - strat: ResolveStratLazy, + comptime strat: ResolveStratLazy, ) SemaError!AbiAlignmentAdvanced { const mod = pt.zcu; const target = mod.getTarget(); @@ -1231,7 +1233,7 @@ const AbiSizeAdvanced = union(enum) { pub fn abiSizeAdvanced( ty: Type, pt: Zcu.PerThread, - strat: ResolveStratLazy, + comptime strat: ResolveStratLazy, ) SemaError!AbiSizeAdvanced { const mod = pt.zcu; const target = mod.getTarget(); @@ -1505,7 +1507,7 @@ pub fn abiSizeAdvanced( fn abiSizeAdvancedOptional( ty: Type, pt: Zcu.PerThread, - strat: ResolveStratLazy, + comptime strat: ResolveStratLazy, ) SemaError!AbiSizeAdvanced { const mod = pt.zcu; const child_ty = ty.optionalChild(mod); @@ -1680,7 +1682,7 @@ pub fn bitSize(ty: Type, pt: Zcu.PerThread) u64 { pub fn bitSizeAdvanced( ty: Type, pt: Zcu.PerThread, - strat: ResolveStrat, + comptime strat: ResolveStrat, ) SemaError!u64 { const mod = pt.zcu; const target = mod.getTarget(); @@ -2739,7 +2741,7 @@ pub fn comptimeOnly(ty: Type, pt: Zcu.PerThread) bool { /// `generic_poison` will return false. /// May return false negatives when structs and unions are having their field types resolved. -pub fn comptimeOnlyAdvanced(ty: Type, pt: Zcu.PerThread, strat: ResolveStrat) SemaError!bool { +pub fn comptimeOnlyAdvanced(ty: Type, pt: Zcu.PerThread, comptime strat: ResolveStrat) SemaError!bool { const mod = pt.zcu; const ip = &mod.intern_pool; return switch (ty.toIntern()) { @@ -2829,7 +2831,8 @@ pub fn comptimeOnlyAdvanced(ty: Type, pt: Zcu.PerThread, strat: ResolveStrat) Se .no, .wip => false, .yes => true, .unknown => { - assert(strat == .sema); + // Inlined `assert` so that the resolution calls below are not statically reachable. + if (strat != .sema) unreachable; if (struct_type.flagsUnordered(ip).field_types_wip) { struct_type.setRequiresComptime(ip, .unknown); @@ -2874,7 +2877,8 @@ pub fn comptimeOnlyAdvanced(ty: Type, pt: Zcu.PerThread, strat: ResolveStrat) Se .no, .wip => return false, .yes => return true, .unknown => { - assert(strat == .sema); + // Inlined `assert` so that the resolution calls below are not statically reachable. + if (strat != .sema) unreachable; if (union_type.flagsUnordered(ip).status == .field_types_wip) { union_type.setRequiresComptime(ip, .unknown); @@ -3198,7 +3202,7 @@ pub fn structFieldAlign(ty: Type, index: usize, pt: Zcu.PerThread) Alignment { return ty.structFieldAlignAdvanced(index, pt, .normal) catch unreachable; } -pub fn structFieldAlignAdvanced(ty: Type, index: usize, pt: Zcu.PerThread, strat: ResolveStrat) !Alignment { +pub fn structFieldAlignAdvanced(ty: Type, index: usize, pt: Zcu.PerThread, comptime strat: ResolveStrat) !Alignment { const ip = &pt.zcu.intern_pool; switch (ip.indexToKey(ty.toIntern())) { .struct_type => { diff --git a/src/Value.zig b/src/Value.zig index 66253bc29c..7aead8ae7d 100644 --- a/src/Value.zig +++ b/src/Value.zig @@ -40,16 +40,25 @@ pub fn fmtDebug(val: Value) std.fmt.Formatter(dump) { return .{ .data = val }; } -pub fn fmtValue(val: Value, pt: Zcu.PerThread, opt_sema: ?*Sema) std.fmt.Formatter(print_value.format) { +pub fn fmtValue(val: Value, pt: Zcu.PerThread) std.fmt.Formatter(print_value.format) { return .{ .data = .{ .val = val, .pt = pt, - .opt_sema = opt_sema, + .opt_sema = null, .depth = 3, } }; } -pub fn fmtValueFull(ctx: print_value.FormatContext) std.fmt.Formatter(print_value.format) { +pub fn fmtValueSema(val: Value, pt: Zcu.PerThread, sema: *Sema) std.fmt.Formatter(print_value.formatSema) { + return .{ .data = .{ + .val = val, + .pt = pt, + .opt_sema = sema, + .depth = 3, + } }; +} + +pub fn fmtValueSemaFull(ctx: print_value.FormatContext) std.fmt.Formatter(print_value.formatSema) { return .{ .data = ctx }; } @@ -178,7 +187,7 @@ pub fn toBigIntAdvanced( val: Value, space: *BigIntSpace, pt: Zcu.PerThread, - strat: ResolveStrat, + comptime strat: ResolveStrat, ) Module.CompileError!BigIntConst { return switch (val.toIntern()) { .bool_false => BigIntMutable.init(&space.limbs, 0).toConst(), @@ -240,7 +249,7 @@ pub fn getUnsignedInt(val: Value, pt: Zcu.PerThread) ?u64 { /// If the value fits in a u64, return it, otherwise null. /// Asserts not undefined. -pub fn getUnsignedIntAdvanced(val: Value, pt: Zcu.PerThread, strat: ResolveStrat) !?u64 { +pub fn getUnsignedIntAdvanced(val: Value, pt: Zcu.PerThread, comptime strat: ResolveStrat) !?u64 { const mod = pt.zcu; return switch (val.toIntern()) { .undef => unreachable, @@ -1042,7 +1051,7 @@ pub fn orderAgainstZero(lhs: Value, pt: Zcu.PerThread) std.math.Order { pub fn orderAgainstZeroAdvanced( lhs: Value, pt: Zcu.PerThread, - strat: ResolveStrat, + comptime strat: ResolveStrat, ) Module.CompileError!std.math.Order { return switch (lhs.toIntern()) { .bool_false => .eq, @@ -1081,7 +1090,7 @@ pub fn order(lhs: Value, rhs: Value, pt: Zcu.PerThread) std.math.Order { } /// Asserts the value is comparable. -pub fn orderAdvanced(lhs: Value, rhs: Value, pt: Zcu.PerThread, strat: ResolveStrat) !std.math.Order { +pub fn orderAdvanced(lhs: Value, rhs: Value, pt: Zcu.PerThread, comptime strat: ResolveStrat) !std.math.Order { const lhs_against_zero = try lhs.orderAgainstZeroAdvanced(pt, strat); const rhs_against_zero = try rhs.orderAgainstZeroAdvanced(pt, strat); switch (lhs_against_zero) { @@ -1119,7 +1128,7 @@ pub fn compareHeteroAdvanced( op: std.math.CompareOperator, rhs: Value, pt: Zcu.PerThread, - strat: ResolveStrat, + comptime strat: ResolveStrat, ) !bool { if (lhs.pointerDecl(pt.zcu)) |lhs_decl| { if (rhs.pointerDecl(pt.zcu)) |rhs_decl| { @@ -1199,7 +1208,7 @@ pub fn compareAllWithZeroAdvancedExtra( lhs: Value, op: std.math.CompareOperator, pt: Zcu.PerThread, - strat: ResolveStrat, + comptime strat: ResolveStrat, ) Module.CompileError!bool { const mod = pt.zcu; if (lhs.isInf(mod)) { @@ -1505,7 +1514,7 @@ pub fn floatFromIntAdvanced( int_ty: Type, float_ty: Type, pt: Zcu.PerThread, - strat: ResolveStrat, + comptime strat: ResolveStrat, ) !Value { const mod = pt.zcu; if (int_ty.zigTypeTag(mod) == .Vector) { @@ -1523,7 +1532,7 @@ pub fn floatFromIntAdvanced( return floatFromIntScalar(val, float_ty, pt, strat); } -pub fn floatFromIntScalar(val: Value, float_ty: Type, pt: Zcu.PerThread, strat: ResolveStrat) !Value { +pub fn floatFromIntScalar(val: Value, float_ty: Type, pt: Zcu.PerThread, comptime strat: ResolveStrat) !Value { const mod = pt.zcu; return switch (mod.intern_pool.indexToKey(val.toIntern())) { .undef => try pt.undefValue(float_ty), @@ -4071,7 +4080,7 @@ pub const PointerDeriveStep = union(enum) { }; pub fn pointerDerivation(ptr_val: Value, arena: Allocator, pt: Zcu.PerThread) Allocator.Error!PointerDeriveStep { - return ptr_val.pointerDerivationAdvanced(arena, pt, null) catch |err| switch (err) { + return ptr_val.pointerDerivationAdvanced(arena, pt, false, {}) catch |err| switch (err) { error.OutOfMemory => |e| return e, error.AnalysisFail => unreachable, }; @@ -4081,7 +4090,7 @@ pub fn pointerDerivation(ptr_val: Value, arena: Allocator, pt: Zcu.PerThread) Al /// only field and element pointers with no casts. This can be used by codegen backends /// which prefer field/elem accesses when lowering constant pointer values. /// It is also used by the Value printing logic for pointers. -pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, pt: Zcu.PerThread, opt_sema: ?*Sema) !PointerDeriveStep { +pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, pt: Zcu.PerThread, comptime have_sema: bool, sema: if (have_sema) *Sema else void) !PointerDeriveStep { const zcu = pt.zcu; const ptr = zcu.intern_pool.indexToKey(ptr_val.toIntern()).ptr; const base_derive: PointerDeriveStep = switch (ptr.base_addr) { @@ -4104,8 +4113,9 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, pt: Zcu.PerTh } }; }, .comptime_alloc => |idx| base: { - const alloc = opt_sema.?.getComptimeAlloc(idx); - const val = try alloc.val.intern(pt, opt_sema.?.arena); + if (!have_sema) unreachable; + const alloc = sema.getComptimeAlloc(idx); + const val = try alloc.val.intern(pt, sema.arena); const ty = val.typeOf(zcu); break :base .{ .comptime_alloc_ptr = .{ .val = val, @@ -4122,7 +4132,7 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, pt: Zcu.PerTh const base_ptr = Value.fromInterned(eu_ptr); const base_ptr_ty = base_ptr.typeOf(zcu); const parent_step = try arena.create(PointerDeriveStep); - parent_step.* = try pointerDerivationAdvanced(Value.fromInterned(eu_ptr), arena, pt, opt_sema); + parent_step.* = try pointerDerivationAdvanced(Value.fromInterned(eu_ptr), arena, pt, have_sema, sema); break :base .{ .eu_payload_ptr = .{ .parent = parent_step, .result_ptr_ty = try pt.adjustPtrTypeChild(base_ptr_ty, base_ptr_ty.childType(zcu).errorUnionPayload(zcu)), @@ -4132,7 +4142,7 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, pt: Zcu.PerTh const base_ptr = Value.fromInterned(opt_ptr); const base_ptr_ty = base_ptr.typeOf(zcu); const parent_step = try arena.create(PointerDeriveStep); - parent_step.* = try pointerDerivationAdvanced(Value.fromInterned(opt_ptr), arena, pt, opt_sema); + parent_step.* = try pointerDerivationAdvanced(Value.fromInterned(opt_ptr), arena, pt, have_sema, sema); break :base .{ .opt_payload_ptr = .{ .parent = parent_step, .result_ptr_ty = try pt.adjustPtrTypeChild(base_ptr_ty, base_ptr_ty.childType(zcu).optionalChild(zcu)), @@ -4143,8 +4153,8 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, pt: Zcu.PerTh const base_ptr_ty = base_ptr.typeOf(zcu); const agg_ty = base_ptr_ty.childType(zcu); const field_ty, const field_align = switch (agg_ty.zigTypeTag(zcu)) { - .Struct => .{ agg_ty.structFieldType(@intCast(field.index), zcu), try agg_ty.structFieldAlignAdvanced(@intCast(field.index), pt, .sema) }, - .Union => .{ agg_ty.unionFieldTypeByIndex(@intCast(field.index), zcu), try agg_ty.structFieldAlignAdvanced(@intCast(field.index), pt, .sema) }, + .Struct => .{ agg_ty.structFieldType(@intCast(field.index), zcu), try agg_ty.structFieldAlignAdvanced(@intCast(field.index), pt, if (have_sema) .sema else .normal) }, + .Union => .{ agg_ty.unionFieldTypeByIndex(@intCast(field.index), zcu), try agg_ty.structFieldAlignAdvanced(@intCast(field.index), pt, if (have_sema) .sema else .normal) }, .Pointer => .{ switch (field.index) { Value.slice_ptr_index => agg_ty.slicePtrFieldType(zcu), Value.slice_len_index => Type.usize, @@ -4167,7 +4177,7 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, pt: Zcu.PerTh }, }); const parent_step = try arena.create(PointerDeriveStep); - parent_step.* = try pointerDerivationAdvanced(base_ptr, arena, pt, opt_sema); + parent_step.* = try pointerDerivationAdvanced(base_ptr, arena, pt, have_sema, sema); break :base .{ .field_ptr = .{ .parent = parent_step, .field_idx = @intCast(field.index), @@ -4176,7 +4186,7 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, pt: Zcu.PerTh }, .arr_elem => |arr_elem| base: { const parent_step = try arena.create(PointerDeriveStep); - parent_step.* = try pointerDerivationAdvanced(Value.fromInterned(arr_elem.base), arena, pt, opt_sema); + parent_step.* = try pointerDerivationAdvanced(Value.fromInterned(arr_elem.base), arena, pt, have_sema, sema); const parent_ptr_info = (try parent_step.ptrType(pt)).ptrInfo(zcu); const result_ptr_ty = try pt.ptrType(.{ .child = parent_ptr_info.child, diff --git a/src/Zcu/PerThread.zig b/src/Zcu/PerThread.zig index d639f3c824..4c43640843 100644 --- a/src/Zcu/PerThread.zig +++ b/src/Zcu/PerThread.zig @@ -3163,7 +3163,7 @@ pub fn unionFieldNormalAlignmentAdvanced( pt: Zcu.PerThread, loaded_union: InternPool.LoadedUnionType, field_index: u32, - strat: Type.ResolveStrat, + comptime strat: Type.ResolveStrat, ) Zcu.SemaError!InternPool.Alignment { const ip = &pt.zcu.intern_pool; assert(loaded_union.flagsUnordered(ip).layout != .@"packed"); @@ -3191,7 +3191,7 @@ pub fn structFieldAlignmentAdvanced( explicit_alignment: InternPool.Alignment, field_ty: Type, layout: std.builtin.Type.ContainerLayout, - strat: Type.ResolveStrat, + comptime strat: Type.ResolveStrat, ) Zcu.SemaError!InternPool.Alignment { assert(layout != .@"packed"); if (explicit_alignment != .none) return explicit_alignment; diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index dfee2a3bf9..1b8d84aa23 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -17975,8 +17975,8 @@ fn airShuffle(self: *Self, inst: Air.Inst.Index) !void { break :result null; }) orelse return self.fail("TODO implement airShuffle from {} and {} to {} with {}", .{ - lhs_ty.fmt(pt), rhs_ty.fmt(pt), dst_ty.fmt(pt), - Value.fromInterned(extra.mask).fmtValue(pt, null), + lhs_ty.fmt(pt), rhs_ty.fmt(pt), dst_ty.fmt(pt), + Value.fromInterned(extra.mask).fmtValue(pt), }); return self.finishAir(inst, result, .{ extra.a, extra.b, .none }); } diff --git a/src/codegen.zig b/src/codegen.zig index 9e0f4db305..f279141604 100644 --- a/src/codegen.zig +++ b/src/codegen.zig @@ -188,7 +188,7 @@ pub fn generateSymbol( const target = mod.getTarget(); const endian = target.cpu.arch.endian(); - log.debug("generateSymbol: val = {}", .{val.fmtValue(pt, null)}); + log.debug("generateSymbol: val = {}", .{val.fmtValue(pt)}); if (val.isUndefDeep(mod)) { const abi_size = math.cast(usize, ty.abiSize(pt)) orelse return error.Overflow; @@ -838,7 +838,7 @@ fn genDeclRef( const zcu = pt.zcu; const ip = &zcu.intern_pool; const ty = val.typeOf(zcu); - log.debug("genDeclRef: val = {}", .{val.fmtValue(pt, null)}); + log.debug("genDeclRef: val = {}", .{val.fmtValue(pt)}); const ptr_decl = zcu.declPtr(ptr_decl_index); const namespace = zcu.namespacePtr(ptr_decl.src_namespace); @@ -943,7 +943,7 @@ fn genUnnamedConst( owner_decl_index: InternPool.DeclIndex, ) CodeGenError!GenResult { const gpa = lf.comp.gpa; - log.debug("genUnnamedConst: val = {}", .{val.fmtValue(pt, null)}); + log.debug("genUnnamedConst: val = {}", .{val.fmtValue(pt)}); const local_sym_index = lf.lowerUnnamedConst(pt, val, owner_decl_index) catch |err| { return GenResult.fail(gpa, src_loc, "lowering unnamed constant failed: {s}", .{@errorName(err)}); @@ -985,7 +985,7 @@ pub fn genTypedValue( const ip = &zcu.intern_pool; const ty = val.typeOf(zcu); - log.debug("genTypedValue: val = {}", .{val.fmtValue(pt, null)}); + log.debug("genTypedValue: val = {}", .{val.fmtValue(pt)}); if (val.isUndef(zcu)) return GenResult.mcv(.undef); diff --git a/src/codegen/spirv.zig b/src/codegen/spirv.zig index d9468cc8ea..bd14c7a03b 100644 --- a/src/codegen/spirv.zig +++ b/src/codegen/spirv.zig @@ -892,7 +892,7 @@ const DeclGen = struct { const result_ty_id = try self.resolveType(ty, repr); const ip = &mod.intern_pool; - log.debug("lowering constant: ty = {}, val = {}", .{ ty.fmt(pt), val.fmtValue(pt, null) }); + log.debug("lowering constant: ty = {}, val = {}", .{ ty.fmt(pt), val.fmtValue(pt) }); if (val.isUndefDeep(mod)) { return self.spv.constUndef(result_ty_id); } diff --git a/src/print_air.zig b/src/print_air.zig index 1872b480f5..f84904dec8 100644 --- a/src/print_air.zig +++ b/src/print_air.zig @@ -957,7 +957,7 @@ const Writer = struct { const ty = Type.fromInterned(pt.zcu.intern_pool.indexToKey(ip_index).typeOf()); try s.print("<{}, {}>", .{ ty.fmt(pt), - Value.fromInterned(ip_index).fmtValue(pt, null), + Value.fromInterned(ip_index).fmtValue(pt), }); } else { return w.writeInstIndex(s, operand.toIndex().?, dies); diff --git a/src/print_value.zig b/src/print_value.zig index c19ba43af3..46b9203068 100644 --- a/src/print_value.zig +++ b/src/print_value.zig @@ -20,18 +20,35 @@ pub const FormatContext = struct { depth: u8, }; -pub fn format( +pub fn formatSema( ctx: FormatContext, comptime fmt: []const u8, options: std.fmt.FormatOptions, writer: anytype, ) !void { _ = options; + const sema = ctx.opt_sema.?; comptime std.debug.assert(fmt.len == 0); - return print(ctx.val, writer, ctx.depth, ctx.pt, ctx.opt_sema) catch |err| switch (err) { + return print(ctx.val, writer, ctx.depth, ctx.pt, true, sema) catch |err| switch (err) { error.OutOfMemory => @panic("OOM"), // We're not allowed to return this from a format function error.ComptimeBreak, error.ComptimeReturn => unreachable, - error.AnalysisFail => unreachable, // TODO: re-evaluate when we use `opt_sema` more fully + error.AnalysisFail => unreachable, // TODO: re-evaluate when we use `sema` more fully + else => |e| return e, + }; +} + +pub fn format( + ctx: FormatContext, + comptime fmt: []const u8, + options: std.fmt.FormatOptions, + writer: anytype, +) !void { + _ = options; + std.debug.assert(ctx.opt_sema == null); + comptime std.debug.assert(fmt.len == 0); + return print(ctx.val, writer, ctx.depth, ctx.pt, false, {}) catch |err| switch (err) { + error.OutOfMemory => @panic("OOM"), // We're not allowed to return this from a format function + error.ComptimeBreak, error.ComptimeReturn, error.AnalysisFail => unreachable, else => |e| return e, }; } @@ -42,7 +59,8 @@ pub fn print( level: u8, pt: Zcu.PerThread, /// If this `Sema` is provided, we will recurse through pointers where possible to provide friendly output. - opt_sema: ?*Sema, + comptime have_sema: bool, + sema: if (have_sema) *Sema else void, ) (@TypeOf(writer).Error || Zcu.CompileError)!void { const mod = pt.zcu; const ip = &mod.intern_pool; @@ -80,11 +98,11 @@ pub fn print( }), .int => |int| switch (int.storage) { inline .u64, .i64, .big_int => |x| try writer.print("{}", .{x}), - .lazy_align => |ty| if (opt_sema != null) { + .lazy_align => |ty| if (have_sema) { const a = (try Type.fromInterned(ty).abiAlignmentAdvanced(pt, .sema)).scalar; try writer.print("{}", .{a.toByteUnits() orelse 0}); } else try writer.print("@alignOf({})", .{Type.fromInterned(ty).fmt(pt)}), - .lazy_size => |ty| if (opt_sema != null) { + .lazy_size => |ty| if (have_sema) { const s = (try Type.fromInterned(ty).abiSizeAdvanced(pt, .sema)).scalar; try writer.print("{}", .{s}); } else try writer.print("@sizeOf({})", .{Type.fromInterned(ty).fmt(pt)}), @@ -96,7 +114,7 @@ pub fn print( .err_name => |err_name| try writer.print("error.{}", .{ err_name.fmt(ip), }), - .payload => |payload| try print(Value.fromInterned(payload), writer, level, pt, opt_sema), + .payload => |payload| try print(Value.fromInterned(payload), writer, level, pt, have_sema, sema), }, .enum_literal => |enum_literal| try writer.print(".{}", .{ enum_literal.fmt(ip), @@ -110,7 +128,7 @@ pub fn print( return writer.writeAll("@enumFromInt(...)"); } try writer.writeAll("@enumFromInt("); - try print(Value.fromInterned(enum_tag.int), writer, level - 1, pt, opt_sema); + try print(Value.fromInterned(enum_tag.int), writer, level - 1, pt, have_sema, sema); try writer.writeAll(")"); }, .empty_enum_value => try writer.writeAll("(empty enum value)"), @@ -124,15 +142,15 @@ pub fn print( .decl, .int => false, }; if (print_contents) { - // TODO: eventually we want to load the slice as an array with `opt_sema`, but that's + // TODO: eventually we want to load the slice as an array with `sema`, but that's // currently not possible without e.g. triggering compile errors. } - try printPtr(Value.fromInterned(slice.ptr), writer, level, pt, opt_sema); + try printPtr(Value.fromInterned(slice.ptr), writer, level, pt, have_sema, sema); try writer.writeAll("[0.."); if (level == 0) { try writer.writeAll("(...)"); } else { - try print(Value.fromInterned(slice.len), writer, level - 1, pt, opt_sema); + try print(Value.fromInterned(slice.len), writer, level - 1, pt, have_sema, sema); } try writer.writeAll("]"); }, @@ -143,16 +161,16 @@ pub fn print( .decl, .int => false, }; if (print_contents) { - // TODO: eventually we want to load the pointer with `opt_sema`, but that's + // TODO: eventually we want to load the pointer with `sema`, but that's // currently not possible without e.g. triggering compile errors. } - try printPtr(val, writer, level, pt, opt_sema); + try printPtr(val, writer, level, pt, have_sema, sema); }, .opt => |opt| switch (opt.val) { .none => try writer.writeAll("null"), - else => |payload| try print(Value.fromInterned(payload), writer, level, pt, opt_sema), + else => |payload| try print(Value.fromInterned(payload), writer, level, pt, have_sema, sema), }, - .aggregate => |aggregate| try printAggregate(val, aggregate, false, writer, level, pt, opt_sema), + .aggregate => |aggregate| try printAggregate(val, aggregate, false, writer, level, pt, have_sema, sema), .un => |un| { if (level == 0) { try writer.writeAll(".{ ... }"); @@ -161,13 +179,13 @@ pub fn print( if (un.tag == .none) { const backing_ty = try val.typeOf(mod).unionBackingType(pt); try writer.print("@bitCast(@as({}, ", .{backing_ty.fmt(pt)}); - try print(Value.fromInterned(un.val), writer, level - 1, pt, opt_sema); + try print(Value.fromInterned(un.val), writer, level - 1, pt, have_sema, sema); try writer.writeAll("))"); } else { try writer.writeAll(".{ "); - try print(Value.fromInterned(un.tag), writer, level - 1, pt, opt_sema); + try print(Value.fromInterned(un.tag), writer, level - 1, pt, have_sema, sema); try writer.writeAll(" = "); - try print(Value.fromInterned(un.val), writer, level - 1, pt, opt_sema); + try print(Value.fromInterned(un.val), writer, level - 1, pt, have_sema, sema); try writer.writeAll(" }"); } }, @@ -182,7 +200,8 @@ fn printAggregate( writer: anytype, level: u8, pt: Zcu.PerThread, - opt_sema: ?*Sema, + comptime have_sema: bool, + sema: if (have_sema) *Sema else void, ) (@TypeOf(writer).Error || Zcu.CompileError)!void { if (level == 0) { if (is_ref) try writer.writeByte('&'); @@ -203,7 +222,7 @@ fn printAggregate( if (i != 0) try writer.writeAll(", "); const field_name = ty.structFieldName(@intCast(i), zcu).unwrap().?; try writer.print(".{i} = ", .{field_name.fmt(ip)}); - try print(try val.fieldValue(pt, i), writer, level - 1, pt, opt_sema); + try print(try val.fieldValue(pt, i), writer, level - 1, pt, have_sema, sema); } try writer.writeAll(" }"); return; @@ -253,7 +272,7 @@ fn printAggregate( const max_len = @min(len, max_aggregate_items); for (0..max_len) |i| { if (i != 0) try writer.writeAll(", "); - try print(try val.fieldValue(pt, i), writer, level - 1, pt, opt_sema); + try print(try val.fieldValue(pt, i), writer, level - 1, pt, have_sema, sema); } if (len > max_aggregate_items) { try writer.writeAll(", ..."); @@ -261,7 +280,14 @@ fn printAggregate( return writer.writeAll(" }"); } -fn printPtr(ptr_val: Value, writer: anytype, level: u8, pt: Zcu.PerThread, opt_sema: ?*Sema) (@TypeOf(writer).Error || Zcu.CompileError)!void { +fn printPtr( + ptr_val: Value, + writer: anytype, + level: u8, + pt: Zcu.PerThread, + comptime have_sema: bool, + sema: if (have_sema) *Sema else void, +) (@TypeOf(writer).Error || Zcu.CompileError)!void { const ptr = switch (pt.zcu.intern_pool.indexToKey(ptr_val.toIntern())) { .undef => return writer.writeAll("undefined"), .ptr => |ptr| ptr, @@ -278,7 +304,8 @@ fn printPtr(ptr_val: Value, writer: anytype, level: u8, pt: Zcu.PerThread, opt_s writer, level, pt, - opt_sema, + have_sema, + sema, ), else => {}, } @@ -286,12 +313,19 @@ fn printPtr(ptr_val: Value, writer: anytype, level: u8, pt: Zcu.PerThread, opt_s var arena = std.heap.ArenaAllocator.init(pt.zcu.gpa); defer arena.deinit(); - const derivation = try ptr_val.pointerDerivationAdvanced(arena.allocator(), pt, opt_sema); - try printPtrDerivation(derivation, writer, level, pt, opt_sema); + const derivation = try ptr_val.pointerDerivationAdvanced(arena.allocator(), pt, have_sema, sema); + try printPtrDerivation(derivation, writer, level, pt, have_sema, sema); } /// Print `derivation` as an lvalue, i.e. such that writing `&` before this gives the pointer value. -fn printPtrDerivation(derivation: Value.PointerDeriveStep, writer: anytype, level: u8, pt: Zcu.PerThread, opt_sema: ?*Sema) (@TypeOf(writer).Error || Zcu.CompileError)!void { +fn printPtrDerivation( + derivation: Value.PointerDeriveStep, + writer: anytype, + level: u8, + pt: Zcu.PerThread, + comptime have_sema: bool, + sema: if (have_sema) *Sema else void, +) (@TypeOf(writer).Error || Zcu.CompileError)!void { const zcu = pt.zcu; const ip = &zcu.intern_pool; switch (derivation) { @@ -305,31 +339,31 @@ fn printPtrDerivation(derivation: Value.PointerDeriveStep, writer: anytype, leve .anon_decl_ptr => |anon| { const ty = Value.fromInterned(anon.val).typeOf(zcu); try writer.print("@as({}, ", .{ty.fmt(pt)}); - try print(Value.fromInterned(anon.val), writer, level - 1, pt, opt_sema); + try print(Value.fromInterned(anon.val), writer, level - 1, pt, have_sema, sema); try writer.writeByte(')'); }, .comptime_alloc_ptr => |info| { try writer.print("@as({}, ", .{info.val.typeOf(zcu).fmt(pt)}); - try print(info.val, writer, level - 1, pt, opt_sema); + try print(info.val, writer, level - 1, pt, have_sema, sema); try writer.writeByte(')'); }, .comptime_field_ptr => |val| { const ty = val.typeOf(zcu); try writer.print("@as({}, ", .{ty.fmt(pt)}); - try print(val, writer, level - 1, pt, opt_sema); + try print(val, writer, level - 1, pt, have_sema, sema); try writer.writeByte(')'); }, .eu_payload_ptr => |info| { try writer.writeByte('('); - try printPtrDerivation(info.parent.*, writer, level, pt, opt_sema); + try printPtrDerivation(info.parent.*, writer, level, pt, have_sema, sema); try writer.writeAll(" catch unreachable)"); }, .opt_payload_ptr => |info| { - try printPtrDerivation(info.parent.*, writer, level, pt, opt_sema); + try printPtrDerivation(info.parent.*, writer, level, pt, have_sema, sema); try writer.writeAll(".?"); }, .field_ptr => |field| { - try printPtrDerivation(field.parent.*, writer, level, pt, opt_sema); + try printPtrDerivation(field.parent.*, writer, level, pt, have_sema, sema); const agg_ty = (try field.parent.ptrType(pt)).childType(zcu); switch (agg_ty.zigTypeTag(zcu)) { .Struct => if (agg_ty.structFieldName(field.field_idx, zcu).unwrap()) |field_name| { @@ -351,16 +385,16 @@ fn printPtrDerivation(derivation: Value.PointerDeriveStep, writer: anytype, leve } }, .elem_ptr => |elem| { - try printPtrDerivation(elem.parent.*, writer, level, pt, opt_sema); + try printPtrDerivation(elem.parent.*, writer, level, pt, have_sema, sema); try writer.print("[{d}]", .{elem.elem_idx}); }, .offset_and_cast => |oac| if (oac.byte_offset == 0) { try writer.print("@as({}, @ptrCast(", .{oac.new_ptr_ty.fmt(pt)}); - try printPtrDerivation(oac.parent.*, writer, level, pt, opt_sema); + try printPtrDerivation(oac.parent.*, writer, level, pt, have_sema, sema); try writer.writeAll("))"); } else { try writer.print("@as({}, @ptrFromInt(@intFromPtr(", .{oac.new_ptr_ty.fmt(pt)}); - try printPtrDerivation(oac.parent.*, writer, level, pt, opt_sema); + try printPtrDerivation(oac.parent.*, writer, level, pt, have_sema, sema); try writer.print(") + {d}))", .{oac.byte_offset}); }, } |
