Commit fd208d9d59
Changed files (4)
src/astgen.zig
@@ -482,6 +482,13 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) In
const result = try addZIRInst(mod, scope, src, zir.Inst.EnumLiteral, .{ .name = name }, .{});
return rvalue(mod, scope, rl, result);
},
+ .error_value => {
+ const ident_token = node_datas[node].rhs;
+ const name = try mod.identifierTokenString(scope, ident_token);
+ const src = token_starts[ident_token];
+ const result = try addZirInstTag(mod, scope, src, .error_value, .{ .name = name });
+ return rvalue(mod, scope, rl, result);
+ },
.error_union => {
const error_set = try typeExpr(mod, scope, node_datas[node].lhs);
const payload = try typeExpr(mod, scope, node_datas[node].rhs);
@@ -644,7 +651,6 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) In
=> return mod.failNode(scope, node, "TODO implement astgen.expr for function prototypes", .{}),
.@"nosuspend" => return mod.failNode(scope, node, "TODO implement astgen.expr for .nosuspend", .{}),
- .error_value => return mod.failNode(scope, node, "TODO implement astgen.expr for .error_value", .{}),
}
}
src/value.zig
@@ -2138,13 +2138,13 @@ pub const Value = extern union {
data: f128,
};
- // TODO move to type.zig
+ /// TODO move to type.zig
pub const ErrorSet = struct {
pub const base_tag = Tag.error_set;
base: Payload = .{ .tag = base_tag },
data: struct {
- // TODO revisit this when we have the concept of the error tag type
+ /// TODO revisit this when we have the concept of the error tag type
fields: std.StringHashMapUnmanaged(u16),
decl: *Module.Decl,
},
@@ -2153,9 +2153,9 @@ pub const Value = extern union {
pub const Error = struct {
base: Payload = .{ .tag = .@"error" },
data: struct {
- // TODO revisit this when we have the concept of the error tag type
/// `name` is owned by `Module` and will be valid for the entire
/// duration of the compilation.
+ /// TODO revisit this when we have the concept of the error tag type
name: []const u8,
value: u16,
},
src/zir.zig
@@ -154,6 +154,8 @@ pub const Inst = struct {
error_union_type,
/// Create an error set.
error_set,
+ /// `error.Foo` syntax.
+ error_value,
/// Export the provided Decl as the provided name in the compilation's output object file.
@"export",
/// Given a pointer to a struct or object that contains virtual fields, returns a pointer
@@ -487,6 +489,7 @@ pub const Inst = struct {
.ptr_type => PtrType,
.enum_literal => EnumLiteral,
.error_set => ErrorSet,
+ .error_value => ErrorValue,
.slice => Slice,
.typeof_peer => TypeOfPeer,
.container_field_named => ContainerFieldNamed,
@@ -612,6 +615,7 @@ pub const Inst = struct {
.error_union_type,
.bit_not,
.error_set,
+ .error_value,
.slice,
.slice_start,
.import,
@@ -1099,6 +1103,16 @@ pub const Inst = struct {
kw_args: struct {},
};
+ pub const ErrorValue = struct {
+ pub const base_tag = Tag.error_value;
+ base: Inst,
+
+ positionals: struct {
+ name: []const u8,
+ },
+ kw_args: struct {},
+ };
+
pub const Slice = struct {
pub const base_tag = Tag.slice;
base: Inst,
src/zir_sema.zig
@@ -149,6 +149,7 @@ pub fn analyzeInst(mod: *Module, scope: *Scope, old_inst: *zir.Inst) InnerError!
.error_union_type => return zirErrorUnionType(mod, scope, old_inst.castTag(.error_union_type).?),
.anyframe_type => return zirAnyframeType(mod, scope, old_inst.castTag(.anyframe_type).?),
.error_set => return zirErrorSet(mod, scope, old_inst.castTag(.error_set).?),
+ .error_value => return zirErrorValue(mod, scope, old_inst.castTag(.error_value).?),
.slice => return zirSlice(mod, scope, old_inst.castTag(.slice).?),
.slice_start => return zirSliceStart(mod, scope, old_inst.castTag(.slice_start).?),
.import => return zirImport(mod, scope, old_inst.castTag(.import).?),
@@ -1166,6 +1167,22 @@ fn zirErrorSet(mod: *Module, scope: *Scope, inst: *zir.Inst.ErrorSet) InnerError
return mod.analyzeDeclVal(scope, inst.base.src, new_decl);
}
+fn zirErrorValue(mod: *Module, scope: *Scope, inst: *zir.Inst.ErrorValue) InnerError!*Inst {
+ const tracy = trace(@src());
+ defer tracy.end();
+
+ // Create an anonymous error set type with only this error value, and return the value.
+ const entry = try mod.getErrorValue(inst.positionals.name);
+ const result_type = try Type.Tag.error_set_single.create(scope.arena(), entry.key);
+ return mod.constInst(scope, inst.base.src, .{
+ .ty = result_type,
+ .val = try Value.Tag.@"error".create(scope.arena(), .{
+ .name = entry.key,
+ .value = entry.value,
+ }),
+ });
+}
+
fn zirMergeErrorSets(mod: *Module, scope: *Scope, inst: *zir.Inst.BinOp) InnerError!*Inst {
const tracy = trace(@src());
defer tracy.end();