aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMitchell Hashimoto <mitchell.hashimoto@gmail.com>2022-03-01 17:09:03 -0800
committerAndrew Kelley <andrew@ziglang.org>2022-03-03 15:07:23 -0500
commit7deadf4301d5f5f5e2b8a1a8b2dc7109e2c82181 (patch)
tree9ceee5649ba2b889e2fb8cce3ca08e4b1192e10d /src
parent65943010c70b33e711a038dff5f80066045ee1b7 (diff)
downloadzig-7deadf4301d5f5f5e2b8a1a8b2dc7109e2c82181.tar.gz
zig-7deadf4301d5f5f5e2b8a1a8b2dc7109e2c82181.zip
stage2: reify error sets
Diffstat (limited to 'src')
-rw-r--r--src/Sema.zig34
-rw-r--r--src/value.zig9
2 files changed, 41 insertions, 2 deletions
diff --git a/src/Sema.zig b/src/Sema.zig
index 998efadcef..adc0492446 100644
--- a/src/Sema.zig
+++ b/src/Sema.zig
@@ -10397,7 +10397,13 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
vals,
),
);
- break :v try Value.Tag.decl_ref.create(sema.arena, new_decl);
+
+ const new_decl_val = try Value.Tag.decl_ref.create(sema.arena, new_decl);
+ const slice_val = try Value.Tag.slice.create(sema.arena, .{
+ .ptr = new_decl_val,
+ .len = try Value.Tag.int_u64.create(sema.arena, vals.len),
+ });
+ break :v try Value.Tag.opt_payload.create(sema.arena, slice_val);
} else Value.@"null";
// Construct TypeInfo{ .ErrorSet = errors_val }
@@ -12317,7 +12323,31 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
});
return sema.addType(ty);
},
- .ErrorSet => return sema.fail(block, src, "TODO: Sema.zirReify for ErrorSet", .{}),
+ .ErrorSet => {
+ const payload_val = union_val.val.optionalValue() orelse
+ return sema.addType(Type.initTag(.anyerror));
+ const slice_val = payload_val.castTag(.slice).?.data;
+ const decl = slice_val.ptr.castTag(.decl_ref).?.data;
+ try sema.ensureDeclAnalyzed(decl);
+ const array_val = decl.val.castTag(.array).?.data;
+
+ var names: Module.ErrorSet.NameMap = .{};
+ try names.ensureUnusedCapacity(sema.arena, array_val.len);
+ for (array_val) |elem_val| {
+ const struct_val = elem_val.castTag(.@"struct").?.data;
+ // TODO use reflection instead of magic numbers here
+ // error_set: type,
+ const name_val = struct_val[0];
+
+ names.putAssumeCapacityNoClobber(
+ try name_val.toAllocatedBytes(Type.initTag(.const_slice_u8), sema.arena),
+ {},
+ );
+ }
+
+ const ty = try Type.Tag.error_set_merged.create(sema.arena, names);
+ return sema.addType(ty);
+ },
.Enum => return sema.fail(block, src, "TODO: Sema.zirReify for Enum", .{}),
.Union => return sema.fail(block, src, "TODO: Sema.zirReify for Union", .{}),
.Fn => return sema.fail(block, src, "TODO: Sema.zirReify for Fn", .{}),
diff --git a/src/value.zig b/src/value.zig
index d576074ba3..e667c566b9 100644
--- a/src/value.zig
+++ b/src/value.zig
@@ -2506,6 +2506,15 @@ pub const Value = extern union {
};
}
+ /// Value of the optional, null if optional has no payload.
+ pub fn optionalValue(val: Value) ?Value {
+ if (val.isNull()) return null;
+
+ // Valid for optional representation to be the direct value
+ // and not use opt_payload.
+ return if (val.castTag(.opt_payload)) |p| p.data else val;
+ }
+
/// Valid for all types. Asserts the value is not undefined.
pub fn isFloat(self: Value) bool {
return switch (self.tag()) {