Skip to content

Commit

Permalink
Sema: allow in-memory coercion of tuples
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
mlugg committed Jun 13, 2023
1 parent 2ed8904 commit 1b6f3f5
Showing 1 changed file with 19 additions and 13 deletions.
32 changes: 19 additions & 13 deletions src/Sema.zig
Original file line number Diff line number Diff line change
Expand Up @@ -26807,11 +26807,18 @@ fn coerceValueInMemory(
.fields.values()[i].ty.toIntern(),
else => unreachable,
};
dest_elem.* = try mod.intern_pool.getCoerced(mod.gpa, switch (aggregate.storage) {
const cur_val = switch (aggregate.storage) {
.bytes => |bytes| (try mod.intValue(Type.u8, bytes[i])).toIntern(),
.elems => |elems| elems[i],
.repeated_elem => |elem| elem,
}, elem_ty);
};
dest_elem.* = (try sema.coerceValueInMemory(
block,
cur_val.toValue(),
mod.intern_pool.typeOf(cur_val).toType(),
elem_ty.toType(),
dst_ty_src,
)).toIntern();
}
return (try mod.intern(.{ .aggregate = .{
.ty = dst_ty.toIntern(),
Expand Down Expand Up @@ -27372,17 +27379,16 @@ fn coerceInMemoryAllowed(
return .ok;
}

// Tuples
// TODO: this can go away once tuple type equality works
if (dest_ty.isTuple() and src_ty.isTuple()) tuple: {
if (dest_ty.containerLayout() != src_ty.containerLayout()) break :tuple;
if (dest_ty.structFieldCount() != src_ty.structFieldCount()) break :tuple;
const field_count = dest_ty.structFieldCount();
// Tuples (with in-memory-coercible fields)
if (dest_ty.isTuple(mod) and src_ty.isTuple(mod)) tuple: {
if (dest_ty.containerLayout(mod) != src_ty.containerLayout(mod)) break :tuple;
if (dest_ty.structFieldCount(mod) != src_ty.structFieldCount(mod)) break :tuple;
const field_count = dest_ty.structFieldCount(mod);
for (0..field_count) |field_idx| {
if (dest_ty.structFieldIsComptime(field_idx) != src_ty.structFieldIsComptime(field_idx)) break :tuple;
if (dest_ty.structFieldAlign(field_idx, target) != src_ty.structFieldAlign(field_idx, target)) break :tuple;
const dest_field_ty = dest_ty.structFieldType(field_idx);
const src_field_ty = src_ty.structFieldType(field_idx);
if (dest_ty.structFieldIsComptime(field_idx, mod) != src_ty.structFieldIsComptime(field_idx, mod)) break :tuple;
if (dest_ty.structFieldAlign(field_idx, mod) != src_ty.structFieldAlign(field_idx, mod)) break :tuple;
const dest_field_ty = dest_ty.structFieldType(field_idx, mod);
const src_field_ty = src_ty.structFieldType(field_idx, mod);
const field = try sema.coerceInMemoryAllowed(block, dest_field_ty, src_field_ty, dest_is_mut, target, dest_src, src_src);
if (field != .ok) break :tuple;
}
Expand Down Expand Up @@ -32401,7 +32407,7 @@ fn resolvePeerTypesInner(
is_tuple = ty.isTuple(mod);
field_count = ty.structFieldCount(mod);
if (!is_tuple) {
const names = mod.intern_pool.indexTokey(ty.toIntern()).anon_struct_type.names;
const names = mod.intern_pool.indexToKey(ty.toIntern()).anon_struct_type.names;
field_names = try sema.arena.dupe(InternPool.NullTerminatedString, names);
}
continue;
Expand Down

0 comments on commit 1b6f3f5

Please sign in to comment.