InternPool: add getCoercedInt to avoid copy in Sema
This commit is contained in:
@@ -1535,6 +1535,26 @@ pub fn slicePtrType(ip: InternPool, i: Index) Index {
|
||||
}
|
||||
}
|
||||
|
||||
/// Given an existing integer value, returns the same numerical value but with
|
||||
/// the supplied type.
|
||||
pub fn getCoercedInt(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Allocator.Error!Index {
|
||||
const key = ip.indexToKey(val);
|
||||
// The key cannot be passed directly to `get`, otherwise in the case of
|
||||
// big_int storage, the limbs would be invalidated before they are read.
|
||||
// Here we pre-reserve the limbs to ensure that the logic in `addInt` will
|
||||
// not use an invalidated limbs pointer.
|
||||
switch (key.int.storage) {
|
||||
.u64, .i64 => {},
|
||||
.big_int => |big_int| {
|
||||
try reserveLimbs(ip, gpa, @typeInfo(Int).Struct.fields.len + big_int.limbs.len);
|
||||
},
|
||||
}
|
||||
return ip.get(gpa, .{ .int = .{
|
||||
.ty = new_ty,
|
||||
.storage = key.int.storage,
|
||||
} });
|
||||
}
|
||||
|
||||
pub fn dump(ip: InternPool) void {
|
||||
dumpFallible(ip, std.heap.page_allocator) catch return;
|
||||
}
|
||||
|
||||
15
src/Sema.zig
15
src/Sema.zig
@@ -25957,20 +25957,7 @@ fn coerceExtra(
|
||||
if (!opts.report_err) return error.NotCoercible;
|
||||
return sema.fail(block, inst_src, "type '{}' cannot represent integer value '{}'", .{ dest_ty.fmt(sema.mod), val.fmtValue(inst_ty, sema.mod) });
|
||||
}
|
||||
const key = mod.intern_pool.indexToKey(val.ip_index);
|
||||
// If the int is represented as a bigint, copy it so we can safely pass it to `mod.intern`
|
||||
const int_storage: InternPool.Key.Int.Storage = switch (key.int.storage) {
|
||||
.u64 => |x| .{ .u64 = x },
|
||||
.i64 => |x| .{ .i64 = x },
|
||||
.big_int => |big_int| .{ .big_int = .{
|
||||
.limbs = try sema.arena.dupe(std.math.big.Limb, big_int.limbs),
|
||||
.positive = big_int.positive,
|
||||
} },
|
||||
};
|
||||
const new_val = try mod.intern(.{ .int = .{
|
||||
.ty = dest_ty.ip_index,
|
||||
.storage = int_storage,
|
||||
} });
|
||||
const new_val = try mod.intern_pool.getCoercedInt(sema.gpa, val.ip_index, dest_ty.ip_index);
|
||||
return try sema.addConstant(dest_ty, new_val.toValue());
|
||||
}
|
||||
if (dest_ty.zigTypeTag(mod) == .ComptimeInt) {
|
||||
|
||||
Reference in New Issue
Block a user