diff options
| author | Mitchell Hashimoto <mitchell.hashimoto@gmail.com> | 2022-03-01 17:09:03 -0800 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2022-03-03 15:07:23 -0500 |
| commit | 7deadf4301d5f5f5e2b8a1a8b2dc7109e2c82181 (patch) | |
| tree | 9ceee5649ba2b889e2fb8cce3ca08e4b1192e10d /src | |
| parent | 65943010c70b33e711a038dff5f80066045ee1b7 (diff) | |
| download | zig-7deadf4301d5f5f5e2b8a1a8b2dc7109e2c82181.tar.gz zig-7deadf4301d5f5f5e2b8a1a8b2dc7109e2c82181.zip | |
stage2: reify error sets
Diffstat (limited to 'src')
| -rw-r--r-- | src/Sema.zig | 34 | ||||
| -rw-r--r-- | src/value.zig | 9 |
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()) { |
