authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-02-25 18:21:22-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-02-25 18:21:22-07:00
logfd208d9d5913a0929e444deb97b91092c427bb14
tree2d3fa39c5f3b8eec18ead580a8dc1c7a0c091c51
parent4360f45d7fa242f95aae86a137d56c737798dccf

stage2: implement the error_value AST tag


4 files changed, 41 insertions(+), 4 deletions(-)

src/astgen.zig+7-1
......@@ -482,6 +482,13 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) In
482482 const result = try addZIRInst(mod, scope, src, zir.Inst.EnumLiteral, .{ .name = name }, .{});
483483 return rvalue(mod, scope, rl, result);
484484 },
485 .error_value => {
486 const ident_token = node_datas[node].rhs;
487 const name = try mod.identifierTokenString(scope, ident_token);
488 const src = token_starts[ident_token];
489 const result = try addZirInstTag(mod, scope, src, .error_value, .{ .name = name });
490 return rvalue(mod, scope, rl, result);
491 },
485492 .error_union => {
486493 const error_set = try typeExpr(mod, scope, node_datas[node].lhs);
487494 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
644651 => return mod.failNode(scope, node, "TODO implement astgen.expr for function prototypes", .{}),
645652
646653 .@"nosuspend" => return mod.failNode(scope, node, "TODO implement astgen.expr for .nosuspend", .{}),
647 .error_value => return mod.failNode(scope, node, "TODO implement astgen.expr for .error_value", .{}),
648654 }
649655}
650656
src/value.zig+3-3
......@@ -2138,13 +2138,13 @@ pub const Value = extern union {
21382138 data: f128,
21392139 };
21402140
2141 // TODO move to type.zig
2141 /// TODO move to type.zig
21422142 pub const ErrorSet = struct {
21432143 pub const base_tag = Tag.error_set;
21442144
21452145 base: Payload = .{ .tag = base_tag },
21462146 data: struct {
2147 // TODO revisit this when we have the concept of the error tag type
2147 /// TODO revisit this when we have the concept of the error tag type
21482148 fields: std.StringHashMapUnmanaged(u16),
21492149 decl: *Module.Decl,
21502150 },
......@@ -2153,9 +2153,9 @@ pub const Value = extern union {
21532153 pub const Error = struct {
21542154 base: Payload = .{ .tag = .@"error" },
21552155 data: struct {
2156 // TODO revisit this when we have the concept of the error tag type
21572156 /// `name` is owned by `Module` and will be valid for the entire
21582157 /// duration of the compilation.
2158 /// TODO revisit this when we have the concept of the error tag type
21592159 name: []const u8,
21602160 value: u16,
21612161 },
src/zir.zig+14
......@@ -154,6 +154,8 @@ pub const Inst = struct {
154154 error_union_type,
155155 /// Create an error set.
156156 error_set,
157 /// `error.Foo` syntax.
158 error_value,
157159 /// Export the provided Decl as the provided name in the compilation's output object file.
158160 @"export",
159161 /// Given a pointer to a struct or object that contains virtual fields, returns a pointer
......@@ -487,6 +489,7 @@ pub const Inst = struct {
487489 .ptr_type => PtrType,
488490 .enum_literal => EnumLiteral,
489491 .error_set => ErrorSet,
492 .error_value => ErrorValue,
490493 .slice => Slice,
491494 .typeof_peer => TypeOfPeer,
492495 .container_field_named => ContainerFieldNamed,
......@@ -612,6 +615,7 @@ pub const Inst = struct {
612615 .error_union_type,
613616 .bit_not,
614617 .error_set,
618 .error_value,
615619 .slice,
616620 .slice_start,
617621 .import,
......@@ -1099,6 +1103,16 @@ pub const Inst = struct {
10991103 kw_args: struct {},
11001104 };
11011105
1106 pub const ErrorValue = struct {
1107 pub const base_tag = Tag.error_value;
1108 base: Inst,
1109
1110 positionals: struct {
1111 name: []const u8,
1112 },
1113 kw_args: struct {},
1114 };
1115
11021116 pub const Slice = struct {
11031117 pub const base_tag = Tag.slice;
11041118 base: Inst,
src/zir_sema.zig+17
......@@ -149,6 +149,7 @@ pub fn analyzeInst(mod: *Module, scope: *Scope, old_inst: *zir.Inst) InnerError!
149149 .error_union_type => return zirErrorUnionType(mod, scope, old_inst.castTag(.error_union_type).?),
150150 .anyframe_type => return zirAnyframeType(mod, scope, old_inst.castTag(.anyframe_type).?),
151151 .error_set => return zirErrorSet(mod, scope, old_inst.castTag(.error_set).?),
152 .error_value => return zirErrorValue(mod, scope, old_inst.castTag(.error_value).?),
152153 .slice => return zirSlice(mod, scope, old_inst.castTag(.slice).?),
153154 .slice_start => return zirSliceStart(mod, scope, old_inst.castTag(.slice_start).?),
154155 .import => return zirImport(mod, scope, old_inst.castTag(.import).?),
......@@ -1166,6 +1167,22 @@ fn zirErrorSet(mod: *Module, scope: *Scope, inst: *zir.Inst.ErrorSet) InnerError
11661167 return mod.analyzeDeclVal(scope, inst.base.src, new_decl);
11671168}
11681169
1170fn zirErrorValue(mod: *Module, scope: *Scope, inst: *zir.Inst.ErrorValue) InnerError!*Inst {
1171 const tracy = trace(@src());
1172 defer tracy.end();
1173
1174 // Create an anonymous error set type with only this error value, and return the value.
1175 const entry = try mod.getErrorValue(inst.positionals.name);
1176 const result_type = try Type.Tag.error_set_single.create(scope.arena(), entry.key);
1177 return mod.constInst(scope, inst.base.src, .{
1178 .ty = result_type,
1179 .val = try Value.Tag.@"error".create(scope.arena(), .{
1180 .name = entry.key,
1181 .value = entry.value,
1182 }),
1183 });
1184}
1185
11691186fn zirMergeErrorSets(mod: *Module, scope: *Scope, inst: *zir.Inst.BinOp) InnerError!*Inst {
11701187 const tracy = trace(@src());
11711188 defer tracy.end();