aboutsummaryrefslogtreecommitdiff
path: root/src/Sema.zig
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2022-02-24 22:27:54 -0700
committerAndrew Kelley <andrew@ziglang.org>2022-02-24 22:28:37 -0700
commit27eb42c15e4e9ab547eaf02cca8810cc0e10e6bf (patch)
tree83cd40198ef1f55946163766a04fe9202a510206 /src/Sema.zig
parentadb746a7017ba6f91974d5e940bc8a8f64bb45f5 (diff)
downloadzig-27eb42c15e4e9ab547eaf02cca8810cc0e10e6bf.tar.gz
zig-27eb42c15e4e9ab547eaf02cca8810cc0e10e6bf.zip
Sema: implement tupleFieldVal, fix comptime elem_ptr
Diffstat (limited to 'src/Sema.zig')
-rw-r--r--src/Sema.zig44
1 files changed, 44 insertions, 0 deletions
diff --git a/src/Sema.zig b/src/Sema.zig
index 3ba9761cd8..ef9ba41bec 100644
--- a/src/Sema.zig
+++ b/src/Sema.zig
@@ -14360,6 +14360,10 @@ fn structFieldVal(
assert(unresolved_struct_ty.zigTypeTag() == .Struct);
const struct_ty = try sema.resolveTypeFields(block, src, unresolved_struct_ty);
+ if (struct_ty.isTuple()) {
+ return sema.tupleFieldVal(block, src, struct_byval, field_name, field_name_src, struct_ty);
+ }
+
const struct_obj = struct_ty.castTag(.@"struct").?.data;
const field_index_usize = struct_obj.fields.getIndex(field_name) orelse
@@ -14381,6 +14385,46 @@ fn structFieldVal(
return block.addStructFieldVal(struct_byval, field_index, field.ty);
}
+fn tupleFieldVal(
+ sema: *Sema,
+ block: *Block,
+ src: LazySrcLoc,
+ tuple_byval: Air.Inst.Ref,
+ field_name: []const u8,
+ field_name_src: LazySrcLoc,
+ tuple_ty: Type,
+) CompileError!Air.Inst.Ref {
+ const tuple = tuple_ty.castTag(.tuple).?.data;
+
+ if (mem.eql(u8, field_name, "len")) {
+ return sema.addIntUnsigned(Type.usize, tuple.types.len);
+ }
+
+ const field_index = std.fmt.parseUnsigned(u32, field_name, 10) catch |err| {
+ return sema.fail(block, field_name_src, "tuple {} has no such field '{s}': {s}", .{
+ tuple_ty, field_name, @errorName(err),
+ });
+ };
+
+ const field_ty = tuple.types[field_index];
+
+ if (tuple.values[field_index].tag() != .unreachable_value) {
+ return sema.addConstant(field_ty, tuple.values[field_index]);
+ }
+
+ if (try sema.resolveMaybeUndefVal(block, src, tuple_byval)) |tuple_val| {
+ if (tuple_val.isUndef()) return sema.addConstUndef(field_ty);
+ if ((try sema.typeHasOnePossibleValue(block, src, field_ty))) |opv| {
+ return sema.addConstant(field_ty, opv);
+ }
+ const field_values = tuple_val.castTag(.@"struct").?.data;
+ return sema.addConstant(field_ty, field_values[field_index]);
+ }
+
+ try sema.requireRuntimeBlock(block, src);
+ return block.addStructFieldVal(tuple_byval, field_index, field_ty);
+}
+
fn unionFieldPtr(
sema: *Sema,
block: *Block,