aboutsummaryrefslogtreecommitdiff
path: root/src/Sema.zig
diff options
context:
space:
mode:
authorMeghan Denny <hello@nektro.net>2021-10-16 22:49:51 -0700
committerAndrew Kelley <andrew@ziglang.org>2021-10-17 21:42:22 -0700
commit0ef2e2520af59a42014399282ddea983fa526449 (patch)
treeb186116f3064299d58a81cacb2f68ae492d26d65 /src/Sema.zig
parent7d0a74456b0f239e6cc8532143badeb6781bd47d (diff)
downloadzig-0ef2e2520af59a42014399282ddea983fa526449.tar.gz
zig-0ef2e2520af59a42014399282ddea983fa526449.zip
stage2: implement `@hasField`
struct and union are kept in stage1 because struct/unionFieldCount are returning zero
Diffstat (limited to 'src/Sema.zig')
-rw-r--r--src/Sema.zig17
1 files changed, 14 insertions, 3 deletions
diff --git a/src/Sema.zig b/src/Sema.zig
index 589419be86..75698784d5 100644
--- a/src/Sema.zig
+++ b/src/Sema.zig
@@ -6413,10 +6413,21 @@ fn validateSwitchNoRange(
fn zirHasField(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
- _ = extra;
- const src = inst_data.src();
+ const lhs_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
+ const rhs_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };
+ const container_type = try sema.resolveType(block, lhs_src, extra.lhs);
+ const field_name = try sema.resolveConstString(block, rhs_src, extra.rhs);
- return sema.fail(block, src, "TODO implement zirHasField", .{});
+ const has_field = switch (container_type.zigTypeTag()) {
+ .Struct => container_type.structFields().contains(field_name),
+ .Union => container_type.unionFields().contains(field_name),
+ .Enum => container_type.enumFields().contains(field_name),
+ else => return sema.fail(block, lhs_src, "expected struct, enum, or union, found '{}'", .{container_type}),
+ };
+ if (has_field) {
+ return Air.Inst.Ref.bool_true;
+ }
+ return Air.Inst.Ref.bool_false;
}
fn zirHasDecl(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {