mirror of
https://github.com/ziglang/zig.git
synced 2025-12-10 16:23:07 +00:00
Sema: fix in-memory coercion during comptime load
This commit is contained in:
parent
dc18739a73
commit
e8bcdca044
44
src/Sema.zig
44
src/Sema.zig
@ -22472,9 +22472,7 @@ fn analyzeMinMax(
|
|||||||
if (std.debug.runtime_safety) {
|
if (std.debug.runtime_safety) {
|
||||||
assert(try sema.intFitsInType(val, refined_ty, null));
|
assert(try sema.intFitsInType(val, refined_ty, null));
|
||||||
}
|
}
|
||||||
cur_minmax = try sema.addConstant(refined_ty, (try sema.resolveMaybeUndefVal(
|
cur_minmax = try sema.coerceInMemory(block, val, orig_ty, refined_ty, src);
|
||||||
try sema.coerceInMemory(block, val, orig_ty, refined_ty, src),
|
|
||||||
)).?);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
break :refined refined_ty;
|
break :refined refined_ty;
|
||||||
@ -26659,16 +26657,16 @@ fn coerceExtra(
|
|||||||
return sema.failWithOwnedErrorMsg(msg);
|
return sema.failWithOwnedErrorMsg(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn coerceInMemory(
|
fn coerceValueInMemory(
|
||||||
sema: *Sema,
|
sema: *Sema,
|
||||||
block: *Block,
|
block: *Block,
|
||||||
val: Value,
|
val: Value,
|
||||||
src_ty: Type,
|
src_ty: Type,
|
||||||
dst_ty: Type,
|
dst_ty: Type,
|
||||||
dst_ty_src: LazySrcLoc,
|
dst_ty_src: LazySrcLoc,
|
||||||
) CompileError!Air.Inst.Ref {
|
) CompileError!Value {
|
||||||
const mod = sema.mod;
|
const mod = sema.mod;
|
||||||
switch (mod.intern_pool.indexToKey(val.toIntern())) {
|
return switch (mod.intern_pool.indexToKey(val.toIntern())) {
|
||||||
.aggregate => |aggregate| {
|
.aggregate => |aggregate| {
|
||||||
const dst_ty_key = mod.intern_pool.indexToKey(dst_ty.toIntern());
|
const dst_ty_key = mod.intern_pool.indexToKey(dst_ty.toIntern());
|
||||||
const dest_len = try sema.usizeCast(
|
const dest_len = try sema.usizeCast(
|
||||||
@ -26688,14 +26686,14 @@ fn coerceInMemory(
|
|||||||
else => unreachable,
|
else => unreachable,
|
||||||
};
|
};
|
||||||
if (src_ty_child != dst_ty_child) break :direct;
|
if (src_ty_child != dst_ty_child) break :direct;
|
||||||
return try sema.addConstant(dst_ty, (try mod.intern(.{ .aggregate = .{
|
return (try mod.intern(.{ .aggregate = .{
|
||||||
.ty = dst_ty.toIntern(),
|
.ty = dst_ty.toIntern(),
|
||||||
.storage = switch (aggregate.storage) {
|
.storage = switch (aggregate.storage) {
|
||||||
.bytes => |bytes| .{ .bytes = bytes[0..dest_len] },
|
.bytes => |bytes| .{ .bytes = bytes[0..dest_len] },
|
||||||
.elems => |elems| .{ .elems = elems[0..dest_len] },
|
.elems => |elems| .{ .elems = elems[0..dest_len] },
|
||||||
.repeated_elem => |elem| .{ .repeated_elem = elem },
|
.repeated_elem => |elem| .{ .repeated_elem = elem },
|
||||||
},
|
},
|
||||||
} })).toValue());
|
} })).toValue();
|
||||||
}
|
}
|
||||||
const dest_elems = try sema.arena.alloc(InternPool.Index, dest_len);
|
const dest_elems = try sema.arena.alloc(InternPool.Index, dest_len);
|
||||||
for (dest_elems, 0..) |*dest_elem, i| {
|
for (dest_elems, 0..) |*dest_elem, i| {
|
||||||
@ -26712,17 +26710,28 @@ fn coerceInMemory(
|
|||||||
.repeated_elem => |elem| elem,
|
.repeated_elem => |elem| elem,
|
||||||
}, elem_ty);
|
}, elem_ty);
|
||||||
}
|
}
|
||||||
return sema.addConstant(dst_ty, (try mod.intern(.{ .aggregate = .{
|
return (try mod.intern(.{ .aggregate = .{
|
||||||
.ty = dst_ty.toIntern(),
|
.ty = dst_ty.toIntern(),
|
||||||
.storage = .{ .elems = dest_elems },
|
.storage = .{ .elems = dest_elems },
|
||||||
} })).toValue());
|
} })).toValue();
|
||||||
},
|
},
|
||||||
.float => |float| return sema.addConstant(dst_ty, (try mod.intern(.{ .float = .{
|
.float => |float| (try mod.intern(.{ .float = .{
|
||||||
.ty = dst_ty.toIntern(),
|
.ty = dst_ty.toIntern(),
|
||||||
.storage = float.storage,
|
.storage = float.storage,
|
||||||
} })).toValue()),
|
} })).toValue(),
|
||||||
else => return sema.addConstant(dst_ty, try mod.getCoerced(val, dst_ty)),
|
else => try mod.getCoerced(val, dst_ty),
|
||||||
}
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn coerceInMemory(
|
||||||
|
sema: *Sema,
|
||||||
|
block: *Block,
|
||||||
|
val: Value,
|
||||||
|
src_ty: Type,
|
||||||
|
dst_ty: Type,
|
||||||
|
dst_ty_src: LazySrcLoc,
|
||||||
|
) CompileError!Air.Inst.Ref {
|
||||||
|
return sema.addConstant(dst_ty, try sema.coerceValueInMemory(block, val, src_ty, dst_ty, dst_ty_src));
|
||||||
}
|
}
|
||||||
|
|
||||||
const InMemoryCoercionResult = union(enum) {
|
const InMemoryCoercionResult = union(enum) {
|
||||||
@ -33935,8 +33944,11 @@ fn pointerDerefExtra(sema: *Sema, block: *Block, src: LazySrcLoc, ptr_val: Value
|
|||||||
if (coerce_in_mem_ok) {
|
if (coerce_in_mem_ok) {
|
||||||
// We have a Value that lines up in virtual memory exactly with what we want to load,
|
// We have a Value that lines up in virtual memory exactly with what we want to load,
|
||||||
// and it is in-memory coercible to load_ty. It may be returned without modifications.
|
// and it is in-memory coercible to load_ty. It may be returned without modifications.
|
||||||
// Move mutable decl values to the InternPool and assert other decls are already in the InternPool.
|
// Move mutable decl values to the InternPool and assert other decls are already in
|
||||||
return .{ .val = (if (deref.is_mutable) try tv.val.intern(tv.ty, mod) else tv.val.toIntern()).toValue() };
|
// the InternPool.
|
||||||
|
const uncoerced_val = if (deref.is_mutable) try tv.val.intern(tv.ty, mod) else tv.val.toIntern();
|
||||||
|
const coerced_val = try sema.coerceValueInMemory(block, uncoerced_val.toValue(), tv.ty, load_ty, src);
|
||||||
|
return .{ .val = coerced_val };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1842,6 +1842,7 @@ pub const Value = struct {
|
|||||||
pub fn elemValue(val: Value, mod: *Module, index: usize) Allocator.Error!Value {
|
pub fn elemValue(val: Value, mod: *Module, index: usize) Allocator.Error!Value {
|
||||||
return switch (val.ip_index) {
|
return switch (val.ip_index) {
|
||||||
.none => switch (val.tag()) {
|
.none => switch (val.tag()) {
|
||||||
|
.bytes => try mod.intValue(Type.u8, val.castTag(.bytes).?.data[index]),
|
||||||
.repeated => val.castTag(.repeated).?.data,
|
.repeated => val.castTag(.repeated).?.data,
|
||||||
.aggregate => val.castTag(.aggregate).?.data[index],
|
.aggregate => val.castTag(.aggregate).?.data[index],
|
||||||
.slice => val.castTag(.slice).?.data.ptr.elemValue(mod, index),
|
.slice => val.castTag(.slice).?.data.ptr.elemValue(mod, index),
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user