authorgravatar for mitchell.hashimoto@gmail.comMitchell Hashimoto <mitchell.hashimoto@gmail.com> 2022-03-01 17:09:03-08:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-03-03 15:07:23-05:00
log7deadf4301d5f5f5e2b8a1a8b2dc7109e2c82181
tree9ceee5649ba2b889e2fb8cce3ca08e4b1192e10d
parent65943010c70b33e711a038dff5f80066045ee1b7

stage2: reify error sets


3 files changed, 49 insertions(+), 3 deletions(-)

src/Sema.zig+32-2
...@@ -10397,7 +10397,13 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -10397,7 +10397,13 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
10397 vals,10397 vals,
10398 ),10398 ),
10399 );10399 );
10400 break :v try Value.Tag.decl_ref.create(sema.arena, new_decl);10400
10401 const new_decl_val = try Value.Tag.decl_ref.create(sema.arena, new_decl);
10402 const slice_val = try Value.Tag.slice.create(sema.arena, .{
10403 .ptr = new_decl_val,
10404 .len = try Value.Tag.int_u64.create(sema.arena, vals.len),
10405 });
10406 break :v try Value.Tag.opt_payload.create(sema.arena, slice_val);
10401 } else Value.@"null";10407 } else Value.@"null";
1040210408
10403 // Construct TypeInfo{ .ErrorSet = errors_val }10409 // Construct TypeInfo{ .ErrorSet = errors_val }
...@@ -12317,7 +12323,31 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I...@@ -12317,7 +12323,31 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
12317 });12323 });
12318 return sema.addType(ty);12324 return sema.addType(ty);
12319 },12325 },
12320 .ErrorSet => return sema.fail(block, src, "TODO: Sema.zirReify for ErrorSet", .{}),12326 .ErrorSet => {
12327 const payload_val = union_val.val.optionalValue() orelse
12328 return sema.addType(Type.initTag(.anyerror));
12329 const slice_val = payload_val.castTag(.slice).?.data;
12330 const decl = slice_val.ptr.castTag(.decl_ref).?.data;
12331 try sema.ensureDeclAnalyzed(decl);
12332 const array_val = decl.val.castTag(.array).?.data;
12333
12334 var names: Module.ErrorSet.NameMap = .{};
12335 try names.ensureUnusedCapacity(sema.arena, array_val.len);
12336 for (array_val) |elem_val| {
12337 const struct_val = elem_val.castTag(.@"struct").?.data;
12338 // TODO use reflection instead of magic numbers here
12339 // error_set: type,
12340 const name_val = struct_val[0];
12341
12342 names.putAssumeCapacityNoClobber(
12343 try name_val.toAllocatedBytes(Type.initTag(.const_slice_u8), sema.arena),
12344 {},
12345 );
12346 }
12347
12348 const ty = try Type.Tag.error_set_merged.create(sema.arena, names);
12349 return sema.addType(ty);
12350 },
12321 .Enum => return sema.fail(block, src, "TODO: Sema.zirReify for Enum", .{}),12351 .Enum => return sema.fail(block, src, "TODO: Sema.zirReify for Enum", .{}),
12322 .Union => return sema.fail(block, src, "TODO: Sema.zirReify for Union", .{}),12352 .Union => return sema.fail(block, src, "TODO: Sema.zirReify for Union", .{}),
12323 .Fn => return sema.fail(block, src, "TODO: Sema.zirReify for Fn", .{}),12353 .Fn => return sema.fail(block, src, "TODO: Sema.zirReify for Fn", .{}),
src/value.zig+9
...@@ -2506,6 +2506,15 @@ pub const Value = extern union {...@@ -2506,6 +2506,15 @@ pub const Value = extern union {
2506 };2506 };
2507 }2507 }
25082508
2509 /// Value of the optional, null if optional has no payload.
2510 pub fn optionalValue(val: Value) ?Value {
2511 if (val.isNull()) return null;
2512
2513 // Valid for optional representation to be the direct value
2514 // and not use opt_payload.
2515 return if (val.castTag(.opt_payload)) |p| p.data else val;
2516 }
2517
2509 /// Valid for all types. Asserts the value is not undefined.2518 /// Valid for all types. Asserts the value is not undefined.
2510 pub fn isFloat(self: Value) bool {2519 pub fn isFloat(self: Value) bool {
2511 return switch (self.tag()) {2520 return switch (self.tag()) {
test/behavior/type.zig+8-1
...@@ -240,12 +240,19 @@ fn add(a: i32, b: i32) i32 {...@@ -240,12 +240,19 @@ fn add(a: i32, b: i32) i32 {
240}240}
241241
242test "Type.ErrorSet" {242test "Type.ErrorSet" {
243 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO243 try testing.expect(@Type(TypeInfo{ .ErrorSet = null }) == anyerror);
244244
245 // error sets don't compare equal so just check if they compile245 // error sets don't compare equal so just check if they compile
246 _ = @Type(@typeInfo(error{}));246 _ = @Type(@typeInfo(error{}));
247 _ = @Type(@typeInfo(error{A}));247 _ = @Type(@typeInfo(error{A}));
248 _ = @Type(@typeInfo(error{ A, B, C }));248 _ = @Type(@typeInfo(error{ A, B, C }));
249 _ = @Type(TypeInfo{
250 .ErrorSet = &[_]TypeInfo.Error{
251 .{ .name = "A" },
252 .{ .name = "B" },
253 .{ .name = "C" },
254 },
255 });
249}256}
250257
251test "Type.Struct" {258test "Type.Struct" {