Merge pull request #20637 from mlugg/comptime-resolution-strat

Type,Value: mark `ResolveStrat` parameter of type queries as `comptime`
This commit is contained in:
Matthew Lugg 2024-07-16 19:22:39 +01:00 committed by GitHub
commit ee695c8ef4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 183 additions and 135 deletions

View File

@ -2318,7 +2318,7 @@ fn failWithIntegerOverflow(sema: *Sema, block: *Block, src: LazySrcLoc, int_ty:
if (int_ty.zigTypeTag(zcu) == .Vector) { if (int_ty.zigTypeTag(zcu) == .Vector) {
const msg = msg: { const msg = msg: {
const msg = try sema.errMsg(src, "overflow of vector type '{}' with value '{}'", .{ 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); errdefer msg.destroy(sema.gpa);
try sema.errNote(src, msg, "when computing vector element at index '{d}'", .{vector_index}); 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.failWithOwnedErrorMsg(block, msg);
} }
return sema.fail(block, src, "overflow of integer type '{}' with value '{}'", .{ 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 // in turn helps to avoid unreasonably long symbol names for namespaced
// symbols. Such names should ideally be human-readable, and additionally, // symbols. Such names should ideally be human-readable, and additionally,
// some tooling may not support very long symbol names. // some tooling may not support very long symbol names.
try writer.print("{}", .{Value.fmtValueFull(.{ try writer.print("{}", .{Value.fmtValueSemaFull(.{
.val = arg_val, .val = arg_val,
.pt = pt, .pt = pt,
.opt_sema = sema, .opt_sema = sema,
@ -3202,7 +3202,7 @@ fn zirEnumDecl(
.offset = .{ .container_field_value = conflict.prev_field_idx }, .offset = .{ .container_field_value = conflict.prev_field_idx },
}; };
const msg = msg: { 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); errdefer msg.destroy(gpa);
try sema.errNote(other_field_src, msg, "other occurrence here", .{}); try sema.errNote(other_field_src, msg, "other occurrence here", .{});
break :msg msg; break :msg msg;
@ -3224,7 +3224,7 @@ fn zirEnumDecl(
.offset = .{ .container_field_value = conflict.prev_field_idx }, .offset = .{ .container_field_value = conflict.prev_field_idx },
}; };
const msg = msg: { 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); errdefer msg.destroy(gpa);
try sema.errNote(other_field_src, msg, "other occurrence here", .{}); try sema.errNote(other_field_src, msg, "other occurrence here", .{});
break :msg msg; break :msg msg;
@ -3242,7 +3242,7 @@ fn zirEnumDecl(
if (tag_overflow) { if (tag_overflow) {
const msg = try sema.errMsg(value_src, "enumeration value '{}' too large for type '{}'", .{ 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); 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, .input_index = len_idx,
} }); } });
try sema.errNote(a_src, msg, "length {} here", .{ try sema.errNote(a_src, msg, "length {} here", .{
v.fmtValue(pt, sema), v.fmtValueSema(pt, sema),
}); });
try sema.errNote(arg_src, msg, "length {} here", .{ try sema.errNote(arg_src, msg, "length {} here", .{
arg_val.fmtValue(pt, sema), arg_val.fmtValueSema(pt, sema),
}); });
break :msg msg; break :msg msg;
}; };
@ -5853,7 +5853,7 @@ fn zirCompileLog(
const arg_ty = sema.typeOf(arg); const arg_ty = sema.typeOf(arg);
if (try sema.resolveValueResolveLazy(arg)) |val| { if (try sema.resolveValueResolveLazy(arg)) |val| {
try writer.print("@as({}, {})", .{ try writer.print("@as({}, {})", .{
arg_ty.fmt(pt), val.fmtValue(pt, sema), arg_ty.fmt(pt), val.fmtValueSema(pt, sema),
}); });
} else { } else {
try writer.print("@as({}, [runtime value])", .{arg_ty.fmt(pt)}); 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 Air.internedToRef((try pt.getCoerced(int_val, dest_ty)).toIntern());
} }
return sema.fail(block, src, "int value '{}' out of range of non-exhaustive enum '{}'", .{ 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)) { 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))) { if (!(try sema.enumHasInt(dest_ty, int_val))) {
return sema.fail(block, src, "enum '{}' has no tag with value '{}'", .{ 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()); 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); const rhs_elem = try rhs_val.elemValue(pt, i);
if (rhs_elem.compareHetero(.gte, bit_value, pt)) { 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 '{}'", .{ 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, i,
scalar_ty.fmt(pt), scalar_ty.fmt(pt),
}); });
@ -14075,7 +14075,7 @@ fn zirShl(
} }
} else if (rhs_val.compareHetero(.gte, bit_value, pt)) { } else if (rhs_val.compareHetero(.gte, bit_value, pt)) {
return sema.fail(block, rhs_src, "shift amount '{}' is too large for operand type '{}'", .{ 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), scalar_ty.fmt(pt),
}); });
} }
@ -14086,14 +14086,14 @@ fn zirShl(
const rhs_elem = try rhs_val.elemValue(pt, i); const rhs_elem = try rhs_val.elemValue(pt, i);
if (rhs_elem.compareHetero(.lt, try pt.intValue(scalar_rhs_ty, 0), pt)) { 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}'", .{ return sema.fail(block, rhs_src, "shift by negative amount '{}' at index '{d}'", .{
rhs_elem.fmtValue(pt, sema), rhs_elem.fmtValueSema(pt, sema),
i, i,
}); });
} }
} }
} else if (rhs_val.compareHetero(.lt, try pt.intValue(rhs_ty, 0), pt)) { } else if (rhs_val.compareHetero(.lt, try pt.intValue(rhs_ty, 0), pt)) {
return sema.fail(block, rhs_src, "shift by negative amount '{}'", .{ 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); const rhs_elem = try rhs_val.elemValue(pt, i);
if (rhs_elem.compareHetero(.gte, bit_value, pt)) { 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 '{}'", .{ 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, i,
scalar_ty.fmt(pt), scalar_ty.fmt(pt),
}); });
@ -14241,7 +14241,7 @@ fn zirShr(
} }
} else if (rhs_val.compareHetero(.gte, bit_value, pt)) { } else if (rhs_val.compareHetero(.gte, bit_value, pt)) {
return sema.fail(block, rhs_src, "shift amount '{}' is too large for operand type '{}'", .{ 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), scalar_ty.fmt(pt),
}); });
} }
@ -14252,14 +14252,14 @@ fn zirShr(
const rhs_elem = try rhs_val.elemValue(pt, i); const rhs_elem = try rhs_val.elemValue(pt, i);
if (rhs_elem.compareHetero(.lt, try pt.intValue(rhs_ty.childType(mod), 0), pt)) { 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}'", .{ return sema.fail(block, rhs_src, "shift by negative amount '{}' at index '{d}'", .{
rhs_elem.fmtValue(pt, sema), rhs_elem.fmtValueSema(pt, sema),
i, i,
}); });
} }
} }
} else if (rhs_val.compareHetero(.lt, try pt.intValue(rhs_ty, 0), pt)) { } else if (rhs_val.compareHetero(.lt, try pt.intValue(rhs_ty, 0), pt)) {
return sema.fail(block, rhs_src, "shift by negative amount '{}'", .{ 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| { if (maybe_lhs_val) |lhs_val| {
@ -15190,7 +15190,7 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
block, block,
src, src,
"ambiguous coercion of division operands '{}' and '{}'; non-zero remainder '{}'", "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 field_index = enum_ty.enumTagFieldIndex(val, mod) orelse {
const msg = msg: { const msg = msg: {
const msg = try sema.errMsg(src, "no field with value '{}' in enum '{}'", .{ 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); errdefer msg.destroy(sema.gpa);
try sema.errNote(enum_ty.srcLoc(mod), msg, "declared here", .{}); try sema.errNote(enum_ty.srcLoc(mod), msg, "declared here", .{});
@ -22005,7 +22005,7 @@ fn reifyEnum(
// TODO: better source location // TODO: better source location
return sema.fail(block, src, "field '{}' with enumeration value '{}' is too large for backing int type '{}'", .{ return sema.fail(block, src, "field '{}' with enumeration value '{}' is too large for backing int type '{}'", .{
field_name.fmt(ip), field_name.fmt(ip),
field_value_val.fmtValue(pt, sema), field_value_val.fmtValueSema(pt, sema),
tag_ty.fmt(pt), tag_ty.fmt(pt),
}); });
} }
@ -22021,7 +22021,7 @@ fn reifyEnum(
break :msg msg; break :msg msg;
}, },
.value => 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); errdefer msg.destroy(gpa);
_ = conflict.prev_field_idx; // TODO: this note is incorrect _ = conflict.prev_field_idx; // TODO: this note is incorrect
try sema.errNote(src, msg, "other enum tag value here", .{}); try sema.errNote(src, msg, "other enum tag value here", .{});
@ -23194,12 +23194,12 @@ fn ptrCastFull(
return sema.failWithOwnedErrorMsg(block, msg: { return sema.failWithOwnedErrorMsg(block, msg: {
const msg = if (src_info.sentinel == .none) blk: { const msg = if (src_info.sentinel == .none) blk: {
break :blk try sema.errMsg(src, "destination pointer requires '{}' sentinel", .{ 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: { } else blk: {
break :blk try sema.errMsg(src, "pointer sentinel '{}' cannot coerce into pointer sentinel '{}'", .{ break :blk try sema.errMsg(src, "pointer sentinel '{}' cannot coerce into pointer sentinel '{}'", .{
Value.fromInterned(src_info.sentinel).fmtValue(pt, sema), Value.fromInterned(src_info.sentinel).fmtValueSema(pt, sema),
Value.fromInterned(dest_info.sentinel).fmtValue(pt, sema), Value.fromInterned(dest_info.sentinel).fmtValueSema(pt, sema),
}); });
}; };
errdefer msg.destroy(sema.gpa); 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", .{}); const msg = try sema.errMsg(src, "non-matching @memcpy lengths", .{});
errdefer msg.destroy(sema.gpa); errdefer msg.destroy(sema.gpa);
try sema.errNote(dest_src, msg, "length {} here", .{ 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", .{ try sema.errNote(src_src, msg, "length {} here", .{
src_len_val.fmtValue(pt, sema), src_len_val.fmtValueSema(pt, sema),
}); });
break :msg msg; break :msg msg;
}; };
@ -29563,7 +29563,7 @@ fn coerceExtra(
// comptime-known integer to other number // comptime-known integer to other number
if (!(try sema.intFitsInType(val, dest_ty, null))) { if (!(try sema.intFitsInType(val, dest_ty, null))) {
if (!opts.report_err) return error.NotCoercible; 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())) { return switch (zcu.intern_pool.indexToKey(val.toIntern())) {
.undef => try pt.undefRef(dest_ty), .undef => try pt.undefRef(dest_ty),
@ -29608,7 +29608,7 @@ fn coerceExtra(
block, block,
inst_src, inst_src,
"type '{}' cannot represent float value '{}'", "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()); return Air.internedToRef(result_val.toIntern());
@ -30026,11 +30026,11 @@ const InMemoryCoercionResult = union(enum) {
.array_sentinel => |sentinel| { .array_sentinel => |sentinel| {
if (sentinel.actual.toIntern() != .unreachable_value) { if (sentinel.actual.toIntern() != .unreachable_value) {
try sema.errNote(src, msg, "array sentinel '{}' cannot cast into array sentinel '{}'", .{ 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 { } else {
try sema.errNote(src, msg, "destination array requires '{}' sentinel", .{ try sema.errNote(src, msg, "destination array requires '{}' sentinel", .{
sentinel.wanted.fmtValue(pt, sema), sentinel.wanted.fmtValueSema(pt, sema),
}); });
} }
break; break;
@ -30152,11 +30152,11 @@ const InMemoryCoercionResult = union(enum) {
.ptr_sentinel => |sentinel| { .ptr_sentinel => |sentinel| {
if (sentinel.actual.toIntern() != .unreachable_value) { if (sentinel.actual.toIntern() != .unreachable_value) {
try sema.errNote(src, msg, "pointer sentinel '{}' cannot cast into pointer sentinel '{}'", .{ 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 { } else {
try sema.errNote(src, msg, "destination pointer requires '{}' sentinel", .{ try sema.errNote(src, msg, "destination pointer requires '{}' sentinel", .{
sentinel.wanted.fmtValue(pt, sema), sentinel.wanted.fmtValueSema(pt, sema),
}); });
} }
break; break;
@ -31412,7 +31412,7 @@ fn coerceEnumToUnion(
if (try sema.resolveDefinedValue(block, inst_src, enum_tag)) |val| { if (try sema.resolveDefinedValue(block, inst_src, enum_tag)) |val| {
const field_index = union_ty.unionTagFieldIndex(val, pt.zcu) orelse { const field_index = union_ty.unionTagFieldIndex(val, pt.zcu) orelse {
return sema.fail(block, inst_src, "union '{}' has no tag with value '{}'", .{ 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, msg,
"expected '{}', found '{}'", "expected '{}', found '{}'",
.{ .{
Value.zero_comptime_int.fmtValue(pt, sema), Value.zero_comptime_int.fmtValueSema(pt, sema),
start_value.fmtValue(pt, sema), start_value.fmtValueSema(pt, sema),
}, },
); );
break :msg msg; break :msg msg;
@ -32660,8 +32660,8 @@ fn analyzeSlice(
msg, msg,
"expected '{}', found '{}'", "expected '{}', found '{}'",
.{ .{
Value.one_comptime_int.fmtValue(pt, sema), Value.one_comptime_int.fmtValueSema(pt, sema),
end_value.fmtValue(pt, sema), end_value.fmtValueSema(pt, sema),
}, },
); );
break :msg msg; break :msg msg;
@ -32674,7 +32674,7 @@ fn analyzeSlice(
block, block,
end_src, end_src,
"end index {} out of bounds for slice of single-item pointer", "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_src,
"end index {} out of bounds for array of length {}{s}", "end index {} out of bounds for array of length {}{s}",
.{ .{
end_val.fmtValue(pt, sema), end_val.fmtValueSema(pt, sema),
len_val.fmtValue(pt, sema), len_val.fmtValueSema(pt, sema),
sentinel_label, sentinel_label,
}, },
); );
@ -32814,7 +32814,7 @@ fn analyzeSlice(
end_src, end_src,
"end index {} out of bounds for slice of length {d}{s}", "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), try slice_val.sliceLen(pt),
sentinel_label, sentinel_label,
}, },
@ -32874,8 +32874,8 @@ fn analyzeSlice(
start_src, start_src,
"start index {} is larger than end index {}", "start index {} is larger than end index {}",
.{ .{
start_val.fmtValue(pt, sema), start_val.fmtValueSema(pt, sema),
end_val.fmtValue(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", .{}); const msg = try sema.errMsg(src, "value in memory does not match slice sentinel", .{});
errdefer msg.destroy(sema.gpa); errdefer msg.destroy(sema.gpa);
try sema.errNote(src, msg, "expected '{}', found '{}'", .{ try sema.errNote(src, msg, "expected '{}', found '{}'", .{
expected_sentinel.fmtValue(pt, sema), expected_sentinel.fmtValueSema(pt, sema),
actual_sentinel.fmtValue(pt, sema), actual_sentinel.fmtValueSema(pt, sema),
}); });
break :msg msg; 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) }, .offset = .{ .container_field_value = @intCast(gop.index) },
}; };
const msg = msg: { 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); errdefer msg.destroy(gpa);
try sema.errNote(other_value_src, msg, "other occurrence here", .{}); try sema.errNote(other_value_src, msg, "other occurrence here", .{});
break :msg msg; break :msg msg;
@ -37888,7 +37888,7 @@ fn intFromFloatScalar(
block, block,
src, src,
"fractional component prevents float value '{}' from coercion to type '{}'", "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); const float = val.toFloat(f128, pt);
@ -37910,7 +37910,7 @@ fn intFromFloatScalar(
if (!(try sema.intFitsInType(cti_result, int_ty, null))) { if (!(try sema.intFitsInType(cti_result, int_ty, null))) {
return sema.fail(block, src, "float value '{}' cannot be stored in integer type '{}'", .{ 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); return pt.getCoerced(cti_result, int_ty);

View File

@ -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) { if (info.sentinel != .none) switch (info.flags.size) {
.One, .C => unreachable, .One, .C => unreachable,
.Many => 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, null)}), .Slice => try writer.print("[:{}]", .{Value.fromInterned(info.sentinel).fmtValue(pt)}),
} else switch (info.flags.size) { } else switch (info.flags.size) {
.One => try writer.writeAll("*"), .One => try writer.writeAll("*"),
.Many => 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 { } else {
try writer.print("[{d}:{}]", .{ try writer.print("[{d}:{}]", .{
array_type.len, 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); 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); try print(Type.fromInterned(field_ty), writer, pt);
if (val != .none) { if (val != .none) {
try writer.print(" = {}", .{Value.fromInterned(val).fmtValue(pt, null)}); try writer.print(" = {}", .{Value.fromInterned(val).fmtValue(pt)});
} }
} }
try writer.writeAll("}"); try writer.writeAll("}");
@ -478,7 +478,7 @@ pub fn hasRuntimeBitsAdvanced(
ty: Type, ty: Type,
pt: Zcu.PerThread, pt: Zcu.PerThread,
ignore_comptime_only: bool, ignore_comptime_only: bool,
strat: ResolveStratLazy, comptime strat: ResolveStratLazy,
) RuntimeBitsError!bool { ) RuntimeBitsError!bool {
const mod = pt.zcu; const mod = pt.zcu;
const ip = &mod.intern_pool; 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 /// Determines whether a function type has runtime bits, i.e. whether a
/// function with this type can exist at runtime. /// function with this type can exist at runtime.
/// Asserts that `ty` is a function type. /// 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).?; const fn_info = pt.zcu.typeToFunc(ty).?;
if (fn_info.is_generic) return false; if (fn_info.is_generic) return false;
if (fn_info.is_var_args) return true; 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; 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())) { return switch (pt.zcu.intern_pool.indexToKey(ty.toIntern())) {
.ptr_type => |ptr_type| { .ptr_type => |ptr_type| {
if (ptr_type.flags.alignment != .none) if (ptr_type.flags.alignment != .none)
@ -891,7 +891,7 @@ pub const ResolveStrat = enum {
/// This should typically be used from semantic analysis. /// This should typically be used from semantic analysis.
sema, sema,
pub fn toLazy(strat: ResolveStrat) ResolveStratLazy { pub inline fn toLazy(strat: ResolveStrat) ResolveStratLazy {
return switch (strat) { return switch (strat) {
.normal => .eager, .normal => .eager,
.sema => .sema, .sema => .sema,
@ -908,7 +908,7 @@ pub const ResolveStrat = enum {
pub fn abiAlignmentAdvanced( pub fn abiAlignmentAdvanced(
ty: Type, ty: Type,
pt: Zcu.PerThread, pt: Zcu.PerThread,
strat: ResolveStratLazy, comptime strat: ResolveStratLazy,
) SemaError!AbiAlignmentAdvanced { ) SemaError!AbiAlignmentAdvanced {
const mod = pt.zcu; const mod = pt.zcu;
const target = mod.getTarget(); const target = mod.getTarget();
@ -932,7 +932,9 @@ pub fn abiAlignmentAdvanced(
if (vector_type.len == 0) return .{ .scalar = .@"1" }; if (vector_type.len == 0) return .{ .scalar = .@"1" };
switch (mod.comp.getZigBackend()) { switch (mod.comp.getZigBackend()) {
else => { 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" }; if (elem_bits == 0) return .{ .scalar = .@"1" };
const bytes = ((elem_bits * vector_type.len) + 7) / 8; const bytes = ((elem_bits * vector_type.len) + 7) / 8;
const alignment = std.math.ceilPowerOfTwoAssert(u32, bytes); const alignment = std.math.ceilPowerOfTwoAssert(u32, bytes);
@ -1130,7 +1132,7 @@ pub fn abiAlignmentAdvanced(
fn abiAlignmentAdvancedErrorUnion( fn abiAlignmentAdvancedErrorUnion(
ty: Type, ty: Type,
pt: Zcu.PerThread, pt: Zcu.PerThread,
strat: ResolveStratLazy, comptime strat: ResolveStratLazy,
payload_ty: Type, payload_ty: Type,
) SemaError!AbiAlignmentAdvanced { ) SemaError!AbiAlignmentAdvanced {
// This code needs to be kept in sync with the equivalent switch prong // This code needs to be kept in sync with the equivalent switch prong
@ -1167,7 +1169,7 @@ fn abiAlignmentAdvancedErrorUnion(
fn abiAlignmentAdvancedOptional( fn abiAlignmentAdvancedOptional(
ty: Type, ty: Type,
pt: Zcu.PerThread, pt: Zcu.PerThread,
strat: ResolveStratLazy, comptime strat: ResolveStratLazy,
) SemaError!AbiAlignmentAdvanced { ) SemaError!AbiAlignmentAdvanced {
const mod = pt.zcu; const mod = pt.zcu;
const target = mod.getTarget(); const target = mod.getTarget();
@ -1231,7 +1233,7 @@ const AbiSizeAdvanced = union(enum) {
pub fn abiSizeAdvanced( pub fn abiSizeAdvanced(
ty: Type, ty: Type,
pt: Zcu.PerThread, pt: Zcu.PerThread,
strat: ResolveStratLazy, comptime strat: ResolveStratLazy,
) SemaError!AbiSizeAdvanced { ) SemaError!AbiSizeAdvanced {
const mod = pt.zcu; const mod = pt.zcu;
const target = mod.getTarget(); const target = mod.getTarget();
@ -1505,7 +1507,7 @@ pub fn abiSizeAdvanced(
fn abiSizeAdvancedOptional( fn abiSizeAdvancedOptional(
ty: Type, ty: Type,
pt: Zcu.PerThread, pt: Zcu.PerThread,
strat: ResolveStratLazy, comptime strat: ResolveStratLazy,
) SemaError!AbiSizeAdvanced { ) SemaError!AbiSizeAdvanced {
const mod = pt.zcu; const mod = pt.zcu;
const child_ty = ty.optionalChild(mod); const child_ty = ty.optionalChild(mod);
@ -1680,7 +1682,7 @@ pub fn bitSize(ty: Type, pt: Zcu.PerThread) u64 {
pub fn bitSizeAdvanced( pub fn bitSizeAdvanced(
ty: Type, ty: Type,
pt: Zcu.PerThread, pt: Zcu.PerThread,
strat: ResolveStrat, comptime strat: ResolveStrat,
) SemaError!u64 { ) SemaError!u64 {
const mod = pt.zcu; const mod = pt.zcu;
const target = mod.getTarget(); const target = mod.getTarget();
@ -2739,7 +2741,7 @@ pub fn comptimeOnly(ty: Type, pt: Zcu.PerThread) bool {
/// `generic_poison` will return false. /// `generic_poison` will return false.
/// May return false negatives when structs and unions are having their field types resolved. /// 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 mod = pt.zcu;
const ip = &mod.intern_pool; const ip = &mod.intern_pool;
return switch (ty.toIntern()) { return switch (ty.toIntern()) {
@ -2829,7 +2831,8 @@ pub fn comptimeOnlyAdvanced(ty: Type, pt: Zcu.PerThread, strat: ResolveStrat) Se
.no, .wip => false, .no, .wip => false,
.yes => true, .yes => true,
.unknown => { .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) { if (struct_type.flagsUnordered(ip).field_types_wip) {
struct_type.setRequiresComptime(ip, .unknown); struct_type.setRequiresComptime(ip, .unknown);
@ -2874,7 +2877,8 @@ pub fn comptimeOnlyAdvanced(ty: Type, pt: Zcu.PerThread, strat: ResolveStrat) Se
.no, .wip => return false, .no, .wip => return false,
.yes => return true, .yes => return true,
.unknown => { .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) { if (union_type.flagsUnordered(ip).status == .field_types_wip) {
union_type.setRequiresComptime(ip, .unknown); 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; 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; const ip = &pt.zcu.intern_pool;
switch (ip.indexToKey(ty.toIntern())) { switch (ip.indexToKey(ty.toIntern())) {
.struct_type => { .struct_type => {

View File

@ -40,16 +40,25 @@ pub fn fmtDebug(val: Value) std.fmt.Formatter(dump) {
return .{ .data = val }; 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 = .{ return .{ .data = .{
.val = val, .val = val,
.pt = pt, .pt = pt,
.opt_sema = opt_sema, .opt_sema = null,
.depth = 3, .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 }; return .{ .data = ctx };
} }
@ -178,7 +187,7 @@ pub fn toBigIntAdvanced(
val: Value, val: Value,
space: *BigIntSpace, space: *BigIntSpace,
pt: Zcu.PerThread, pt: Zcu.PerThread,
strat: ResolveStrat, comptime strat: ResolveStrat,
) Module.CompileError!BigIntConst { ) Module.CompileError!BigIntConst {
return switch (val.toIntern()) { return switch (val.toIntern()) {
.bool_false => BigIntMutable.init(&space.limbs, 0).toConst(), .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. /// If the value fits in a u64, return it, otherwise null.
/// Asserts not undefined. /// 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; const mod = pt.zcu;
return switch (val.toIntern()) { return switch (val.toIntern()) {
.undef => unreachable, .undef => unreachable,
@ -1042,7 +1051,7 @@ pub fn orderAgainstZero(lhs: Value, pt: Zcu.PerThread) std.math.Order {
pub fn orderAgainstZeroAdvanced( pub fn orderAgainstZeroAdvanced(
lhs: Value, lhs: Value,
pt: Zcu.PerThread, pt: Zcu.PerThread,
strat: ResolveStrat, comptime strat: ResolveStrat,
) Module.CompileError!std.math.Order { ) Module.CompileError!std.math.Order {
return switch (lhs.toIntern()) { return switch (lhs.toIntern()) {
.bool_false => .eq, .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. /// 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 lhs_against_zero = try lhs.orderAgainstZeroAdvanced(pt, strat);
const rhs_against_zero = try rhs.orderAgainstZeroAdvanced(pt, strat); const rhs_against_zero = try rhs.orderAgainstZeroAdvanced(pt, strat);
switch (lhs_against_zero) { switch (lhs_against_zero) {
@ -1119,7 +1128,7 @@ pub fn compareHeteroAdvanced(
op: std.math.CompareOperator, op: std.math.CompareOperator,
rhs: Value, rhs: Value,
pt: Zcu.PerThread, pt: Zcu.PerThread,
strat: ResolveStrat, comptime strat: ResolveStrat,
) !bool { ) !bool {
if (lhs.pointerDecl(pt.zcu)) |lhs_decl| { if (lhs.pointerDecl(pt.zcu)) |lhs_decl| {
if (rhs.pointerDecl(pt.zcu)) |rhs_decl| { if (rhs.pointerDecl(pt.zcu)) |rhs_decl| {
@ -1199,7 +1208,7 @@ pub fn compareAllWithZeroAdvancedExtra(
lhs: Value, lhs: Value,
op: std.math.CompareOperator, op: std.math.CompareOperator,
pt: Zcu.PerThread, pt: Zcu.PerThread,
strat: ResolveStrat, comptime strat: ResolveStrat,
) Module.CompileError!bool { ) Module.CompileError!bool {
const mod = pt.zcu; const mod = pt.zcu;
if (lhs.isInf(mod)) { if (lhs.isInf(mod)) {
@ -1505,7 +1514,7 @@ pub fn floatFromIntAdvanced(
int_ty: Type, int_ty: Type,
float_ty: Type, float_ty: Type,
pt: Zcu.PerThread, pt: Zcu.PerThread,
strat: ResolveStrat, comptime strat: ResolveStrat,
) !Value { ) !Value {
const mod = pt.zcu; const mod = pt.zcu;
if (int_ty.zigTypeTag(mod) == .Vector) { if (int_ty.zigTypeTag(mod) == .Vector) {
@ -1523,7 +1532,7 @@ pub fn floatFromIntAdvanced(
return floatFromIntScalar(val, float_ty, pt, strat); 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; const mod = pt.zcu;
return switch (mod.intern_pool.indexToKey(val.toIntern())) { return switch (mod.intern_pool.indexToKey(val.toIntern())) {
.undef => try pt.undefValue(float_ty), .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 { 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.OutOfMemory => |e| return e,
error.AnalysisFail => unreachable, 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 /// 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. /// which prefer field/elem accesses when lowering constant pointer values.
/// It is also used by the Value printing logic for pointers. /// 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 zcu = pt.zcu;
const ptr = zcu.intern_pool.indexToKey(ptr_val.toIntern()).ptr; const ptr = zcu.intern_pool.indexToKey(ptr_val.toIntern()).ptr;
const base_derive: PointerDeriveStep = switch (ptr.base_addr) { 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: { .comptime_alloc => |idx| base: {
const alloc = opt_sema.?.getComptimeAlloc(idx); if (!have_sema) unreachable;
const val = try alloc.val.intern(pt, opt_sema.?.arena); const alloc = sema.getComptimeAlloc(idx);
const val = try alloc.val.intern(pt, sema.arena);
const ty = val.typeOf(zcu); const ty = val.typeOf(zcu);
break :base .{ .comptime_alloc_ptr = .{ break :base .{ .comptime_alloc_ptr = .{
.val = val, .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 = Value.fromInterned(eu_ptr);
const base_ptr_ty = base_ptr.typeOf(zcu); const base_ptr_ty = base_ptr.typeOf(zcu);
const parent_step = try arena.create(PointerDeriveStep); 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 = .{ break :base .{ .eu_payload_ptr = .{
.parent = parent_step, .parent = parent_step,
.result_ptr_ty = try pt.adjustPtrTypeChild(base_ptr_ty, base_ptr_ty.childType(zcu).errorUnionPayload(zcu)), .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 = Value.fromInterned(opt_ptr);
const base_ptr_ty = base_ptr.typeOf(zcu); const base_ptr_ty = base_ptr.typeOf(zcu);
const parent_step = try arena.create(PointerDeriveStep); 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 = .{ break :base .{ .opt_payload_ptr = .{
.parent = parent_step, .parent = parent_step,
.result_ptr_ty = try pt.adjustPtrTypeChild(base_ptr_ty, base_ptr_ty.childType(zcu).optionalChild(zcu)), .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 base_ptr_ty = base_ptr.typeOf(zcu);
const agg_ty = base_ptr_ty.childType(zcu); const agg_ty = base_ptr_ty.childType(zcu);
const field_ty, const field_align = switch (agg_ty.zigTypeTag(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) }, .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, .sema) }, .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) { .Pointer => .{ switch (field.index) {
Value.slice_ptr_index => agg_ty.slicePtrFieldType(zcu), Value.slice_ptr_index => agg_ty.slicePtrFieldType(zcu),
Value.slice_len_index => Type.usize, 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); 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 = .{ break :base .{ .field_ptr = .{
.parent = parent_step, .parent = parent_step,
.field_idx = @intCast(field.index), .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: { .arr_elem => |arr_elem| base: {
const parent_step = try arena.create(PointerDeriveStep); 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 parent_ptr_info = (try parent_step.ptrType(pt)).ptrInfo(zcu);
const result_ptr_ty = try pt.ptrType(.{ const result_ptr_ty = try pt.ptrType(.{
.child = parent_ptr_info.child, .child = parent_ptr_info.child,

View File

@ -3163,7 +3163,7 @@ pub fn unionFieldNormalAlignmentAdvanced(
pt: Zcu.PerThread, pt: Zcu.PerThread,
loaded_union: InternPool.LoadedUnionType, loaded_union: InternPool.LoadedUnionType,
field_index: u32, field_index: u32,
strat: Type.ResolveStrat, comptime strat: Type.ResolveStrat,
) Zcu.SemaError!InternPool.Alignment { ) Zcu.SemaError!InternPool.Alignment {
const ip = &pt.zcu.intern_pool; const ip = &pt.zcu.intern_pool;
assert(loaded_union.flagsUnordered(ip).layout != .@"packed"); assert(loaded_union.flagsUnordered(ip).layout != .@"packed");
@ -3191,7 +3191,7 @@ pub fn structFieldAlignmentAdvanced(
explicit_alignment: InternPool.Alignment, explicit_alignment: InternPool.Alignment,
field_ty: Type, field_ty: Type,
layout: std.builtin.Type.ContainerLayout, layout: std.builtin.Type.ContainerLayout,
strat: Type.ResolveStrat, comptime strat: Type.ResolveStrat,
) Zcu.SemaError!InternPool.Alignment { ) Zcu.SemaError!InternPool.Alignment {
assert(layout != .@"packed"); assert(layout != .@"packed");
if (explicit_alignment != .none) return explicit_alignment; if (explicit_alignment != .none) return explicit_alignment;

View File

@ -17975,8 +17975,8 @@ fn airShuffle(self: *Self, inst: Air.Inst.Index) !void {
break :result null; break :result null;
}) orelse return self.fail("TODO implement airShuffle from {} and {} to {} with {}", .{ }) orelse return self.fail("TODO implement airShuffle from {} and {} to {} with {}", .{
lhs_ty.fmt(pt), rhs_ty.fmt(pt), dst_ty.fmt(pt), lhs_ty.fmt(pt), rhs_ty.fmt(pt), dst_ty.fmt(pt),
Value.fromInterned(extra.mask).fmtValue(pt, null), Value.fromInterned(extra.mask).fmtValue(pt),
}); });
return self.finishAir(inst, result, .{ extra.a, extra.b, .none }); return self.finishAir(inst, result, .{ extra.a, extra.b, .none });
} }

View File

@ -188,7 +188,7 @@ pub fn generateSymbol(
const target = mod.getTarget(); const target = mod.getTarget();
const endian = target.cpu.arch.endian(); 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)) { if (val.isUndefDeep(mod)) {
const abi_size = math.cast(usize, ty.abiSize(pt)) orelse return error.Overflow; const abi_size = math.cast(usize, ty.abiSize(pt)) orelse return error.Overflow;
@ -838,7 +838,7 @@ fn genDeclRef(
const zcu = pt.zcu; const zcu = pt.zcu;
const ip = &zcu.intern_pool; const ip = &zcu.intern_pool;
const ty = val.typeOf(zcu); 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 ptr_decl = zcu.declPtr(ptr_decl_index);
const namespace = zcu.namespacePtr(ptr_decl.src_namespace); const namespace = zcu.namespacePtr(ptr_decl.src_namespace);
@ -943,7 +943,7 @@ fn genUnnamedConst(
owner_decl_index: InternPool.DeclIndex, owner_decl_index: InternPool.DeclIndex,
) CodeGenError!GenResult { ) CodeGenError!GenResult {
const gpa = lf.comp.gpa; 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| { 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)}); 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 ip = &zcu.intern_pool;
const ty = val.typeOf(zcu); const ty = val.typeOf(zcu);
log.debug("genTypedValue: val = {}", .{val.fmtValue(pt, null)}); log.debug("genTypedValue: val = {}", .{val.fmtValue(pt)});
if (val.isUndef(zcu)) if (val.isUndef(zcu))
return GenResult.mcv(.undef); return GenResult.mcv(.undef);

View File

@ -892,7 +892,7 @@ const DeclGen = struct {
const result_ty_id = try self.resolveType(ty, repr); const result_ty_id = try self.resolveType(ty, repr);
const ip = &mod.intern_pool; 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)) { if (val.isUndefDeep(mod)) {
return self.spv.constUndef(result_ty_id); return self.spv.constUndef(result_ty_id);
} }

View File

@ -957,7 +957,7 @@ const Writer = struct {
const ty = Type.fromInterned(pt.zcu.intern_pool.indexToKey(ip_index).typeOf()); const ty = Type.fromInterned(pt.zcu.intern_pool.indexToKey(ip_index).typeOf());
try s.print("<{}, {}>", .{ try s.print("<{}, {}>", .{
ty.fmt(pt), ty.fmt(pt),
Value.fromInterned(ip_index).fmtValue(pt, null), Value.fromInterned(ip_index).fmtValue(pt),
}); });
} else { } else {
return w.writeInstIndex(s, operand.toIndex().?, dies); return w.writeInstIndex(s, operand.toIndex().?, dies);

View File

@ -20,6 +20,23 @@ pub const FormatContext = struct {
depth: u8, depth: u8,
}; };
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, 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 `sema` more fully
else => |e| return e,
};
}
pub fn format( pub fn format(
ctx: FormatContext, ctx: FormatContext,
comptime fmt: []const u8, comptime fmt: []const u8,
@ -27,11 +44,11 @@ pub fn format(
writer: anytype, writer: anytype,
) !void { ) !void {
_ = options; _ = options;
std.debug.assert(ctx.opt_sema == null);
comptime std.debug.assert(fmt.len == 0); 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, false, {}) catch |err| switch (err) {
error.OutOfMemory => @panic("OOM"), // We're not allowed to return this from a format function error.OutOfMemory => @panic("OOM"), // We're not allowed to return this from a format function
error.ComptimeBreak, error.ComptimeReturn => unreachable, error.ComptimeBreak, error.ComptimeReturn, error.AnalysisFail => unreachable,
error.AnalysisFail => unreachable, // TODO: re-evaluate when we use `opt_sema` more fully
else => |e| return e, else => |e| return e,
}; };
} }
@ -42,7 +59,8 @@ pub fn print(
level: u8, level: u8,
pt: Zcu.PerThread, pt: Zcu.PerThread,
/// If this `Sema` is provided, we will recurse through pointers where possible to provide friendly output. /// 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 { ) (@TypeOf(writer).Error || Zcu.CompileError)!void {
const mod = pt.zcu; const mod = pt.zcu;
const ip = &mod.intern_pool; const ip = &mod.intern_pool;
@ -80,11 +98,11 @@ pub fn print(
}), }),
.int => |int| switch (int.storage) { .int => |int| switch (int.storage) {
inline .u64, .i64, .big_int => |x| try writer.print("{}", .{x}), 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; const a = (try Type.fromInterned(ty).abiAlignmentAdvanced(pt, .sema)).scalar;
try writer.print("{}", .{a.toByteUnits() orelse 0}); try writer.print("{}", .{a.toByteUnits() orelse 0});
} else try writer.print("@alignOf({})", .{Type.fromInterned(ty).fmt(pt)}), } 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; const s = (try Type.fromInterned(ty).abiSizeAdvanced(pt, .sema)).scalar;
try writer.print("{}", .{s}); try writer.print("{}", .{s});
} else try writer.print("@sizeOf({})", .{Type.fromInterned(ty).fmt(pt)}), } 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 => |err_name| try writer.print("error.{}", .{
err_name.fmt(ip), 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 => |enum_literal| try writer.print(".{}", .{
enum_literal.fmt(ip), enum_literal.fmt(ip),
@ -110,7 +128,7 @@ pub fn print(
return writer.writeAll("@enumFromInt(...)"); return writer.writeAll("@enumFromInt(...)");
} }
try 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(")"); try writer.writeAll(")");
}, },
.empty_enum_value => try writer.writeAll("(empty enum value)"), .empty_enum_value => try writer.writeAll("(empty enum value)"),
@ -124,15 +142,15 @@ pub fn print(
.decl, .int => false, .decl, .int => false,
}; };
if (print_contents) { 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. // 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.."); try writer.writeAll("[0..");
if (level == 0) { if (level == 0) {
try writer.writeAll("(...)"); try writer.writeAll("(...)");
} else { } 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("]"); try writer.writeAll("]");
}, },
@ -143,16 +161,16 @@ pub fn print(
.decl, .int => false, .decl, .int => false,
}; };
if (print_contents) { 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. // 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) { .opt => |opt| switch (opt.val) {
.none => try writer.writeAll("null"), .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| { .un => |un| {
if (level == 0) { if (level == 0) {
try writer.writeAll(".{ ... }"); try writer.writeAll(".{ ... }");
@ -161,13 +179,13 @@ pub fn print(
if (un.tag == .none) { if (un.tag == .none) {
const backing_ty = try val.typeOf(mod).unionBackingType(pt); const backing_ty = try val.typeOf(mod).unionBackingType(pt);
try writer.print("@bitCast(@as({}, ", .{backing_ty.fmt(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("))"); try writer.writeAll("))");
} else { } else {
try writer.writeAll(".{ "); 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 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(" }"); try writer.writeAll(" }");
} }
}, },
@ -182,7 +200,8 @@ fn printAggregate(
writer: anytype, writer: anytype,
level: u8, level: u8,
pt: Zcu.PerThread, pt: Zcu.PerThread,
opt_sema: ?*Sema, comptime have_sema: bool,
sema: if (have_sema) *Sema else void,
) (@TypeOf(writer).Error || Zcu.CompileError)!void { ) (@TypeOf(writer).Error || Zcu.CompileError)!void {
if (level == 0) { if (level == 0) {
if (is_ref) try writer.writeByte('&'); if (is_ref) try writer.writeByte('&');
@ -203,7 +222,7 @@ fn printAggregate(
if (i != 0) try writer.writeAll(", "); if (i != 0) try writer.writeAll(", ");
const field_name = ty.structFieldName(@intCast(i), zcu).unwrap().?; const field_name = ty.structFieldName(@intCast(i), zcu).unwrap().?;
try writer.print(".{i} = ", .{field_name.fmt(ip)}); 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(" }"); try writer.writeAll(" }");
return; return;
@ -253,7 +272,7 @@ fn printAggregate(
const max_len = @min(len, max_aggregate_items); const max_len = @min(len, max_aggregate_items);
for (0..max_len) |i| { for (0..max_len) |i| {
if (i != 0) try writer.writeAll(", "); 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) { if (len > max_aggregate_items) {
try writer.writeAll(", ..."); try writer.writeAll(", ...");
@ -261,7 +280,14 @@ fn printAggregate(
return writer.writeAll(" }"); 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())) { const ptr = switch (pt.zcu.intern_pool.indexToKey(ptr_val.toIntern())) {
.undef => return writer.writeAll("undefined"), .undef => return writer.writeAll("undefined"),
.ptr => |ptr| ptr, .ptr => |ptr| ptr,
@ -278,7 +304,8 @@ fn printPtr(ptr_val: Value, writer: anytype, level: u8, pt: Zcu.PerThread, opt_s
writer, writer,
level, level,
pt, pt,
opt_sema, have_sema,
sema,
), ),
else => {}, 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); var arena = std.heap.ArenaAllocator.init(pt.zcu.gpa);
defer arena.deinit(); defer arena.deinit();
const derivation = try ptr_val.pointerDerivationAdvanced(arena.allocator(), pt, opt_sema); const derivation = try ptr_val.pointerDerivationAdvanced(arena.allocator(), pt, have_sema, sema);
try printPtrDerivation(derivation, writer, level, pt, opt_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. /// 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 zcu = pt.zcu;
const ip = &zcu.intern_pool; const ip = &zcu.intern_pool;
switch (derivation) { switch (derivation) {
@ -305,31 +339,31 @@ fn printPtrDerivation(derivation: Value.PointerDeriveStep, writer: anytype, leve
.anon_decl_ptr => |anon| { .anon_decl_ptr => |anon| {
const ty = Value.fromInterned(anon.val).typeOf(zcu); const ty = Value.fromInterned(anon.val).typeOf(zcu);
try writer.print("@as({}, ", .{ty.fmt(pt)}); 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(')'); try writer.writeByte(')');
}, },
.comptime_alloc_ptr => |info| { .comptime_alloc_ptr => |info| {
try writer.print("@as({}, ", .{info.val.typeOf(zcu).fmt(pt)}); 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(')'); try writer.writeByte(')');
}, },
.comptime_field_ptr => |val| { .comptime_field_ptr => |val| {
const ty = val.typeOf(zcu); const ty = val.typeOf(zcu);
try writer.print("@as({}, ", .{ty.fmt(pt)}); 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(')'); try writer.writeByte(')');
}, },
.eu_payload_ptr => |info| { .eu_payload_ptr => |info| {
try writer.writeByte('('); 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)"); try writer.writeAll(" catch unreachable)");
}, },
.opt_payload_ptr => |info| { .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(".?"); try writer.writeAll(".?");
}, },
.field_ptr => |field| { .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); const agg_ty = (try field.parent.ptrType(pt)).childType(zcu);
switch (agg_ty.zigTypeTag(zcu)) { switch (agg_ty.zigTypeTag(zcu)) {
.Struct => if (agg_ty.structFieldName(field.field_idx, zcu).unwrap()) |field_name| { .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| { .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}); try writer.print("[{d}]", .{elem.elem_idx});
}, },
.offset_and_cast => |oac| if (oac.byte_offset == 0) { .offset_and_cast => |oac| if (oac.byte_offset == 0) {
try writer.print("@as({}, @ptrCast(", .{oac.new_ptr_ty.fmt(pt)}); 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("))"); try writer.writeAll("))");
} else { } else {
try writer.print("@as({}, @ptrFromInt(@intFromPtr(", .{oac.new_ptr_ty.fmt(pt)}); 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}); try writer.print(") + {d}))", .{oac.byte_offset});
}, },
} }