authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2023-05-21 22:21:50+01:00
committergravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2023-06-13 21:48:21+01:00
log588f45a0a1492711b2cd9991ba8e9137e583e513
tree8a10108df3ecdbef4102329b489b2a47dfbf8426
parentc9531eb833e1e2c432dc2bfb0ca3b25622b7001e
signaturelock-open Commit is signed but in an unrecognized format.

Sema: allow in-memory coercion of tuples

This allows tuples whose fields are in-memory coercible to themselves be coerced in memory. No InMemoryCoercionResult field has been added, so in future one could be added to improve error messages.

1 files changed, 25 insertions(+), 2 deletions(-)

src/Sema.zig+25-2
...@@ -27326,11 +27326,18 @@ fn coerceValueInMemory(...@@ -27326,11 +27326,18 @@ fn coerceValueInMemory(
27326 .fields.values()[i].ty.toIntern(),27326 .fields.values()[i].ty.toIntern(),
27327 else => unreachable,27327 else => unreachable,
27328 };27328 };
27329 dest_elem.* = try mod.intern_pool.getCoerced(mod.gpa, switch (aggregate.storage) {27329 const cur_val = switch (aggregate.storage) {
27330 .bytes => |bytes| (try mod.intValue(Type.u8, bytes[i])).toIntern(),27330 .bytes => |bytes| (try mod.intValue(Type.u8, bytes[i])).toIntern(),
27331 .elems => |elems| elems[i],27331 .elems => |elems| elems[i],
27332 .repeated_elem => |elem| elem,27332 .repeated_elem => |elem| elem,
27333 }, elem_ty);27333 };
27334 dest_elem.* = (try sema.coerceValueInMemory(
27335 block,
27336 cur_val.toValue(),
27337 mod.intern_pool.typeOf(cur_val).toType(),
27338 elem_ty.toType(),
27339 dst_ty_src,
27340 )).toIntern();
27334 }27341 }
27335 return (try mod.intern(.{ .aggregate = .{27342 return (try mod.intern(.{ .aggregate = .{
27336 .ty = dst_ty.toIntern(),27343 .ty = dst_ty.toIntern(),
...@@ -27891,6 +27898,22 @@ fn coerceInMemoryAllowed(...@@ -27891,6 +27898,22 @@ fn coerceInMemoryAllowed(
27891 return .ok;27898 return .ok;
27892 }27899 }
2789327900
27901 // Tuples (with in-memory-coercible fields)
27902 if (dest_ty.isTuple(mod) and src_ty.isTuple(mod)) tuple: {
27903 if (dest_ty.containerLayout(mod) != src_ty.containerLayout(mod)) break :tuple;
27904 if (dest_ty.structFieldCount(mod) != src_ty.structFieldCount(mod)) break :tuple;
27905 const field_count = dest_ty.structFieldCount(mod);
27906 for (0..field_count) |field_idx| {
27907 if (dest_ty.structFieldIsComptime(field_idx, mod) != src_ty.structFieldIsComptime(field_idx, mod)) break :tuple;
27908 if (dest_ty.structFieldAlign(field_idx, mod) != src_ty.structFieldAlign(field_idx, mod)) break :tuple;
27909 const dest_field_ty = dest_ty.structFieldType(field_idx, mod);
27910 const src_field_ty = src_ty.structFieldType(field_idx, mod);
27911 const field = try sema.coerceInMemoryAllowed(block, dest_field_ty, src_field_ty, dest_is_mut, target, dest_src, src_src);
27912 if (field != .ok) break :tuple;
27913 }
27914 return .ok;
27915 }
27916
27894 return InMemoryCoercionResult{ .no_match = .{27917 return InMemoryCoercionResult{ .no_match = .{
27895 .actual = dest_ty,27918 .actual = dest_ty,
27896 .wanted = src_ty,27919 .wanted = src_ty,