compiler: eliminate legacy Value representation
Good riddance! Most of these changes are trivial. There's a fix for a minor bug this exposed in `Value.readFromPackedMemory`, but aside from that, it's all just things like changing `intern` calls to `toIntern`.
This commit is contained in:
@@ -497,13 +497,6 @@ pub const Decl = struct {
|
||||
};
|
||||
}
|
||||
|
||||
pub fn internValue(decl: *Decl, zcu: *Zcu) Allocator.Error!InternPool.Index {
|
||||
assert(decl.has_tv);
|
||||
const ip_index = try decl.val.intern(decl.typeOf(zcu), zcu);
|
||||
decl.val = Value.fromInterned(ip_index);
|
||||
return ip_index;
|
||||
}
|
||||
|
||||
pub fn isFunction(decl: Decl, zcu: *const Zcu) !bool {
|
||||
const tv = try decl.typedValue(zcu);
|
||||
return tv.ty.zigTypeTag(zcu) == .Fn;
|
||||
@@ -3763,7 +3756,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !SemaDeclResult {
|
||||
},
|
||||
}
|
||||
|
||||
decl.val = Value.fromInterned((try decl_tv.val.intern(decl_tv.ty, mod)));
|
||||
decl.val = decl_tv.val;
|
||||
// Function linksection, align, and addrspace were already set by Sema
|
||||
if (!is_func) {
|
||||
decl.alignment = blk: {
|
||||
@@ -5624,8 +5617,6 @@ pub fn markDeclAlive(mod: *Module, decl: *Decl) Allocator.Error!void {
|
||||
if (decl.alive) return;
|
||||
decl.alive = true;
|
||||
|
||||
_ = try decl.internValue(mod);
|
||||
|
||||
// This is the first time we are marking this Decl alive. We must
|
||||
// therefore recurse into its value and mark any Decl it references
|
||||
// as also alive, so that any Decl referenced does not get garbage collected.
|
||||
|
||||
116
src/Sema.zig
116
src/Sema.zig
@@ -7835,7 +7835,7 @@ fn analyzeCall(
|
||||
|
||||
if (is_comptime_call) {
|
||||
const result_val = try sema.resolveConstValue(block, .unneeded, result, undefined);
|
||||
const result_interned = try result_val.intern2(sema.fn_ret_ty, mod);
|
||||
const result_interned = result_val.toIntern();
|
||||
|
||||
// Transform ad-hoc inferred error set types into concrete error sets.
|
||||
const result_transformed = try sema.resolveAdHocInferredErrorSet(block, call_src, result_interned);
|
||||
@@ -7856,8 +7856,7 @@ fn analyzeCall(
|
||||
}
|
||||
|
||||
if (try sema.resolveValue(result)) |result_val| {
|
||||
const result_interned = try result_val.intern2(sema.fn_ret_ty, mod);
|
||||
const result_transformed = try sema.resolveAdHocInferredErrorSet(block, call_src, result_interned);
|
||||
const result_transformed = try sema.resolveAdHocInferredErrorSet(block, call_src, result_val.toIntern());
|
||||
break :res2 Air.internedToRef(result_transformed);
|
||||
}
|
||||
|
||||
@@ -8042,7 +8041,7 @@ fn analyzeInlineCallArg(
|
||||
// when the hash function is called.
|
||||
const resolved_arg_val = try ics.caller().resolveLazyValue(arg_val);
|
||||
should_memoize.* = should_memoize.* and !resolved_arg_val.canMutateComptimeVarState(mod);
|
||||
memoized_arg_values[arg_i.*] = try resolved_arg_val.intern(Type.fromInterned(param_ty), mod);
|
||||
memoized_arg_values[arg_i.*] = resolved_arg_val.toIntern();
|
||||
} else {
|
||||
ics.callee().inst_map.putAssumeCapacityNoClobber(inst, casted_arg);
|
||||
}
|
||||
@@ -8081,7 +8080,7 @@ fn analyzeInlineCallArg(
|
||||
// when the hash function is called.
|
||||
const resolved_arg_val = try ics.caller().resolveLazyValue(arg_val);
|
||||
should_memoize.* = should_memoize.* and !resolved_arg_val.canMutateComptimeVarState(mod);
|
||||
memoized_arg_values[arg_i.*] = try resolved_arg_val.intern(ics.caller().typeOf(uncasted_arg), mod);
|
||||
memoized_arg_values[arg_i.*] = resolved_arg_val.toIntern();
|
||||
} else {
|
||||
if (zir_tags[@intFromEnum(inst)] == .param_anytype_comptime) {
|
||||
_ = try ics.caller().resolveConstValue(arg_block, arg_src, uncasted_arg, .{
|
||||
@@ -14270,7 +14269,7 @@ fn zirBitNot(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
|
||||
const elems = try sema.arena.alloc(InternPool.Index, vec_len);
|
||||
for (elems, 0..) |*elem, i| {
|
||||
const elem_val = try val.elemValue(mod, i);
|
||||
elem.* = try (try elem_val.bitwiseNot(scalar_type, sema.arena, mod)).intern(scalar_type, mod);
|
||||
elem.* = (try elem_val.bitwiseNot(scalar_type, sema.arena, mod)).toIntern();
|
||||
}
|
||||
return Air.internedToRef((try mod.intern(.{ .aggregate = .{
|
||||
.ty = operand_type.toIntern(),
|
||||
@@ -14521,7 +14520,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
|
||||
} };
|
||||
const coerced_elem_val_inst = try sema.coerce(block, resolved_elem_ty, elem_val_inst, operand_src);
|
||||
const coerced_elem_val = try sema.resolveConstValue(block, operand_src, coerced_elem_val_inst, undefined);
|
||||
element_vals[elem_i] = try coerced_elem_val.intern(resolved_elem_ty, mod);
|
||||
element_vals[elem_i] = coerced_elem_val.toIntern();
|
||||
}
|
||||
while (elem_i < result_len) : (elem_i += 1) {
|
||||
const rhs_elem_i = elem_i - lhs_len;
|
||||
@@ -14534,7 +14533,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
|
||||
} };
|
||||
const coerced_elem_val_inst = try sema.coerce(block, resolved_elem_ty, elem_val_inst, operand_src);
|
||||
const coerced_elem_val = try sema.resolveConstValue(block, operand_src, coerced_elem_val_inst, undefined);
|
||||
element_vals[elem_i] = try coerced_elem_val.intern(resolved_elem_ty, mod);
|
||||
element_vals[elem_i] = coerced_elem_val.toIntern();
|
||||
}
|
||||
return sema.addConstantMaybeRef(try mod.intern(.{ .aggregate = .{
|
||||
.ty = result_ty.toIntern(),
|
||||
@@ -15813,7 +15812,7 @@ fn intRem(
|
||||
for (result_data, 0..) |*scalar, i| {
|
||||
const lhs_elem = try lhs.elemValue(mod, i);
|
||||
const rhs_elem = try rhs.elemValue(mod, i);
|
||||
scalar.* = try (try sema.intRemScalar(lhs_elem, rhs_elem, scalar_ty)).intern(scalar_ty, mod);
|
||||
scalar.* = (try sema.intRemScalar(lhs_elem, rhs_elem, scalar_ty)).toIntern();
|
||||
}
|
||||
return Value.fromInterned((try mod.intern(.{ .aggregate = .{
|
||||
.ty = ty.toIntern(),
|
||||
@@ -17753,7 +17752,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
|
||||
const info = ty.intInfo(mod);
|
||||
const field_values = .{
|
||||
// signedness: Signedness,
|
||||
try (try mod.enumValueFieldIndex(signedness_ty, @intFromEnum(info.signedness))).intern(signedness_ty, mod),
|
||||
(try mod.enumValueFieldIndex(signedness_ty, @intFromEnum(info.signedness))).toIntern(),
|
||||
// bits: u16,
|
||||
(try mod.intValue(Type.u16, info.bits)).toIntern(),
|
||||
};
|
||||
@@ -17823,7 +17822,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
|
||||
|
||||
const field_values = .{
|
||||
// size: Size,
|
||||
try (try mod.enumValueFieldIndex(ptr_size_ty, @intFromEnum(info.flags.size))).intern(ptr_size_ty, mod),
|
||||
(try mod.enumValueFieldIndex(ptr_size_ty, @intFromEnum(info.flags.size))).toIntern(),
|
||||
// is_const: bool,
|
||||
Value.makeBool(info.flags.is_const).toIntern(),
|
||||
// is_volatile: bool,
|
||||
@@ -17831,7 +17830,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
|
||||
// alignment: comptime_int,
|
||||
alignment.toIntern(),
|
||||
// address_space: AddressSpace
|
||||
try (try mod.enumValueFieldIndex(addrspace_ty, @intFromEnum(info.flags.address_space))).intern(addrspace_ty, mod),
|
||||
(try mod.enumValueFieldIndex(addrspace_ty, @intFromEnum(info.flags.address_space))).toIntern(),
|
||||
// child: type,
|
||||
info.child,
|
||||
// is_allowzero: bool,
|
||||
@@ -19975,8 +19974,8 @@ fn unionInit(
|
||||
const tag_val = try mod.enumValueFieldIndex(tag_ty, field_index);
|
||||
return Air.internedToRef((try mod.intern(.{ .un = .{
|
||||
.ty = union_ty.toIntern(),
|
||||
.tag = try tag_val.intern(tag_ty, mod),
|
||||
.val = try init_val.intern(field_ty, mod),
|
||||
.tag = tag_val.toIntern(),
|
||||
.val = init_val.toIntern(),
|
||||
} })));
|
||||
}
|
||||
|
||||
@@ -20099,8 +20098,8 @@ fn zirStructInit(
|
||||
if (try sema.resolveValue(init_inst)) |val| {
|
||||
const struct_val = Value.fromInterned((try mod.intern(.{ .un = .{
|
||||
.ty = resolved_ty.toIntern(),
|
||||
.tag = try tag_val.intern(tag_ty, mod),
|
||||
.val = try val.intern(field_ty, mod),
|
||||
.tag = tag_val.toIntern(),
|
||||
.val = val.toIntern(),
|
||||
} })));
|
||||
const final_val_inst = try sema.coerce(block, result_ty, Air.internedToRef(struct_val.toIntern()), src);
|
||||
const final_val = (try sema.resolveValue(final_val_inst)).?;
|
||||
@@ -20400,7 +20399,7 @@ fn structInitAnon(
|
||||
return sema.failWithOwnedErrorMsg(block, msg);
|
||||
}
|
||||
if (try sema.resolveValue(init)) |init_val| {
|
||||
field_val.* = try init_val.intern(Type.fromInterned(field_ty.*), mod);
|
||||
field_val.* = init_val.toIntern();
|
||||
} else {
|
||||
field_val.* = .none;
|
||||
runtime_index = @intCast(i_usize);
|
||||
@@ -20577,13 +20576,9 @@ fn zirArrayInit(
|
||||
|
||||
const runtime_index = opt_runtime_index orelse {
|
||||
const elem_vals = try sema.arena.alloc(InternPool.Index, resolved_args.len);
|
||||
for (elem_vals, resolved_args, 0..) |*val, arg, i| {
|
||||
const elem_ty = if (is_tuple)
|
||||
array_ty.structFieldType(i, mod)
|
||||
else
|
||||
array_ty.elemType2(mod);
|
||||
for (elem_vals, resolved_args) |*val, arg| {
|
||||
// We checked that all args are comptime above.
|
||||
val.* = try ((sema.resolveValue(arg) catch unreachable).?).intern(elem_ty, mod);
|
||||
val.* = (sema.resolveValue(arg) catch unreachable).?.toIntern();
|
||||
}
|
||||
const arr_val = try mod.intern(.{ .aggregate = .{
|
||||
.ty = array_ty.toIntern(),
|
||||
@@ -20998,7 +20993,7 @@ fn maybeConstantUnaryMath(
|
||||
const elems = try sema.arena.alloc(InternPool.Index, vec_len);
|
||||
for (elems, 0..) |*elem, i| {
|
||||
const elem_val = try val.elemValue(sema.mod, i);
|
||||
elem.* = try (try eval(elem_val, scalar_ty, sema.arena, sema.mod)).intern(scalar_ty, mod);
|
||||
elem.* = (try eval(elem_val, scalar_ty, sema.arena, sema.mod)).toIntern();
|
||||
}
|
||||
return Air.internedToRef((try mod.intern(.{ .aggregate = .{
|
||||
.ty = result_ty.toIntern(),
|
||||
@@ -23216,7 +23211,8 @@ fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
|
||||
const elems = try sema.arena.alloc(InternPool.Index, operand_ty.vectorLen(mod));
|
||||
for (elems, 0..) |*elem, i| {
|
||||
const elem_val = try val.elemValue(mod, i);
|
||||
elem.* = try (try elem_val.intTrunc(operand_scalar_ty, sema.arena, dest_info.signedness, dest_info.bits, mod)).intern(dest_scalar_ty, mod);
|
||||
const uncoerced_elem = try elem_val.intTrunc(operand_scalar_ty, sema.arena, dest_info.signedness, dest_info.bits, mod);
|
||||
elem.* = (try mod.getCoerced(uncoerced_elem, dest_scalar_ty)).toIntern();
|
||||
}
|
||||
return Air.internedToRef((try mod.intern(.{ .aggregate = .{
|
||||
.ty = dest_ty.toIntern(),
|
||||
@@ -23330,7 +23326,7 @@ fn zirByteSwap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
|
||||
const elems = try sema.arena.alloc(InternPool.Index, vec_len);
|
||||
for (elems, 0..) |*elem, i| {
|
||||
const elem_val = try val.elemValue(mod, i);
|
||||
elem.* = try (try elem_val.byteSwap(scalar_ty, mod, sema.arena)).intern(scalar_ty, mod);
|
||||
elem.* = (try elem_val.byteSwap(scalar_ty, mod, sema.arena)).toIntern();
|
||||
}
|
||||
return Air.internedToRef((try mod.intern(.{ .aggregate = .{
|
||||
.ty = operand_ty.toIntern(),
|
||||
@@ -23378,7 +23374,7 @@ fn zirBitReverse(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
|
||||
const elems = try sema.arena.alloc(InternPool.Index, vec_len);
|
||||
for (elems, 0..) |*elem, i| {
|
||||
const elem_val = try val.elemValue(mod, i);
|
||||
elem.* = try (try elem_val.bitReverse(scalar_ty, mod, sema.arena)).intern(scalar_ty, mod);
|
||||
elem.* = (try elem_val.bitReverse(scalar_ty, mod, sema.arena)).toIntern();
|
||||
}
|
||||
return Air.internedToRef((try mod.intern(.{ .aggregate = .{
|
||||
.ty = operand_ty.toIntern(),
|
||||
@@ -24311,7 +24307,7 @@ fn analyzeShuffle(
|
||||
}
|
||||
const int = mask_elem_val.toSignedInt(mod);
|
||||
const unsigned: u32 = @intCast(if (int >= 0) int else ~int);
|
||||
values[i] = try (try (if (int >= 0) a_val else b_val).elemValue(mod, unsigned)).intern(elem_ty, mod);
|
||||
values[i] = (try (if (int >= 0) a_val else b_val).elemValue(mod, unsigned)).toIntern();
|
||||
}
|
||||
return Air.internedToRef((try mod.intern(.{ .aggregate = .{
|
||||
.ty = res_ty.toIntern(),
|
||||
@@ -24417,7 +24413,7 @@ fn zirSelect(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) C
|
||||
for (elems, 0..) |*elem, i| {
|
||||
const pred_elem_val = try pred_val.elemValue(mod, i);
|
||||
const should_choose_a = pred_elem_val.toBool();
|
||||
elem.* = try (try (if (should_choose_a) a_val else b_val).elemValue(mod, i)).intern(elem_ty, mod);
|
||||
elem.* = (try (if (should_choose_a) a_val else b_val).elemValue(mod, i)).toIntern();
|
||||
}
|
||||
|
||||
return Air.internedToRef((try mod.intern(.{ .aggregate = .{
|
||||
@@ -27789,7 +27785,7 @@ fn structFieldPtrByIndex(
|
||||
const val = try mod.intern(.{ .ptr = .{
|
||||
.ty = ptr_field_ty.toIntern(),
|
||||
.addr = .{ .field = .{
|
||||
.base = try struct_ptr_val.intern(struct_ptr_ty, mod),
|
||||
.base = struct_ptr_val.toIntern(),
|
||||
.index = field_index,
|
||||
} },
|
||||
} });
|
||||
@@ -31611,7 +31607,7 @@ fn coerceCompatiblePtrs(
|
||||
}
|
||||
// The comptime Value representation is compatible with both types.
|
||||
return Air.internedToRef(
|
||||
(try mod.getCoerced(Value.fromInterned((try val.intern(inst_ty, mod))), dest_ty)).toIntern(),
|
||||
(try mod.getCoerced(val, dest_ty)).toIntern(),
|
||||
);
|
||||
}
|
||||
try sema.requireRuntimeBlock(block, inst_src, null);
|
||||
@@ -31948,7 +31944,7 @@ fn coerceArrayLike(
|
||||
ref.* = coerced;
|
||||
if (runtime_src == null) {
|
||||
if (try sema.resolveValue(coerced)) |elem_val| {
|
||||
val.* = try elem_val.intern(dest_elem_ty, mod);
|
||||
val.* = elem_val.toIntern();
|
||||
} else {
|
||||
runtime_src = elem_src;
|
||||
}
|
||||
@@ -32013,7 +32009,7 @@ fn coerceTupleToArray(
|
||||
ref.* = coerced;
|
||||
if (runtime_src == null) {
|
||||
if (try sema.resolveValue(coerced)) |elem_val| {
|
||||
val.* = try elem_val.intern(dest_elem_ty, mod);
|
||||
val.* = elem_val.toIntern();
|
||||
} else {
|
||||
runtime_src = elem_src;
|
||||
}
|
||||
@@ -33250,10 +33246,7 @@ fn analyzeSlice(
|
||||
};
|
||||
|
||||
if (!new_ptr_val.isUndef(mod)) {
|
||||
return Air.internedToRef((try mod.getCoerced(
|
||||
Value.fromInterned((try new_ptr_val.intern(new_ptr_ty, mod))),
|
||||
return_ty,
|
||||
)).toIntern());
|
||||
return Air.internedToRef((try mod.getCoerced(new_ptr_val, return_ty)).toIntern());
|
||||
}
|
||||
|
||||
// Special case: @as([]i32, undefined)[x..x]
|
||||
@@ -33765,7 +33758,7 @@ fn wrapErrorUnionPayload(
|
||||
if (try sema.resolveValue(coerced)) |val| {
|
||||
return Air.internedToRef((try mod.intern(.{ .error_union = .{
|
||||
.ty = dest_ty.toIntern(),
|
||||
.val = .{ .payload = try val.intern(dest_payload_ty, mod) },
|
||||
.val = .{ .payload = val.toIntern() },
|
||||
} })));
|
||||
}
|
||||
try sema.requireRuntimeBlock(block, inst_src, null);
|
||||
@@ -36941,15 +36934,14 @@ fn semaStructFieldInits(
|
||||
});
|
||||
};
|
||||
|
||||
const field_init = try default_val.intern(field_ty, mod);
|
||||
if (Value.fromInterned(field_init).canMutateComptimeVarState(mod)) {
|
||||
if (Value.fromInterned(default_val.toIntern()).canMutateComptimeVarState(mod)) {
|
||||
const init_src = mod.fieldSrcLoc(decl_index, .{
|
||||
.index = field_i,
|
||||
.range = .value,
|
||||
}).lazy;
|
||||
return sema.fail(&block_scope, init_src, "field default value contains reference to comptime-mutable memory", .{});
|
||||
}
|
||||
struct_type.field_inits.get(ip)[field_i] = field_init;
|
||||
struct_type.field_inits.get(ip)[field_i] = default_val.toIntern();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -37756,7 +37748,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
|
||||
return sema.failWithOwnedErrorMsg(null, msg);
|
||||
}
|
||||
if (try sema.typeHasOnePossibleValue(field_ty)) |field_opv| {
|
||||
field_val.* = try field_opv.intern(field_ty, mod);
|
||||
field_val.* = field_opv.toIntern();
|
||||
} else return null;
|
||||
}
|
||||
|
||||
@@ -38310,7 +38302,7 @@ fn intAddInner(sema: *Sema, lhs: Value, rhs: Value, ty: Type, overflow_idx: *usi
|
||||
},
|
||||
else => |e| return e,
|
||||
};
|
||||
scalar.* = try val.intern(scalar_ty, mod);
|
||||
scalar.* = val.toIntern();
|
||||
}
|
||||
return Value.fromInterned((try mod.intern(.{ .aggregate = .{
|
||||
.ty = ty.toIntern(),
|
||||
@@ -38400,7 +38392,7 @@ fn intSubInner(sema: *Sema, lhs: Value, rhs: Value, ty: Type, overflow_idx: *usi
|
||||
},
|
||||
else => |e| return e,
|
||||
};
|
||||
scalar.* = try val.intern(scalar_ty, mod);
|
||||
scalar.* = val.toIntern();
|
||||
}
|
||||
return Value.fromInterned((try mod.intern(.{ .aggregate = .{
|
||||
.ty = ty.toIntern(),
|
||||
@@ -38470,8 +38462,8 @@ fn intSubWithOverflow(
|
||||
const lhs_elem = try lhs.elemValue(sema.mod, i);
|
||||
const rhs_elem = try rhs.elemValue(sema.mod, i);
|
||||
const of_math_result = try sema.intSubWithOverflowScalar(lhs_elem, rhs_elem, scalar_ty);
|
||||
of.* = try of_math_result.overflow_bit.intern(Type.u1, mod);
|
||||
scalar.* = try of_math_result.wrapped_result.intern(scalar_ty, mod);
|
||||
of.* = of_math_result.overflow_bit.toIntern();
|
||||
scalar.* = of_math_result.wrapped_result.toIntern();
|
||||
}
|
||||
return Value.OverflowArithmeticResult{
|
||||
.overflow_bit = Value.fromInterned((try mod.intern(.{ .aggregate = .{
|
||||
@@ -38528,10 +38520,9 @@ fn intFromFloat(
|
||||
if (float_ty.zigTypeTag(mod) == .Vector) {
|
||||
const elem_ty = float_ty.scalarType(mod);
|
||||
const result_data = try sema.arena.alloc(InternPool.Index, float_ty.vectorLen(mod));
|
||||
const scalar_ty = int_ty.scalarType(mod);
|
||||
for (result_data, 0..) |*scalar, i| {
|
||||
const elem_val = try val.elemValue(sema.mod, i);
|
||||
scalar.* = try (try sema.intFromFloatScalar(block, src, elem_val, elem_ty, int_ty.scalarType(mod), mode)).intern(scalar_ty, mod);
|
||||
scalar.* = (try sema.intFromFloatScalar(block, src, elem_val, elem_ty, int_ty.scalarType(mod), mode)).toIntern();
|
||||
}
|
||||
return Value.fromInterned((try mod.intern(.{ .aggregate = .{
|
||||
.ty = int_ty.toIntern(),
|
||||
@@ -38724,8 +38715,8 @@ fn intAddWithOverflow(
|
||||
const lhs_elem = try lhs.elemValue(sema.mod, i);
|
||||
const rhs_elem = try rhs.elemValue(sema.mod, i);
|
||||
const of_math_result = try sema.intAddWithOverflowScalar(lhs_elem, rhs_elem, scalar_ty);
|
||||
of.* = try of_math_result.overflow_bit.intern(Type.u1, mod);
|
||||
scalar.* = try of_math_result.wrapped_result.intern(scalar_ty, mod);
|
||||
of.* = of_math_result.overflow_bit.toIntern();
|
||||
scalar.* = of_math_result.wrapped_result.toIntern();
|
||||
}
|
||||
return Value.OverflowArithmeticResult{
|
||||
.overflow_bit = Value.fromInterned((try mod.intern(.{ .aggregate = .{
|
||||
@@ -38835,7 +38826,7 @@ fn compareVector(
|
||||
const lhs_elem = try lhs.elemValue(sema.mod, i);
|
||||
const rhs_elem = try rhs.elemValue(sema.mod, i);
|
||||
const res_bool = try sema.compareScalar(lhs_elem, op, rhs_elem, ty.scalarType(mod));
|
||||
scalar.* = try Value.makeBool(res_bool).intern(Type.bool, mod);
|
||||
scalar.* = Value.makeBool(res_bool).toIntern();
|
||||
}
|
||||
return Value.fromInterned((try mod.intern(.{ .aggregate = .{
|
||||
.ty = (try mod.vectorType(.{ .len = ty.vectorLen(mod), .child = .bool_type })).toIntern(),
|
||||
@@ -39014,29 +39005,6 @@ fn validateRuntimeValue(sema: *Sema, block: *Block, val_src: LazySrcLoc, val: Ai
|
||||
/// Returns true if any value contained in `val` is undefined.
|
||||
fn anyUndef(sema: *Sema, val: Value) !bool {
|
||||
const mod = sema.mod;
|
||||
if (val.ip_index == .none) return switch (val.tag()) {
|
||||
.eu_payload => try sema.anyUndef(val.castTag(.eu_payload).?.data),
|
||||
.opt_payload => try sema.anyUndef(val.castTag(.opt_payload).?.data),
|
||||
.repeated => try sema.anyUndef(val.castTag(.repeated).?.data),
|
||||
.slice => {
|
||||
const slice = val.castTag(.slice).?.data;
|
||||
for (0..@intCast(slice.len.toUnsignedInt(mod))) |idx| {
|
||||
if (try sema.anyUndef((try slice.ptr.maybeElemValueFull(sema, mod, idx)).?)) return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
.bytes => false,
|
||||
.aggregate => for (val.castTag(.aggregate).?.data) |elem| {
|
||||
if (try sema.anyUndef(elem)) break true;
|
||||
} else false,
|
||||
.@"union" => {
|
||||
const un = val.castTag(.@"union").?.data;
|
||||
if (un.tag) |t| {
|
||||
if (try sema.anyUndef(t)) return true;
|
||||
}
|
||||
return sema.anyUndef(un.val);
|
||||
},
|
||||
};
|
||||
return switch (val.toIntern()) {
|
||||
.undef => true,
|
||||
else => switch (mod.intern_pool.indexToKey(val.toIntern())) {
|
||||
|
||||
@@ -77,386 +77,275 @@ pub fn print(
|
||||
var val = tv.val;
|
||||
var ty = tv.ty;
|
||||
const ip = &mod.intern_pool;
|
||||
while (true) switch (val.ip_index) {
|
||||
.none => switch (val.tag()) {
|
||||
.aggregate => return printAggregate(ty, val, writer, level, mod),
|
||||
.@"union" => {
|
||||
if (level == 0) {
|
||||
return writer.writeAll(".{ ... }");
|
||||
while (true) switch (ip.indexToKey(val.toIntern())) {
|
||||
.int_type,
|
||||
.ptr_type,
|
||||
.array_type,
|
||||
.vector_type,
|
||||
.opt_type,
|
||||
.anyframe_type,
|
||||
.error_union_type,
|
||||
.simple_type,
|
||||
.struct_type,
|
||||
.anon_struct_type,
|
||||
.union_type,
|
||||
.opaque_type,
|
||||
.enum_type,
|
||||
.func_type,
|
||||
.error_set_type,
|
||||
.inferred_error_set_type,
|
||||
=> return Type.print(val.toType(), writer, mod),
|
||||
.undef => return writer.writeAll("undefined"),
|
||||
.simple_value => |simple_value| switch (simple_value) {
|
||||
.void => return writer.writeAll("{}"),
|
||||
.empty_struct => return printAggregate(ty, val, writer, level, mod),
|
||||
.generic_poison => return writer.writeAll("(generic poison)"),
|
||||
else => return writer.writeAll(@tagName(simple_value)),
|
||||
},
|
||||
.variable => return writer.writeAll("(variable)"),
|
||||
.extern_func => |extern_func| return writer.print("(extern function '{}')", .{
|
||||
mod.declPtr(extern_func.decl).name.fmt(ip),
|
||||
}),
|
||||
.func => |func| return writer.print("(function '{}')", .{
|
||||
mod.declPtr(func.owner_decl).name.fmt(ip),
|
||||
}),
|
||||
.int => |int| switch (int.storage) {
|
||||
inline .u64, .i64, .big_int => |x| return writer.print("{}", .{x}),
|
||||
.lazy_align => |lazy_ty| return writer.print("{d}", .{
|
||||
Type.fromInterned(lazy_ty).abiAlignment(mod),
|
||||
}),
|
||||
.lazy_size => |lazy_ty| return writer.print("{d}", .{
|
||||
Type.fromInterned(lazy_ty).abiSize(mod),
|
||||
}),
|
||||
},
|
||||
.err => |err| return writer.print("error.{}", .{
|
||||
err.name.fmt(ip),
|
||||
}),
|
||||
.error_union => |error_union| switch (error_union.val) {
|
||||
.err_name => |err_name| return writer.print("error.{}", .{
|
||||
err_name.fmt(ip),
|
||||
}),
|
||||
.payload => |payload| {
|
||||
val = Value.fromInterned(payload);
|
||||
ty = ty.errorUnionPayload(mod);
|
||||
},
|
||||
},
|
||||
.enum_literal => |enum_literal| return writer.print(".{}", .{
|
||||
enum_literal.fmt(ip),
|
||||
}),
|
||||
.enum_tag => |enum_tag| {
|
||||
if (level == 0) {
|
||||
return writer.writeAll("(enum)");
|
||||
}
|
||||
const enum_type = ip.loadEnumType(ty.toIntern());
|
||||
if (enum_type.tagValueIndex(ip, val.toIntern())) |tag_index| {
|
||||
try writer.print(".{i}", .{enum_type.names.get(ip)[tag_index].fmt(ip)});
|
||||
return;
|
||||
}
|
||||
try writer.writeAll("@enumFromInt(");
|
||||
try print(.{
|
||||
.ty = Type.fromInterned(ip.typeOf(enum_tag.int)),
|
||||
.val = Value.fromInterned(enum_tag.int),
|
||||
}, writer, level - 1, mod);
|
||||
try writer.writeAll(")");
|
||||
return;
|
||||
},
|
||||
.empty_enum_value => return writer.writeAll("(empty enum value)"),
|
||||
.float => |float| switch (float.storage) {
|
||||
inline else => |x| return writer.print("{d}", .{@as(f64, @floatCast(x))}),
|
||||
},
|
||||
.slice => |slice| {
|
||||
const ptr_ty = switch (ip.indexToKey(slice.ptr)) {
|
||||
.ptr => |ptr| ty: {
|
||||
if (ptr.addr == .int) return print(.{
|
||||
.ty = Type.fromInterned(ptr.ty),
|
||||
.val = Value.fromInterned(slice.ptr),
|
||||
}, writer, level - 1, mod);
|
||||
break :ty ip.indexToKey(ptr.ty).ptr_type;
|
||||
},
|
||||
.undef => |ptr_ty| ip.indexToKey(ptr_ty).ptr_type,
|
||||
else => unreachable,
|
||||
};
|
||||
if (level == 0) {
|
||||
return writer.writeAll(".{ ... }");
|
||||
}
|
||||
const elem_ty = Type.fromInterned(ptr_ty.child);
|
||||
const len = Value.fromInterned(slice.len).toUnsignedInt(mod);
|
||||
if (elem_ty.eql(Type.u8, mod)) str: {
|
||||
const max_len = @min(len, max_string_len);
|
||||
var buf: [max_string_len]u8 = undefined;
|
||||
for (buf[0..max_len], 0..) |*c, i| {
|
||||
const maybe_elem = try val.maybeElemValue(mod, i);
|
||||
const elem = maybe_elem orelse return writer.writeAll(".{ (reinterpreted data) }");
|
||||
if (elem.isUndef(mod)) break :str;
|
||||
c.* = @as(u8, @intCast(elem.toUnsignedInt(mod)));
|
||||
}
|
||||
const payload = val.castTag(.@"union").?.data;
|
||||
try writer.writeAll(".{ ");
|
||||
|
||||
if (payload.tag) |tag| {
|
||||
const truncated = if (len > max_string_len) " (truncated)" else "";
|
||||
return writer.print("\"{}{s}\"", .{ std.zig.fmtEscapes(buf[0..max_len]), truncated });
|
||||
}
|
||||
try writer.writeAll(".{ ");
|
||||
const max_len = @min(len, max_aggregate_items);
|
||||
for (0..max_len) |i| {
|
||||
if (i != 0) try writer.writeAll(", ");
|
||||
const maybe_elem = try val.maybeElemValue(mod, i);
|
||||
const elem = maybe_elem orelse return writer.writeAll("(reinterpreted data) }");
|
||||
try print(.{
|
||||
.ty = elem_ty,
|
||||
.val = elem,
|
||||
}, writer, level - 1, mod);
|
||||
}
|
||||
if (len > max_aggregate_items) {
|
||||
try writer.writeAll(", ...");
|
||||
}
|
||||
return writer.writeAll(" }");
|
||||
},
|
||||
.ptr => |ptr| {
|
||||
switch (ptr.addr) {
|
||||
.decl => |decl_index| {
|
||||
const decl = mod.declPtr(decl_index);
|
||||
if (level == 0) return writer.print("(decl '{}')", .{decl.name.fmt(ip)});
|
||||
return print(.{
|
||||
.ty = decl.typeOf(mod),
|
||||
.val = decl.val,
|
||||
}, writer, level - 1, mod);
|
||||
},
|
||||
.anon_decl => |anon_decl| {
|
||||
const decl_val = anon_decl.val;
|
||||
if (level == 0) return writer.print("(anon decl '{d}')", .{
|
||||
@intFromEnum(decl_val),
|
||||
});
|
||||
return print(.{
|
||||
.ty = Type.fromInterned(ip.typeOf(decl_val)),
|
||||
.val = Value.fromInterned(decl_val),
|
||||
}, writer, level - 1, mod);
|
||||
},
|
||||
.comptime_alloc => {
|
||||
// TODO: we need a Sema to print this!
|
||||
return writer.writeAll("(comptime alloc)");
|
||||
},
|
||||
.comptime_field => |field_val_ip| {
|
||||
return print(.{
|
||||
.ty = Type.fromInterned(ip.typeOf(field_val_ip)),
|
||||
.val = Value.fromInterned(field_val_ip),
|
||||
}, writer, level - 1, mod);
|
||||
},
|
||||
.int => |int_ip| {
|
||||
try writer.writeAll("@ptrFromInt(");
|
||||
try print(.{
|
||||
.ty = Type.fromInterned(ip.loadUnionType(ty.toIntern()).enum_tag_ty),
|
||||
.val = tag,
|
||||
.ty = Type.usize,
|
||||
.val = Value.fromInterned(int_ip),
|
||||
}, writer, level - 1, mod);
|
||||
try writer.writeByte(')');
|
||||
},
|
||||
.eu_payload => |eu_ip| {
|
||||
try writer.writeAll("(payload of ");
|
||||
try print(.{
|
||||
.ty = Type.fromInterned(ip.typeOf(eu_ip)),
|
||||
.val = Value.fromInterned(eu_ip),
|
||||
}, writer, level - 1, mod);
|
||||
try writer.writeAll(")");
|
||||
},
|
||||
.opt_payload => |opt_ip| {
|
||||
try print(.{
|
||||
.ty = Type.fromInterned(ip.typeOf(opt_ip)),
|
||||
.val = Value.fromInterned(opt_ip),
|
||||
}, writer, level - 1, mod);
|
||||
try writer.writeAll(".?");
|
||||
},
|
||||
.elem => |elem| {
|
||||
if (level == 0) {
|
||||
try writer.writeAll("(...)");
|
||||
} else {
|
||||
try print(.{
|
||||
.ty = Type.fromInterned(ip.typeOf(elem.base)),
|
||||
.val = Value.fromInterned(elem.base),
|
||||
}, writer, level - 1, mod);
|
||||
}
|
||||
try writer.print("[{}]", .{elem.index});
|
||||
},
|
||||
.field => |field| {
|
||||
const ptr_container_ty = Type.fromInterned(ip.typeOf(field.base));
|
||||
if (level == 0) {
|
||||
try writer.writeAll("(...)");
|
||||
} else {
|
||||
try print(.{
|
||||
.ty = ptr_container_ty,
|
||||
.val = Value.fromInterned(field.base),
|
||||
}, writer, level - 1, mod);
|
||||
}
|
||||
|
||||
const container_ty = ptr_container_ty.childType(mod);
|
||||
switch (container_ty.zigTypeTag(mod)) {
|
||||
.Struct => {
|
||||
if (container_ty.structFieldName(@intCast(field.index), mod).unwrap()) |field_name| {
|
||||
try writer.print(".{i}", .{field_name.fmt(ip)});
|
||||
} else {
|
||||
try writer.print("[{d}]", .{field.index});
|
||||
}
|
||||
},
|
||||
.Union => {
|
||||
const field_name = mod.typeToUnion(container_ty).?.loadTagType(ip).names.get(ip)[@intCast(field.index)];
|
||||
try writer.print(".{i}", .{field_name.fmt(ip)});
|
||||
},
|
||||
.Pointer => {
|
||||
std.debug.assert(container_ty.isSlice(mod));
|
||||
try writer.writeAll(switch (field.index) {
|
||||
Value.slice_ptr_index => ".ptr",
|
||||
Value.slice_len_index => ".len",
|
||||
else => unreachable,
|
||||
});
|
||||
},
|
||||
else => unreachable,
|
||||
}
|
||||
},
|
||||
}
|
||||
return;
|
||||
},
|
||||
.opt => |opt| switch (opt.val) {
|
||||
.none => return writer.writeAll("null"),
|
||||
else => |payload| {
|
||||
val = Value.fromInterned(payload);
|
||||
ty = ty.optionalChild(mod);
|
||||
},
|
||||
},
|
||||
.aggregate => |aggregate| switch (aggregate.storage) {
|
||||
.bytes => |bytes| {
|
||||
// Strip the 0 sentinel off of strings before printing
|
||||
const zero_sent = blk: {
|
||||
const sent = ty.sentinel(mod) orelse break :blk false;
|
||||
break :blk sent.eql(Value.zero_u8, Type.u8, mod);
|
||||
};
|
||||
const str = if (zero_sent) bytes[0 .. bytes.len - 1] else bytes;
|
||||
return writer.print("\"{}\"", .{std.zig.fmtEscapes(str)});
|
||||
},
|
||||
.elems, .repeated_elem => return printAggregate(ty, val, writer, level, mod),
|
||||
},
|
||||
.un => |un| {
|
||||
try writer.writeAll(".{ ");
|
||||
if (level > 0) {
|
||||
if (un.tag != .none) {
|
||||
try print(.{
|
||||
.ty = ty.unionTagTypeHypothetical(mod),
|
||||
.val = Value.fromInterned(un.tag),
|
||||
}, writer, level - 1, mod);
|
||||
try writer.writeAll(" = ");
|
||||
const field_ty = ty.unionFieldType(tag, mod).?;
|
||||
const field_ty = ty.unionFieldType(Value.fromInterned(un.tag), mod).?;
|
||||
try print(.{
|
||||
.ty = field_ty,
|
||||
.val = payload.val,
|
||||
.val = Value.fromInterned(un.val),
|
||||
}, writer, level - 1, mod);
|
||||
} else {
|
||||
try writer.writeAll("(unknown tag) = ");
|
||||
const backing_ty = try ty.unionBackingType(mod);
|
||||
try print(.{
|
||||
.ty = backing_ty,
|
||||
.val = payload.val,
|
||||
.val = Value.fromInterned(un.val),
|
||||
}, writer, level - 1, mod);
|
||||
}
|
||||
|
||||
return writer.writeAll(" }");
|
||||
},
|
||||
.bytes => return writer.print("\"{}\"", .{std.zig.fmtEscapes(val.castTag(.bytes).?.data)}),
|
||||
.repeated => {
|
||||
if (level == 0) {
|
||||
return writer.writeAll(".{ ... }");
|
||||
}
|
||||
var i: u32 = 0;
|
||||
try writer.writeAll(".{ ");
|
||||
const elem_tv = TypedValue{
|
||||
.ty = ty.elemType2(mod),
|
||||
.val = val.castTag(.repeated).?.data,
|
||||
};
|
||||
const len = ty.arrayLen(mod);
|
||||
const max_len = @min(len, max_aggregate_items);
|
||||
while (i < max_len) : (i += 1) {
|
||||
if (i != 0) try writer.writeAll(", ");
|
||||
try print(elem_tv, writer, level - 1, mod);
|
||||
}
|
||||
if (len > max_aggregate_items) {
|
||||
try writer.writeAll(", ...");
|
||||
}
|
||||
return writer.writeAll(" }");
|
||||
},
|
||||
.slice => {
|
||||
if (level == 0) {
|
||||
return writer.writeAll(".{ ... }");
|
||||
}
|
||||
const payload = val.castTag(.slice).?.data;
|
||||
const elem_ty = ty.elemType2(mod);
|
||||
const len = payload.len.toUnsignedInt(mod);
|
||||
|
||||
if (elem_ty.eql(Type.u8, mod)) str: {
|
||||
const max_len: usize = @min(len, max_string_len);
|
||||
var buf: [max_string_len]u8 = undefined;
|
||||
|
||||
var i: u32 = 0;
|
||||
while (i < max_len) : (i += 1) {
|
||||
const maybe_elem_val = payload.ptr.maybeElemValue(mod, i) catch |err| switch (err) {
|
||||
error.OutOfMemory => @panic("OOM"), // TODO: eliminate this panic
|
||||
};
|
||||
const elem_val = maybe_elem_val orelse return writer.writeAll(".{ (reinterpreted data) }");
|
||||
if (elem_val.isUndef(mod)) break :str;
|
||||
buf[i] = std.math.cast(u8, elem_val.toUnsignedInt(mod)) orelse break :str;
|
||||
}
|
||||
|
||||
// TODO would be nice if this had a bit of unicode awareness.
|
||||
const truncated = if (len > max_string_len) " (truncated)" else "";
|
||||
return writer.print("\"{}{s}\"", .{ std.zig.fmtEscapes(buf[0..max_len]), truncated });
|
||||
}
|
||||
|
||||
try writer.writeAll(".{ ");
|
||||
|
||||
const max_len = @min(len, max_aggregate_items);
|
||||
var i: u32 = 0;
|
||||
while (i < max_len) : (i += 1) {
|
||||
if (i != 0) try writer.writeAll(", ");
|
||||
const maybe_elem_val = payload.ptr.maybeElemValue(mod, i) catch |err| switch (err) {
|
||||
error.OutOfMemory => @panic("OOM"), // TODO: eliminate this panic
|
||||
};
|
||||
const elem_val = maybe_elem_val orelse return writer.writeAll("(reinterpreted data) }");
|
||||
try print(.{
|
||||
.ty = elem_ty,
|
||||
.val = elem_val,
|
||||
}, writer, level - 1, mod);
|
||||
}
|
||||
if (len > max_aggregate_items) {
|
||||
try writer.writeAll(", ...");
|
||||
}
|
||||
return writer.writeAll(" }");
|
||||
},
|
||||
.eu_payload => {
|
||||
val = val.castTag(.eu_payload).?.data;
|
||||
ty = ty.errorUnionPayload(mod);
|
||||
},
|
||||
.opt_payload => {
|
||||
val = val.castTag(.opt_payload).?.data;
|
||||
ty = ty.optionalChild(mod);
|
||||
},
|
||||
},
|
||||
else => switch (ip.indexToKey(val.toIntern())) {
|
||||
.int_type,
|
||||
.ptr_type,
|
||||
.array_type,
|
||||
.vector_type,
|
||||
.opt_type,
|
||||
.anyframe_type,
|
||||
.error_union_type,
|
||||
.simple_type,
|
||||
.struct_type,
|
||||
.anon_struct_type,
|
||||
.union_type,
|
||||
.opaque_type,
|
||||
.enum_type,
|
||||
.func_type,
|
||||
.error_set_type,
|
||||
.inferred_error_set_type,
|
||||
=> return Type.print(val.toType(), writer, mod),
|
||||
.undef => return writer.writeAll("undefined"),
|
||||
.simple_value => |simple_value| switch (simple_value) {
|
||||
.void => return writer.writeAll("{}"),
|
||||
.empty_struct => return printAggregate(ty, val, writer, level, mod),
|
||||
.generic_poison => return writer.writeAll("(generic poison)"),
|
||||
else => return writer.writeAll(@tagName(simple_value)),
|
||||
},
|
||||
.variable => return writer.writeAll("(variable)"),
|
||||
.extern_func => |extern_func| return writer.print("(extern function '{}')", .{
|
||||
mod.declPtr(extern_func.decl).name.fmt(ip),
|
||||
}),
|
||||
.func => |func| return writer.print("(function '{}')", .{
|
||||
mod.declPtr(func.owner_decl).name.fmt(ip),
|
||||
}),
|
||||
.int => |int| switch (int.storage) {
|
||||
inline .u64, .i64, .big_int => |x| return writer.print("{}", .{x}),
|
||||
.lazy_align => |lazy_ty| return writer.print("{d}", .{
|
||||
Type.fromInterned(lazy_ty).abiAlignment(mod),
|
||||
}),
|
||||
.lazy_size => |lazy_ty| return writer.print("{d}", .{
|
||||
Type.fromInterned(lazy_ty).abiSize(mod),
|
||||
}),
|
||||
},
|
||||
.err => |err| return writer.print("error.{}", .{
|
||||
err.name.fmt(ip),
|
||||
}),
|
||||
.error_union => |error_union| switch (error_union.val) {
|
||||
.err_name => |err_name| return writer.print("error.{}", .{
|
||||
err_name.fmt(ip),
|
||||
}),
|
||||
.payload => |payload| {
|
||||
val = Value.fromInterned(payload);
|
||||
ty = ty.errorUnionPayload(mod);
|
||||
},
|
||||
},
|
||||
.enum_literal => |enum_literal| return writer.print(".{}", .{
|
||||
enum_literal.fmt(ip),
|
||||
}),
|
||||
.enum_tag => |enum_tag| {
|
||||
if (level == 0) {
|
||||
return writer.writeAll("(enum)");
|
||||
}
|
||||
const enum_type = ip.loadEnumType(ty.toIntern());
|
||||
if (enum_type.tagValueIndex(ip, val.toIntern())) |tag_index| {
|
||||
try writer.print(".{i}", .{enum_type.names.get(ip)[tag_index].fmt(ip)});
|
||||
return;
|
||||
}
|
||||
try writer.writeAll("@enumFromInt(");
|
||||
try print(.{
|
||||
.ty = Type.fromInterned(ip.typeOf(enum_tag.int)),
|
||||
.val = Value.fromInterned(enum_tag.int),
|
||||
}, writer, level - 1, mod);
|
||||
try writer.writeAll(")");
|
||||
return;
|
||||
},
|
||||
.empty_enum_value => return writer.writeAll("(empty enum value)"),
|
||||
.float => |float| switch (float.storage) {
|
||||
inline else => |x| return writer.print("{d}", .{@as(f64, @floatCast(x))}),
|
||||
},
|
||||
.slice => |slice| {
|
||||
const ptr_ty = switch (ip.indexToKey(slice.ptr)) {
|
||||
.ptr => |ptr| ty: {
|
||||
if (ptr.addr == .int) return print(.{
|
||||
.ty = Type.fromInterned(ptr.ty),
|
||||
.val = Value.fromInterned(slice.ptr),
|
||||
}, writer, level - 1, mod);
|
||||
break :ty ip.indexToKey(ptr.ty).ptr_type;
|
||||
},
|
||||
.undef => |ptr_ty| ip.indexToKey(ptr_ty).ptr_type,
|
||||
else => unreachable,
|
||||
};
|
||||
if (level == 0) {
|
||||
return writer.writeAll(".{ ... }");
|
||||
}
|
||||
const elem_ty = Type.fromInterned(ptr_ty.child);
|
||||
const len = Value.fromInterned(slice.len).toUnsignedInt(mod);
|
||||
if (elem_ty.eql(Type.u8, mod)) str: {
|
||||
const max_len = @min(len, max_string_len);
|
||||
var buf: [max_string_len]u8 = undefined;
|
||||
for (buf[0..max_len], 0..) |*c, i| {
|
||||
const maybe_elem = try val.maybeElemValue(mod, i);
|
||||
const elem = maybe_elem orelse return writer.writeAll(".{ (reinterpreted data) }");
|
||||
if (elem.isUndef(mod)) break :str;
|
||||
c.* = @as(u8, @intCast(elem.toUnsignedInt(mod)));
|
||||
}
|
||||
const truncated = if (len > max_string_len) " (truncated)" else "";
|
||||
return writer.print("\"{}{s}\"", .{ std.zig.fmtEscapes(buf[0..max_len]), truncated });
|
||||
}
|
||||
try writer.writeAll(".{ ");
|
||||
const max_len = @min(len, max_aggregate_items);
|
||||
for (0..max_len) |i| {
|
||||
if (i != 0) try writer.writeAll(", ");
|
||||
const maybe_elem = try val.maybeElemValue(mod, i);
|
||||
const elem = maybe_elem orelse return writer.writeAll("(reinterpreted data) }");
|
||||
try print(.{
|
||||
.ty = elem_ty,
|
||||
.val = elem,
|
||||
}, writer, level - 1, mod);
|
||||
}
|
||||
if (len > max_aggregate_items) {
|
||||
try writer.writeAll(", ...");
|
||||
}
|
||||
return writer.writeAll(" }");
|
||||
},
|
||||
.ptr => |ptr| {
|
||||
switch (ptr.addr) {
|
||||
.decl => |decl_index| {
|
||||
const decl = mod.declPtr(decl_index);
|
||||
if (level == 0) return writer.print("(decl '{}')", .{decl.name.fmt(ip)});
|
||||
return print(.{
|
||||
.ty = decl.typeOf(mod),
|
||||
.val = decl.val,
|
||||
}, writer, level - 1, mod);
|
||||
},
|
||||
.anon_decl => |anon_decl| {
|
||||
const decl_val = anon_decl.val;
|
||||
if (level == 0) return writer.print("(anon decl '{d}')", .{
|
||||
@intFromEnum(decl_val),
|
||||
});
|
||||
return print(.{
|
||||
.ty = Type.fromInterned(ip.typeOf(decl_val)),
|
||||
.val = Value.fromInterned(decl_val),
|
||||
}, writer, level - 1, mod);
|
||||
},
|
||||
.comptime_alloc => {
|
||||
// TODO: we need a Sema to print this!
|
||||
return writer.writeAll("(comptime alloc)");
|
||||
},
|
||||
.comptime_field => |field_val_ip| {
|
||||
return print(.{
|
||||
.ty = Type.fromInterned(ip.typeOf(field_val_ip)),
|
||||
.val = Value.fromInterned(field_val_ip),
|
||||
}, writer, level - 1, mod);
|
||||
},
|
||||
.int => |int_ip| {
|
||||
try writer.writeAll("@ptrFromInt(");
|
||||
try print(.{
|
||||
.ty = Type.usize,
|
||||
.val = Value.fromInterned(int_ip),
|
||||
}, writer, level - 1, mod);
|
||||
try writer.writeByte(')');
|
||||
},
|
||||
.eu_payload => |eu_ip| {
|
||||
try writer.writeAll("(payload of ");
|
||||
try print(.{
|
||||
.ty = Type.fromInterned(ip.typeOf(eu_ip)),
|
||||
.val = Value.fromInterned(eu_ip),
|
||||
}, writer, level - 1, mod);
|
||||
try writer.writeAll(")");
|
||||
},
|
||||
.opt_payload => |opt_ip| {
|
||||
try print(.{
|
||||
.ty = Type.fromInterned(ip.typeOf(opt_ip)),
|
||||
.val = Value.fromInterned(opt_ip),
|
||||
}, writer, level - 1, mod);
|
||||
try writer.writeAll(".?");
|
||||
},
|
||||
.elem => |elem| {
|
||||
if (level == 0) {
|
||||
try writer.writeAll("(...)");
|
||||
} else {
|
||||
try print(.{
|
||||
.ty = Type.fromInterned(ip.typeOf(elem.base)),
|
||||
.val = Value.fromInterned(elem.base),
|
||||
}, writer, level - 1, mod);
|
||||
}
|
||||
try writer.print("[{}]", .{elem.index});
|
||||
},
|
||||
.field => |field| {
|
||||
const ptr_container_ty = Type.fromInterned(ip.typeOf(field.base));
|
||||
if (level == 0) {
|
||||
try writer.writeAll("(...)");
|
||||
} else {
|
||||
try print(.{
|
||||
.ty = ptr_container_ty,
|
||||
.val = Value.fromInterned(field.base),
|
||||
}, writer, level - 1, mod);
|
||||
}
|
||||
|
||||
const container_ty = ptr_container_ty.childType(mod);
|
||||
switch (container_ty.zigTypeTag(mod)) {
|
||||
.Struct => {
|
||||
if (container_ty.structFieldName(@intCast(field.index), mod).unwrap()) |field_name| {
|
||||
try writer.print(".{i}", .{field_name.fmt(ip)});
|
||||
} else {
|
||||
try writer.print("[{d}]", .{field.index});
|
||||
}
|
||||
},
|
||||
.Union => {
|
||||
const field_name = mod.typeToUnion(container_ty).?.loadTagType(ip).names.get(ip)[@intCast(field.index)];
|
||||
try writer.print(".{i}", .{field_name.fmt(ip)});
|
||||
},
|
||||
.Pointer => {
|
||||
std.debug.assert(container_ty.isSlice(mod));
|
||||
try writer.writeAll(switch (field.index) {
|
||||
Value.slice_ptr_index => ".ptr",
|
||||
Value.slice_len_index => ".len",
|
||||
else => unreachable,
|
||||
});
|
||||
},
|
||||
else => unreachable,
|
||||
}
|
||||
},
|
||||
}
|
||||
return;
|
||||
},
|
||||
.opt => |opt| switch (opt.val) {
|
||||
.none => return writer.writeAll("null"),
|
||||
else => |payload| {
|
||||
val = Value.fromInterned(payload);
|
||||
ty = ty.optionalChild(mod);
|
||||
},
|
||||
},
|
||||
.aggregate => |aggregate| switch (aggregate.storage) {
|
||||
.bytes => |bytes| {
|
||||
// Strip the 0 sentinel off of strings before printing
|
||||
const zero_sent = blk: {
|
||||
const sent = ty.sentinel(mod) orelse break :blk false;
|
||||
break :blk sent.eql(Value.zero_u8, Type.u8, mod);
|
||||
};
|
||||
const str = if (zero_sent) bytes[0 .. bytes.len - 1] else bytes;
|
||||
return writer.print("\"{}\"", .{std.zig.fmtEscapes(str)});
|
||||
},
|
||||
.elems, .repeated_elem => return printAggregate(ty, val, writer, level, mod),
|
||||
},
|
||||
.un => |un| {
|
||||
try writer.writeAll(".{ ");
|
||||
if (level > 0) {
|
||||
if (un.tag != .none) {
|
||||
try print(.{
|
||||
.ty = ty.unionTagTypeHypothetical(mod),
|
||||
.val = Value.fromInterned(un.tag),
|
||||
}, writer, level - 1, mod);
|
||||
try writer.writeAll(" = ");
|
||||
const field_ty = ty.unionFieldType(Value.fromInterned(un.tag), mod).?;
|
||||
try print(.{
|
||||
.ty = field_ty,
|
||||
.val = Value.fromInterned(un.val),
|
||||
}, writer, level - 1, mod);
|
||||
} else {
|
||||
try writer.writeAll("(unknown tag) = ");
|
||||
const backing_ty = try ty.unionBackingType(mod);
|
||||
try print(.{
|
||||
.ty = backing_ty,
|
||||
.val = Value.fromInterned(un.val),
|
||||
}, writer, level - 1, mod);
|
||||
}
|
||||
} else try writer.writeAll("...");
|
||||
return writer.writeAll(" }");
|
||||
},
|
||||
.memoized_call => unreachable,
|
||||
} else try writer.writeAll("...");
|
||||
return writer.writeAll(" }");
|
||||
},
|
||||
.memoized_call => unreachable,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
779
src/Value.zig
779
src/Value.zig
File diff suppressed because it is too large
Load Diff
@@ -2216,7 +2216,7 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
return func.fail("Expected a function, but instead found type '{}'", .{func_val.tag()});
|
||||
return func.fail("Expected a function, but instead found '{s}'", .{@tagName(ip.indexToKey(func_val.toIntern()))});
|
||||
};
|
||||
|
||||
const sret = if (first_param_sret) blk: {
|
||||
|
||||
@@ -12258,7 +12258,7 @@ fn genCall(self: *Self, info: union(enum) {
|
||||
switch (switch (func_key) {
|
||||
else => func_key,
|
||||
.ptr => |ptr| switch (ptr.addr) {
|
||||
.decl => |decl| mod.intern_pool.indexToKey(try mod.declPtr(decl).internValue(mod)),
|
||||
.decl => |decl| mod.intern_pool.indexToKey(mod.declPtr(decl).val.toIntern()),
|
||||
else => func_key,
|
||||
},
|
||||
}) {
|
||||
|
||||
@@ -925,7 +925,7 @@ fn genDeclRef(
|
||||
const ptr_bits = target.ptrBitWidth();
|
||||
const ptr_bytes: u64 = @divExact(ptr_bits, 8);
|
||||
|
||||
const decl_index = switch (zcu.intern_pool.indexToKey(try ptr_decl.internValue(zcu))) {
|
||||
const decl_index = switch (zcu.intern_pool.indexToKey(ptr_decl.val.toIntern())) {
|
||||
.func => |func| func.owner_decl,
|
||||
.extern_func => |extern_func| extern_func.decl,
|
||||
else => ptr_decl_index,
|
||||
|
||||
@@ -2657,7 +2657,7 @@ fn genExports(o: *Object) !void {
|
||||
.anon, .flush => return,
|
||||
};
|
||||
const decl = mod.declPtr(decl_index);
|
||||
const tv: TypedValue = .{ .ty = decl.typeOf(mod), .val = Value.fromInterned((try decl.internValue(mod))) };
|
||||
const tv: TypedValue = .{ .ty = decl.typeOf(mod), .val = decl.val };
|
||||
const fwd = o.dg.fwdDeclWriter();
|
||||
|
||||
const exports = mod.decl_exports.get(decl_index) orelse return;
|
||||
@@ -2894,7 +2894,7 @@ pub fn genDecl(o: *Object) !void {
|
||||
const mod = o.dg.module;
|
||||
const decl_index = o.dg.pass.decl;
|
||||
const decl = mod.declPtr(decl_index);
|
||||
const tv: TypedValue = .{ .ty = decl.typeOf(mod), .val = Value.fromInterned((try decl.internValue(mod))) };
|
||||
const tv: TypedValue = .{ .ty = decl.typeOf(mod), .val = decl.val };
|
||||
|
||||
if (!tv.ty.isFnOrHasRuntimeBitsIgnoreComptime(mod)) return;
|
||||
if (tv.val.getExternFunc(mod)) |_| {
|
||||
|
||||
@@ -5532,7 +5532,7 @@ pub const FuncGen = struct {
|
||||
const msg_decl_index = mod.panic_messages[@intFromEnum(panic_id)].unwrap().?;
|
||||
const msg_decl = mod.declPtr(msg_decl_index);
|
||||
const msg_len = msg_decl.typeOf(mod).childType(mod).arrayLen(mod);
|
||||
const msg_ptr = try o.lowerValue(try msg_decl.internValue(mod));
|
||||
const msg_ptr = try o.lowerValue(msg_decl.val.toIntern());
|
||||
const null_opt_addr_global = try fg.resolveNullOptUsize();
|
||||
const target = mod.getTarget();
|
||||
const llvm_usize = try o.lowerType(Type.usize);
|
||||
|
||||
@@ -2481,7 +2481,7 @@ pub const Type = struct {
|
||||
}
|
||||
const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]);
|
||||
if (try field_ty.onePossibleValue(mod)) |field_opv| {
|
||||
field_val.* = try field_opv.intern(field_ty, mod);
|
||||
field_val.* = field_opv.toIntern();
|
||||
} else return null;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user