authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-08-24 15:42:30-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-08-24 15:42:30-07:00
logb30c5380765bea26647a72ec55f9191824e00d4e
tree7c3df86465e4319d4ed1b237d6b0f1fa3f166e81
parentfd9f509d6dcad43f5b1bf17e57b1f0b200755df8
parent16d54c70eb35b58e871c538bf172991aa81191fe

Merge branch 'Vexu-stage2'

closes #6148

6 files changed, 662 insertions(+), 76 deletions(-)

src-self-hosted/Module.zig+42
...@@ -80,6 +80,9 @@ deletion_set: std.ArrayListUnmanaged(*Decl) = .{},...@@ -80,6 +80,9 @@ deletion_set: std.ArrayListUnmanaged(*Decl) = .{},
80root_name: []u8,80root_name: []u8,
81keep_source_files_loaded: bool,81keep_source_files_loaded: bool,
8282
83/// Error tags and their values, tag names are duped with mod.gpa.
84global_error_set: std.StringHashMapUnmanaged(u16) = .{},
85
83pub const InnerError = error{ OutOfMemory, AnalysisFail };86pub const InnerError = error{ OutOfMemory, AnalysisFail };
8487
85const WorkItem = union(enum) {88const WorkItem = union(enum) {
...@@ -928,6 +931,11 @@ pub fn deinit(self: *Module) void {...@@ -928,6 +931,11 @@ pub fn deinit(self: *Module) void {
928931
929 self.symbol_exports.deinit(gpa);932 self.symbol_exports.deinit(gpa);
930 self.root_scope.destroy(gpa);933 self.root_scope.destroy(gpa);
934
935 for (self.global_error_set.items()) |entry| {
936 gpa.free(entry.key);
937 }
938 self.global_error_set.deinit(gpa);
931 self.* = undefined;939 self.* = undefined;
932}940}
933941
...@@ -2072,6 +2080,18 @@ fn createNewDecl(...@@ -2072,6 +2080,18 @@ fn createNewDecl(
2072 return new_decl;2080 return new_decl;
2073}2081}
20742082
2083/// Get error value for error tag `name`.
2084pub fn getErrorValue(self: *Module, name: []const u8) !std.StringHashMapUnmanaged(u16).Entry {
2085 const gop = try self.global_error_set.getOrPut(self.gpa, name);
2086 if (gop.found_existing)
2087 return gop.entry.*;
2088 errdefer self.global_error_set.removeAssertDiscard(name);
2089
2090 gop.entry.key = try self.gpa.dupe(u8, name);
2091 gop.entry.value = @intCast(u16, self.global_error_set.items().len - 1);
2092 return gop.entry.*;
2093}
2094
2075/// TODO split this into `requireRuntimeBlock` and `requireFunctionBlock` and audit callsites.2095/// TODO split this into `requireRuntimeBlock` and `requireFunctionBlock` and audit callsites.
2076pub fn requireRuntimeBlock(self: *Module, scope: *Scope, src: usize) !*Scope.Block {2096pub fn requireRuntimeBlock(self: *Module, scope: *Scope, src: usize) !*Scope.Block {
2077 return scope.cast(Scope.Block) orelse2097 return scope.cast(Scope.Block) orelse
...@@ -3309,6 +3329,28 @@ pub fn arrayType(self: *Module, scope: *Scope, len: u64, sentinel: ?Value, elem_...@@ -3309,6 +3329,28 @@ pub fn arrayType(self: *Module, scope: *Scope, len: u64, sentinel: ?Value, elem_
3309 return Type.initPayload(&payload.base);3329 return Type.initPayload(&payload.base);
3310}3330}
33113331
3332pub fn errorUnionType(self: *Module, scope: *Scope, error_set: Type, payload: Type) Allocator.Error!Type {
3333 assert(error_set.zigTypeTag() == .ErrorSet);
3334 if (error_set.eql(Type.initTag(.anyerror)) and payload.eql(Type.initTag(.void))) {
3335 return Type.initTag(.anyerror_void_error_union);
3336 }
3337
3338 const result = try scope.arena().create(Type.Payload.ErrorUnion);
3339 result.* = .{
3340 .error_set = error_set,
3341 .payload = payload,
3342 };
3343 return Type.initPayload(&result.base);
3344}
3345
3346pub fn anyframeType(self: *Module, scope: *Scope, return_type: Type) Allocator.Error!Type {
3347 const result = try scope.arena().create(Type.Payload.AnyFrame);
3348 result.* = .{
3349 .return_type = return_type,
3350 };
3351 return Type.initPayload(&result.base);
3352}
3353
3312pub fn dumpInst(self: *Module, scope: *Scope, inst: *Inst) void {3354pub fn dumpInst(self: *Module, scope: *Scope, inst: *Inst) void {
3313 const zir_module = scope.namespace();3355 const zir_module = scope.namespace();
3314 const source = zir_module.getSource(self) catch @panic("dumpInst failed to get source");3356 const source = zir_module.getSource(self) catch @panic("dumpInst failed to get source");
src-self-hosted/astgen.zig+100-61
...@@ -232,6 +232,11 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node) InnerEr...@@ -232,6 +232,11 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node) InnerEr
232 .BoolAnd => return boolBinOp(mod, scope, rl, node.castTag(.BoolAnd).?),232 .BoolAnd => return boolBinOp(mod, scope, rl, node.castTag(.BoolAnd).?),
233 .BoolOr => return boolBinOp(mod, scope, rl, node.castTag(.BoolOr).?),233 .BoolOr => return boolBinOp(mod, scope, rl, node.castTag(.BoolOr).?),
234234
235 .BoolNot => return rlWrap(mod, scope, rl, try boolNot(mod, scope, node.castTag(.BoolNot).?)),
236 .BitNot => return rlWrap(mod, scope, rl, try bitNot(mod, scope, node.castTag(.BitNot).?)),
237 .Negation => return rlWrap(mod, scope, rl, try negation(mod, scope, node.castTag(.Negation).?, .sub)),
238 .NegationWrap => return rlWrap(mod, scope, rl, try negation(mod, scope, node.castTag(.NegationWrap).?, .subwrap)),
239
235 .Identifier => return try identifier(mod, scope, rl, node.castTag(.Identifier).?),240 .Identifier => return try identifier(mod, scope, rl, node.castTag(.Identifier).?),
236 .Asm => return rlWrap(mod, scope, rl, try assembly(mod, scope, node.castTag(.Asm).?)),241 .Asm => return rlWrap(mod, scope, rl, try assembly(mod, scope, node.castTag(.Asm).?)),
237 .StringLiteral => return rlWrap(mod, scope, rl, try stringLiteral(mod, scope, node.castTag(.StringLiteral).?)),242 .StringLiteral => return rlWrap(mod, scope, rl, try stringLiteral(mod, scope, node.castTag(.StringLiteral).?)),
...@@ -242,9 +247,8 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node) InnerEr...@@ -242,9 +247,8 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node) InnerEr
242 .Return => return ret(mod, scope, node.castTag(.Return).?),247 .Return => return ret(mod, scope, node.castTag(.Return).?),
243 .If => return ifExpr(mod, scope, rl, node.castTag(.If).?),248 .If => return ifExpr(mod, scope, rl, node.castTag(.If).?),
244 .While => return whileExpr(mod, scope, rl, node.castTag(.While).?),249 .While => return whileExpr(mod, scope, rl, node.castTag(.While).?),
245 .Period => return rlWrap(mod, scope, rl, try field(mod, scope, node.castTag(.Period).?)),250 .Period => return field(mod, scope, rl, node.castTag(.Period).?),
246 .Deref => return rlWrap(mod, scope, rl, try deref(mod, scope, node.castTag(.Deref).?)),251 .Deref => return rlWrap(mod, scope, rl, try deref(mod, scope, node.castTag(.Deref).?)),
247 .BoolNot => return rlWrap(mod, scope, rl, try boolNot(mod, scope, node.castTag(.BoolNot).?)),
248 .AddressOf => return rlWrap(mod, scope, rl, try addressOf(mod, scope, node.castTag(.AddressOf).?)),252 .AddressOf => return rlWrap(mod, scope, rl, try addressOf(mod, scope, node.castTag(.AddressOf).?)),
249 .FloatLiteral => return rlWrap(mod, scope, rl, try floatLiteral(mod, scope, node.castTag(.FloatLiteral).?)),253 .FloatLiteral => return rlWrap(mod, scope, rl, try floatLiteral(mod, scope, node.castTag(.FloatLiteral).?)),
250 .UndefinedLiteral => return rlWrap(mod, scope, rl, try undefLiteral(mod, scope, node.castTag(.UndefinedLiteral).?)),254 .UndefinedLiteral => return rlWrap(mod, scope, rl, try undefLiteral(mod, scope, node.castTag(.UndefinedLiteral).?)),
...@@ -263,17 +267,17 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node) InnerEr...@@ -263,17 +267,17 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node) InnerEr
263 .MultilineStringLiteral => return rlWrap(mod, scope, rl, try multilineStrLiteral(mod, scope, node.castTag(.MultilineStringLiteral).?)),267 .MultilineStringLiteral => return rlWrap(mod, scope, rl, try multilineStrLiteral(mod, scope, node.castTag(.MultilineStringLiteral).?)),
264 .CharLiteral => return rlWrap(mod, scope, rl, try charLiteral(mod, scope, node.castTag(.CharLiteral).?)),268 .CharLiteral => return rlWrap(mod, scope, rl, try charLiteral(mod, scope, node.castTag(.CharLiteral).?)),
265 .SliceType => return rlWrap(mod, scope, rl, try sliceType(mod, scope, node.castTag(.SliceType).?)),269 .SliceType => return rlWrap(mod, scope, rl, try sliceType(mod, scope, node.castTag(.SliceType).?)),
270 .ErrorUnion => return rlWrap(mod, scope, rl, try typeInixOp(mod, scope, node.castTag(.ErrorUnion).?, .error_union_type)),
271 .MergeErrorSets => return rlWrap(mod, scope, rl, try typeInixOp(mod, scope, node.castTag(.MergeErrorSets).?, .merge_error_sets)),
272 .AnyFrameType => return rlWrap(mod, scope, rl, try anyFrameType(mod, scope, node.castTag(.AnyFrameType).?)),
273 .ErrorSetDecl => return errorSetDecl(mod, scope, rl, node.castTag(.ErrorSetDecl).?),
274 .ErrorType => return rlWrap(mod, scope, rl, try errorType(mod, scope, node.castTag(.ErrorType).?)),
266275
267 .Defer => return mod.failNode(scope, node, "TODO implement astgen.expr for .Defer", .{}),276 .Defer => return mod.failNode(scope, node, "TODO implement astgen.expr for .Defer", .{}),
268 .Catch => return mod.failNode(scope, node, "TODO implement astgen.expr for .Catch", .{}),277 .Catch => return mod.failNode(scope, node, "TODO implement astgen.expr for .Catch", .{}),
269 .ErrorUnion => return mod.failNode(scope, node, "TODO implement astgen.expr for .ErrorUnion", .{}),
270 .MergeErrorSets => return mod.failNode(scope, node, "TODO implement astgen.expr for .MergeErrorSets", .{}),
271 .Range => return mod.failNode(scope, node, "TODO implement astgen.expr for .Range", .{}),278 .Range => return mod.failNode(scope, node, "TODO implement astgen.expr for .Range", .{}),
272 .OrElse => return mod.failNode(scope, node, "TODO implement astgen.expr for .OrElse", .{}),279 .OrElse => return mod.failNode(scope, node, "TODO implement astgen.expr for .OrElse", .{}),
273 .Await => return mod.failNode(scope, node, "TODO implement astgen.expr for .Await", .{}),280 .Await => return mod.failNode(scope, node, "TODO implement astgen.expr for .Await", .{}),
274 .BitNot => return mod.failNode(scope, node, "TODO implement astgen.expr for .BitNot", .{}),
275 .Negation => return mod.failNode(scope, node, "TODO implement astgen.expr for .Negation", .{}),
276 .NegationWrap => return mod.failNode(scope, node, "TODO implement astgen.expr for .NegationWrap", .{}),
277 .Resume => return mod.failNode(scope, node, "TODO implement astgen.expr for .Resume", .{}),281 .Resume => return mod.failNode(scope, node, "TODO implement astgen.expr for .Resume", .{}),
278 .Try => return mod.failNode(scope, node, "TODO implement astgen.expr for .Try", .{}),282 .Try => return mod.failNode(scope, node, "TODO implement astgen.expr for .Try", .{}),
279 .Slice => return mod.failNode(scope, node, "TODO implement astgen.expr for .Slice", .{}),283 .Slice => return mod.failNode(scope, node, "TODO implement astgen.expr for .Slice", .{}),
...@@ -287,10 +291,7 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node) InnerEr...@@ -287,10 +291,7 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node) InnerEr
287 .Suspend => return mod.failNode(scope, node, "TODO implement astgen.expr for .Suspend", .{}),291 .Suspend => return mod.failNode(scope, node, "TODO implement astgen.expr for .Suspend", .{}),
288 .Continue => return mod.failNode(scope, node, "TODO implement astgen.expr for .Continue", .{}),292 .Continue => return mod.failNode(scope, node, "TODO implement astgen.expr for .Continue", .{}),
289 .AnyType => return mod.failNode(scope, node, "TODO implement astgen.expr for .AnyType", .{}),293 .AnyType => return mod.failNode(scope, node, "TODO implement astgen.expr for .AnyType", .{}),
290 .ErrorType => return mod.failNode(scope, node, "TODO implement astgen.expr for .ErrorType", .{}),
291 .FnProto => return mod.failNode(scope, node, "TODO implement astgen.expr for .FnProto", .{}),294 .FnProto => return mod.failNode(scope, node, "TODO implement astgen.expr for .FnProto", .{}),
292 .AnyFrameType => return mod.failNode(scope, node, "TODO implement astgen.expr for .AnyFrameType", .{}),
293 .ErrorSetDecl => return mod.failNode(scope, node, "TODO implement astgen.expr for .ErrorSetDecl", .{}),
294 .ContainerDecl => return mod.failNode(scope, node, "TODO implement astgen.expr for .ContainerDecl", .{}),295 .ContainerDecl => return mod.failNode(scope, node, "TODO implement astgen.expr for .ContainerDecl", .{}),
295 .Comptime => return mod.failNode(scope, node, "TODO implement astgen.expr for .Comptime", .{}),296 .Comptime => return mod.failNode(scope, node, "TODO implement astgen.expr for .Comptime", .{}),
296 .Nosuspend => return mod.failNode(scope, node, "TODO implement astgen.expr for .Nosuspend", .{}),297 .Nosuspend => return mod.failNode(scope, node, "TODO implement astgen.expr for .Nosuspend", .{}),
...@@ -458,7 +459,9 @@ fn varDecl(...@@ -458,7 +459,9 @@ fn varDecl(
458 const tree = scope.tree();459 const tree = scope.tree();
459 const name_src = tree.token_locs[node.name_token].start;460 const name_src = tree.token_locs[node.name_token].start;
460 const ident_name = try identifierTokenString(mod, scope, node.name_token);461 const ident_name = try identifierTokenString(mod, scope, node.name_token);
461 const init_node = node.getTrailer("init_node").?;462 const init_node = node.getTrailer("init_node") orelse
463 return mod.fail(scope, name_src, "variables must be initialized", .{});
464
462 switch (tree.token_ids[node.mut_token]) {465 switch (tree.token_ids[node.mut_token]) {
463 .Keyword_const => {466 .Keyword_const => {
464 // Depending on the type of AST the initialization expression is, we may need an lvalue467 // Depending on the type of AST the initialization expression is, we may need an lvalue
...@@ -554,6 +557,26 @@ fn boolNot(mod: *Module, scope: *Scope, node: *ast.Node.SimplePrefixOp) InnerErr...@@ -554,6 +557,26 @@ fn boolNot(mod: *Module, scope: *Scope, node: *ast.Node.SimplePrefixOp) InnerErr
554 return addZIRUnOp(mod, scope, src, .boolnot, operand);557 return addZIRUnOp(mod, scope, src, .boolnot, operand);
555}558}
556559
560fn bitNot(mod: *Module, scope: *Scope, node: *ast.Node.SimplePrefixOp) InnerError!*zir.Inst {
561 const tree = scope.tree();
562 const src = tree.token_locs[node.op_token].start;
563 const operand = try expr(mod, scope, .none, node.rhs);
564 return addZIRUnOp(mod, scope, src, .bitnot, operand);
565}
566
567fn negation(mod: *Module, scope: *Scope, node: *ast.Node.SimplePrefixOp, op_inst_tag: zir.Inst.Tag) InnerError!*zir.Inst {
568 const tree = scope.tree();
569 const src = tree.token_locs[node.op_token].start;
570
571 const lhs = try addZIRInstConst(mod, scope, src, .{
572 .ty = Type.initTag(.comptime_int),
573 .val = Value.initTag(.zero),
574 });
575 const rhs = try expr(mod, scope, .none, node.rhs);
576
577 return addZIRBinOp(mod, scope, src, op_inst_tag, lhs, rhs);
578}
579
557fn addressOf(mod: *Module, scope: *Scope, node: *ast.Node.SimplePrefixOp) InnerError!*zir.Inst {580fn addressOf(mod: *Module, scope: *Scope, node: *ast.Node.SimplePrefixOp) InnerError!*zir.Inst {
558 return expr(mod, scope, .ref, node.rhs);581 return expr(mod, scope, .ref, node.rhs);
559}582}
...@@ -561,11 +584,7 @@ fn addressOf(mod: *Module, scope: *Scope, node: *ast.Node.SimplePrefixOp) InnerE...@@ -561,11 +584,7 @@ fn addressOf(mod: *Module, scope: *Scope, node: *ast.Node.SimplePrefixOp) InnerE
561fn optionalType(mod: *Module, scope: *Scope, node: *ast.Node.SimplePrefixOp) InnerError!*zir.Inst {584fn optionalType(mod: *Module, scope: *Scope, node: *ast.Node.SimplePrefixOp) InnerError!*zir.Inst {
562 const tree = scope.tree();585 const tree = scope.tree();
563 const src = tree.token_locs[node.op_token].start;586 const src = tree.token_locs[node.op_token].start;
564 const meta_type = try addZIRInstConst(mod, scope, src, .{587 const operand = try typeExpr(mod, scope, node.rhs);
565 .ty = Type.initTag(.type),
566 .val = Value.initTag(.type_type),
567 });
568 const operand = try expr(mod, scope, .{ .ty = meta_type }, node.rhs);
569 return addZIRUnOp(mod, scope, src, .optional_type, operand);588 return addZIRUnOp(mod, scope, src, .optional_type, operand);
570}589}
571590
...@@ -590,18 +609,13 @@ fn ptrType(mod: *Module, scope: *Scope, node: *ast.Node.PtrType) InnerError!*zir...@@ -590,18 +609,13 @@ fn ptrType(mod: *Module, scope: *Scope, node: *ast.Node.PtrType) InnerError!*zir
590}609}
591610
592fn ptrSliceType(mod: *Module, scope: *Scope, src: usize, ptr_info: *ast.PtrInfo, rhs: *ast.Node, size: std.builtin.TypeInfo.Pointer.Size) InnerError!*zir.Inst {611fn ptrSliceType(mod: *Module, scope: *Scope, src: usize, ptr_info: *ast.PtrInfo, rhs: *ast.Node, size: std.builtin.TypeInfo.Pointer.Size) InnerError!*zir.Inst {
593 const meta_type = try addZIRInstConst(mod, scope, src, .{
594 .ty = Type.initTag(.type),
595 .val = Value.initTag(.type_type),
596 });
597
598 const simple = ptr_info.allowzero_token == null and612 const simple = ptr_info.allowzero_token == null and
599 ptr_info.align_info == null and613 ptr_info.align_info == null and
600 ptr_info.volatile_token == null and614 ptr_info.volatile_token == null and
601 ptr_info.sentinel == null;615 ptr_info.sentinel == null;
602616
603 if (simple) {617 if (simple) {
604 const child_type = try expr(mod, scope, .{ .ty = meta_type }, rhs);618 const child_type = try typeExpr(mod, scope, rhs);
605 const mutable = ptr_info.const_token == null;619 const mutable = ptr_info.const_token == null;
606 // TODO stage1 type inference bug620 // TODO stage1 type inference bug
607 const T = zir.Inst.Tag;621 const T = zir.Inst.Tag;
...@@ -629,7 +643,7 @@ fn ptrSliceType(mod: *Module, scope: *Scope, src: usize, ptr_info: *ast.PtrInfo,...@@ -629,7 +643,7 @@ fn ptrSliceType(mod: *Module, scope: *Scope, src: usize, ptr_info: *ast.PtrInfo,
629 kw_args.sentinel = try expr(mod, scope, .none, some);643 kw_args.sentinel = try expr(mod, scope, .none, some);
630 }644 }
631645
632 const child_type = try expr(mod, scope, .{ .ty = meta_type }, rhs);646 const child_type = try typeExpr(mod, scope, rhs);
633 if (kw_args.sentinel) |some| {647 if (kw_args.sentinel) |some| {
634 kw_args.sentinel = try addZIRBinOp(mod, scope, some.src, .as, child_type, some);648 kw_args.sentinel = try addZIRBinOp(mod, scope, some.src, .as, child_type, some);
635 }649 }
...@@ -640,10 +654,6 @@ fn ptrSliceType(mod: *Module, scope: *Scope, src: usize, ptr_info: *ast.PtrInfo,...@@ -640,10 +654,6 @@ fn ptrSliceType(mod: *Module, scope: *Scope, src: usize, ptr_info: *ast.PtrInfo,
640fn arrayType(mod: *Module, scope: *Scope, node: *ast.Node.ArrayType) !*zir.Inst {654fn arrayType(mod: *Module, scope: *Scope, node: *ast.Node.ArrayType) !*zir.Inst {
641 const tree = scope.tree();655 const tree = scope.tree();
642 const src = tree.token_locs[node.op_token].start;656 const src = tree.token_locs[node.op_token].start;
643 const meta_type = try addZIRInstConst(mod, scope, src, .{
644 .ty = Type.initTag(.type),
645 .val = Value.initTag(.type_type),
646 });
647 const usize_type = try addZIRInstConst(mod, scope, src, .{657 const usize_type = try addZIRInstConst(mod, scope, src, .{
648 .ty = Type.initTag(.type),658 .ty = Type.initTag(.type),
649 .val = Value.initTag(.usize_type),659 .val = Value.initTag(.usize_type),
...@@ -651,18 +661,14 @@ fn arrayType(mod: *Module, scope: *Scope, node: *ast.Node.ArrayType) !*zir.Inst...@@ -651,18 +661,14 @@ fn arrayType(mod: *Module, scope: *Scope, node: *ast.Node.ArrayType) !*zir.Inst
651661
652 // TODO check for [_]T662 // TODO check for [_]T
653 const len = try expr(mod, scope, .{ .ty = usize_type }, node.len_expr);663 const len = try expr(mod, scope, .{ .ty = usize_type }, node.len_expr);
654 const child_type = try expr(mod, scope, .{ .ty = meta_type }, node.rhs);664 const elem_type = try typeExpr(mod, scope, node.rhs);
655665
656 return addZIRBinOp(mod, scope, src, .array_type, len, child_type);666 return addZIRBinOp(mod, scope, src, .array_type, len, elem_type);
657}667}
658668
659fn arrayTypeSentinel(mod: *Module, scope: *Scope, node: *ast.Node.ArrayTypeSentinel) !*zir.Inst {669fn arrayTypeSentinel(mod: *Module, scope: *Scope, node: *ast.Node.ArrayTypeSentinel) !*zir.Inst {
660 const tree = scope.tree();670 const tree = scope.tree();
661 const src = tree.token_locs[node.op_token].start;671 const src = tree.token_locs[node.op_token].start;
662 const meta_type = try addZIRInstConst(mod, scope, src, .{
663 .ty = Type.initTag(.type),
664 .val = Value.initTag(.type_type),
665 });
666 const usize_type = try addZIRInstConst(mod, scope, src, .{672 const usize_type = try addZIRInstConst(mod, scope, src, .{
667 .ty = Type.initTag(.type),673 .ty = Type.initTag(.type),
668 .val = Value.initTag(.usize_type),674 .val = Value.initTag(.usize_type),
...@@ -671,7 +677,7 @@ fn arrayTypeSentinel(mod: *Module, scope: *Scope, node: *ast.Node.ArrayTypeSenti...@@ -671,7 +677,7 @@ fn arrayTypeSentinel(mod: *Module, scope: *Scope, node: *ast.Node.ArrayTypeSenti
671 // TODO check for [_]T677 // TODO check for [_]T
672 const len = try expr(mod, scope, .{ .ty = usize_type }, node.len_expr);678 const len = try expr(mod, scope, .{ .ty = usize_type }, node.len_expr);
673 const sentinel_uncasted = try expr(mod, scope, .none, node.sentinel);679 const sentinel_uncasted = try expr(mod, scope, .none, node.sentinel);
674 const elem_type = try expr(mod, scope, .{ .ty = meta_type }, node.rhs);680 const elem_type = try typeExpr(mod, scope, node.rhs);
675 const sentinel = try addZIRBinOp(mod, scope, src, .as, elem_type, sentinel_uncasted);681 const sentinel = try addZIRBinOp(mod, scope, src, .as, elem_type, sentinel_uncasted);
676682
677 return addZIRInst(mod, scope, src, zir.Inst.ArrayTypeSentinel, .{683 return addZIRInst(mod, scope, src, zir.Inst.ArrayTypeSentinel, .{
...@@ -681,6 +687,28 @@ fn arrayTypeSentinel(mod: *Module, scope: *Scope, node: *ast.Node.ArrayTypeSenti...@@ -681,6 +687,28 @@ fn arrayTypeSentinel(mod: *Module, scope: *Scope, node: *ast.Node.ArrayTypeSenti
681 }, .{});687 }, .{});
682}688}
683689
690fn anyFrameType(mod: *Module, scope: *Scope, node: *ast.Node.AnyFrameType) InnerError!*zir.Inst {
691 const tree = scope.tree();
692 const src = tree.token_locs[node.anyframe_token].start;
693 if (node.result) |some| {
694 const return_type = try typeExpr(mod, scope, some.return_type);
695 return addZIRUnOp(mod, scope, src, .anyframe_type, return_type);
696 } else {
697 return addZIRInstConst(mod, scope, src, .{
698 .ty = Type.initTag(.type),
699 .val = Value.initTag(.anyframe_type),
700 });
701 }
702}
703
704fn typeInixOp(mod: *Module, scope: *Scope, node: *ast.Node.SimpleInfixOp, op_inst_tag: zir.Inst.Tag) InnerError!*zir.Inst {
705 const tree = scope.tree();
706 const src = tree.token_locs[node.op_token].start;
707 const error_set = try typeExpr(mod, scope, node.lhs);
708 const payload = try typeExpr(mod, scope, node.rhs);
709 return addZIRBinOp(mod, scope, src, op_inst_tag, error_set, payload);
710}
711
684fn enumLiteral(mod: *Module, scope: *Scope, node: *ast.Node.EnumLiteral) !*zir.Inst {712fn enumLiteral(mod: *Module, scope: *Scope, node: *ast.Node.EnumLiteral) !*zir.Inst {
685 const tree = scope.tree();713 const tree = scope.tree();
686 const src = tree.token_locs[node.name].start;714 const src = tree.token_locs[node.name].start;
...@@ -694,10 +722,31 @@ fn unwrapOptional(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.Si...@@ -694,10 +722,31 @@ fn unwrapOptional(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.Si
694 const src = tree.token_locs[node.rtoken].start;722 const src = tree.token_locs[node.rtoken].start;
695723
696 const operand = try expr(mod, scope, .ref, node.lhs);724 const operand = try expr(mod, scope, .ref, node.lhs);
697 const unwrapped_ptr = try addZIRUnOp(mod, scope, src, .unwrap_optional_safe, operand);725 return rlWrapPtr(mod, scope, rl, try addZIRUnOp(mod, scope, src, .unwrap_optional_safe, operand));
698 if (rl == .lvalue or rl == .ref) return unwrapped_ptr;726}
699727
700 return rlWrap(mod, scope, rl, try addZIRUnOp(mod, scope, src, .deref, unwrapped_ptr));728fn errorSetDecl(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.ErrorSetDecl) InnerError!*zir.Inst {
729 const tree = scope.tree();
730 const src = tree.token_locs[node.error_token].start;
731 const decls = node.decls();
732 const fields = try scope.arena().alloc([]const u8, decls.len);
733
734 for (decls) |decl, i| {
735 const tag = decl.castTag(.ErrorTag).?;
736 fields[i] = try identifierTokenString(mod, scope, tag.name_token);
737 }
738
739 // analyzing the error set results in a decl ref, so we might need to dereference it
740 return rlWrapPtr(mod, scope, rl, try addZIRInst(mod, scope, src, zir.Inst.ErrorSet, .{ .fields = fields }, .{}));
741}
742
743fn errorType(mod: *Module, scope: *Scope, node: *ast.Node.OneToken) InnerError!*zir.Inst {
744 const tree = scope.tree();
745 const src = tree.token_locs[node.token].start;
746 return addZIRInstConst(mod, scope, src, .{
747 .ty = Type.initTag(.type),
748 .val = Value.initTag(.anyerror_type),
749 });
701}750}
702751
703/// Return whether the identifier names of two tokens are equal. Resolves @"" tokens without allocating.752/// Return whether the identifier names of two tokens are equal. Resolves @"" tokens without allocating.
...@@ -737,16 +786,16 @@ pub fn identifierStringInst(mod: *Module, scope: *Scope, node: *ast.Node.OneToke...@@ -737,16 +786,16 @@ pub fn identifierStringInst(mod: *Module, scope: *Scope, node: *ast.Node.OneToke
737 return addZIRInst(mod, scope, src, zir.Inst.Str, .{ .bytes = ident_name }, .{});786 return addZIRInst(mod, scope, src, zir.Inst.Str, .{ .bytes = ident_name }, .{});
738}787}
739788
740fn field(mod: *Module, scope: *Scope, node: *ast.Node.SimpleInfixOp) InnerError!*zir.Inst {789fn field(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.SimpleInfixOp) InnerError!*zir.Inst {
741 // TODO introduce lvalues
742 const tree = scope.tree();790 const tree = scope.tree();
743 const src = tree.token_locs[node.op_token].start;791 const src = tree.token_locs[node.op_token].start;
744792
745 const lhs = try expr(mod, scope, .none, node.lhs);793 const lhs = try expr(mod, scope, .ref, node.lhs);
746 const field_name = try identifierStringInst(mod, scope, node.rhs.castTag(.Identifier).?);794 const field_name = try identifierStringInst(mod, scope, node.rhs.castTag(.Identifier).?);
747795
748 const pointer = try addZIRInst(mod, scope, src, zir.Inst.FieldPtr, .{ .object_ptr = lhs, .field_name = field_name }, .{});796 const pointer = try addZIRInst(mod, scope, src, zir.Inst.FieldPtr, .{ .object_ptr = lhs, .field_name = field_name }, .{});
749 return addZIRUnOp(mod, scope, src, .deref, pointer);797 if (rl == .ref or rl == .lvalue) return pointer;
798 return rlWrap(mod, scope, rl, try addZIRUnOp(mod, scope, src, .deref, pointer));
750}799}
751800
752fn deref(mod: *Module, scope: *Scope, node: *ast.Node.SimpleSuffixOp) InnerError!*zir.Inst {801fn deref(mod: *Module, scope: *Scope, node: *ast.Node.SimpleSuffixOp) InnerError!*zir.Inst {
...@@ -1232,12 +1281,7 @@ fn identifier(mod: *Module, scope: *Scope, rl: ResultLoc, ident: *ast.Node.OneTo...@@ -1232,12 +1281,7 @@ fn identifier(mod: *Module, scope: *Scope, rl: ResultLoc, ident: *ast.Node.OneTo
1232 .local_ptr => {1281 .local_ptr => {
1233 const local_ptr = s.cast(Scope.LocalPtr).?;1282 const local_ptr = s.cast(Scope.LocalPtr).?;
1234 if (mem.eql(u8, local_ptr.name, ident_name)) {1283 if (mem.eql(u8, local_ptr.name, ident_name)) {
1235 if (rl == .lvalue or rl == .ref) {1284 return rlWrapPtr(mod, scope, rl, local_ptr.ptr);
1236 return local_ptr.ptr;
1237 } else {
1238 const result = try addZIRUnOp(mod, scope, src, .deref, local_ptr.ptr);
1239 return rlWrap(mod, scope, rl, result);
1240 }
1241 }1285 }
1242 s = local_ptr.parent;1286 s = local_ptr.parent;
1243 },1287 },
...@@ -1247,10 +1291,7 @@ fn identifier(mod: *Module, scope: *Scope, rl: ResultLoc, ident: *ast.Node.OneTo...@@ -1247,10 +1291,7 @@ fn identifier(mod: *Module, scope: *Scope, rl: ResultLoc, ident: *ast.Node.OneTo
1247 }1291 }
12481292
1249 if (mod.lookupDeclName(scope, ident_name)) |decl| {1293 if (mod.lookupDeclName(scope, ident_name)) |decl| {
1250 const result = try addZIRInst(mod, scope, src, zir.Inst.DeclValInModule, .{ .decl = decl }, .{});1294 return rlWrapPtr(mod, scope, rl, try addZIRInst(mod, scope, src, zir.Inst.DeclValInModule, .{ .decl = decl }, .{}));
1251 if (rl == .lvalue or rl == .ref)
1252 return result;
1253 return rlWrap(mod, scope, rl, try addZIRUnOp(mod, scope, src, .deref, result));
1254 }1295 }
12551296
1256 return mod.failNode(scope, &ident.base, "use of undeclared identifier '{}'", .{ident_name});1297 return mod.failNode(scope, &ident.base, "use of undeclared identifier '{}'", .{ident_name});
...@@ -1466,12 +1507,8 @@ fn simpleCast(...@@ -1466,12 +1507,8 @@ fn simpleCast(
1466 try ensureBuiltinParamCount(mod, scope, call, 2);1507 try ensureBuiltinParamCount(mod, scope, call, 2);
1467 const tree = scope.tree();1508 const tree = scope.tree();
1468 const src = tree.token_locs[call.builtin_token].start;1509 const src = tree.token_locs[call.builtin_token].start;
1469 const type_type = try addZIRInstConst(mod, scope, src, .{
1470 .ty = Type.initTag(.type),
1471 .val = Value.initTag(.type_type),
1472 });
1473 const params = call.params();1510 const params = call.params();
1474 const dest_type = try expr(mod, scope, .{ .ty = type_type }, params[0]);1511 const dest_type = try typeExpr(mod, scope, params[0]);
1475 const rhs = try expr(mod, scope, .none, params[1]);1512 const rhs = try expr(mod, scope, .none, params[1]);
1476 const result = try addZIRBinOp(mod, scope, src, inst_tag, dest_type, rhs);1513 const result = try addZIRBinOp(mod, scope, src, inst_tag, dest_type, rhs);
1477 return rlWrap(mod, scope, rl, result);1514 return rlWrap(mod, scope, rl, result);
...@@ -1533,12 +1570,8 @@ fn bitCast(mod: *Module, scope: *Scope, rl: ResultLoc, call: *ast.Node.BuiltinCa...@@ -1533,12 +1570,8 @@ fn bitCast(mod: *Module, scope: *Scope, rl: ResultLoc, call: *ast.Node.BuiltinCa
1533 try ensureBuiltinParamCount(mod, scope, call, 2);1570 try ensureBuiltinParamCount(mod, scope, call, 2);
1534 const tree = scope.tree();1571 const tree = scope.tree();
1535 const src = tree.token_locs[call.builtin_token].start;1572 const src = tree.token_locs[call.builtin_token].start;
1536 const type_type = try addZIRInstConst(mod, scope, src, .{
1537 .ty = Type.initTag(.type),
1538 .val = Value.initTag(.type_type),
1539 });
1540 const params = call.params();1573 const params = call.params();
1541 const dest_type = try expr(mod, scope, .{ .ty = type_type }, params[0]);1574 const dest_type = try typeExpr(mod, scope, params[0]);
1542 switch (rl) {1575 switch (rl) {
1543 .none => {1576 .none => {
1544 const operand = try expr(mod, scope, .none, params[1]);1577 const operand = try expr(mod, scope, .none, params[1]);
...@@ -1852,6 +1885,12 @@ fn rlWrapVoid(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node, resul...@@ -1852,6 +1885,12 @@ fn rlWrapVoid(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node, resul
1852 return rlWrap(mod, scope, rl, void_inst);1885 return rlWrap(mod, scope, rl, void_inst);
1853}1886}
18541887
1888fn rlWrapPtr(mod: *Module, scope: *Scope, rl: ResultLoc, ptr: *zir.Inst) InnerError!*zir.Inst {
1889 if (rl == .lvalue or rl == .ref) return ptr;
1890
1891 return rlWrap(mod, scope, rl, try addZIRUnOp(mod, scope, ptr.src, .deref, ptr));
1892}
1893
1855pub fn addZIRInstSpecial(1894pub fn addZIRInstSpecial(
1856 mod: *Module,1895 mod: *Module,
1857 scope: *Scope,1896 scope: *Scope,
src-self-hosted/type.zig+250-7
...@@ -3,6 +3,7 @@ const Value = @import("value.zig").Value;...@@ -3,6 +3,7 @@ const Value = @import("value.zig").Value;
3const assert = std.debug.assert;3const assert = std.debug.assert;
4const Allocator = std.mem.Allocator;4const Allocator = std.mem.Allocator;
5const Target = std.Target;5const Target = std.Target;
6const Module = @import("Module.zig");
67
7/// This is the raw data, with no bookkeeping, no memory awareness, no de-duplication.8/// This is the raw data, with no bookkeeping, no memory awareness, no de-duplication.
8/// It's important for this type to be small.9/// It's important for this type to be small.
...@@ -52,7 +53,7 @@ pub const Type = extern union {...@@ -52,7 +53,7 @@ pub const Type = extern union {
52 .bool => return .Bool,53 .bool => return .Bool,
53 .void => return .Void,54 .void => return .Void,
54 .type => return .Type,55 .type => return .Type,
55 .anyerror => return .ErrorSet,56 .error_set, .error_set_single, .anyerror => return .ErrorSet,
56 .comptime_int => return .ComptimeInt,57 .comptime_int => return .ComptimeInt,
57 .comptime_float => return .ComptimeFloat,58 .comptime_float => return .ComptimeFloat,
58 .noreturn => return .NoReturn,59 .noreturn => return .NoReturn,
...@@ -84,6 +85,10 @@ pub const Type = extern union {...@@ -84,6 +85,10 @@ pub const Type = extern union {
84 .optional_single_mut_pointer,85 .optional_single_mut_pointer,
85 => return .Optional,86 => return .Optional,
86 .enum_literal => return .EnumLiteral,87 .enum_literal => return .EnumLiteral,
88
89 .anyerror_void_error_union, .error_union => return .ErrorUnion,
90
91 .anyframe_T, .@"anyframe" => return .AnyFrame,
87 }92 }
88 }93 }
8994
...@@ -151,6 +156,9 @@ pub const Type = extern union {...@@ -151,6 +156,9 @@ pub const Type = extern union {
151 .ComptimeInt => return true,156 .ComptimeInt => return true,
152 .Undefined => return true,157 .Undefined => return true,
153 .Null => return true,158 .Null => return true,
159 .AnyFrame => {
160 return a.elemType().eql(b.elemType());
161 },
154 .Pointer => {162 .Pointer => {
155 // Hot path for common case:163 // Hot path for common case:
156 if (a.castPointer()) |a_payload| {164 if (a.castPointer()) |a_payload| {
...@@ -225,7 +233,6 @@ pub const Type = extern union {...@@ -225,7 +233,6 @@ pub const Type = extern union {
225 .BoundFn,233 .BoundFn,
226 .Opaque,234 .Opaque,
227 .Frame,235 .Frame,
228 .AnyFrame,
229 .Vector,236 .Vector,
230 => std.debug.panic("TODO implement Type equality comparison of {} and {}", .{ a, b }),237 => std.debug.panic("TODO implement Type equality comparison of {} and {}", .{ a, b }),
231 }238 }
...@@ -343,6 +350,8 @@ pub const Type = extern union {...@@ -343,6 +350,8 @@ pub const Type = extern union {
343 .single_const_pointer_to_comptime_int,350 .single_const_pointer_to_comptime_int,
344 .const_slice_u8,351 .const_slice_u8,
345 .enum_literal,352 .enum_literal,
353 .anyerror_void_error_union,
354 .@"anyframe",
346 => unreachable,355 => unreachable,
347356
348 .array_u8_sentinel_0 => return self.copyPayloadShallow(allocator, Payload.Array_u8_Sentinel0),357 .array_u8_sentinel_0 => return self.copyPayloadShallow(allocator, Payload.Array_u8_Sentinel0),
...@@ -397,6 +406,7 @@ pub const Type = extern union {...@@ -397,6 +406,7 @@ pub const Type = extern union {
397 .optional_single_mut_pointer,406 .optional_single_mut_pointer,
398 .optional_single_const_pointer,407 .optional_single_const_pointer,
399 => return self.copyPayloadSingleField(allocator, Payload.PointerSimple, "pointee_type"),408 => return self.copyPayloadSingleField(allocator, Payload.PointerSimple, "pointee_type"),
409 .anyframe_T => return self.copyPayloadSingleField(allocator, Payload.AnyFrame, "return_type"),
400410
401 .pointer => {411 .pointer => {
402 const payload = @fieldParentPtr(Payload.Pointer, "base", self.ptr_otherwise);412 const payload = @fieldParentPtr(Payload.Pointer, "base", self.ptr_otherwise);
...@@ -416,6 +426,19 @@ pub const Type = extern union {...@@ -416,6 +426,19 @@ pub const Type = extern union {
416 };426 };
417 return Type{ .ptr_otherwise = &new_payload.base };427 return Type{ .ptr_otherwise = &new_payload.base };
418 },428 },
429 .error_union => {
430 const payload = @fieldParentPtr(Payload.ErrorUnion, "base", self.ptr_otherwise);
431 const new_payload = try allocator.create(Payload.ErrorUnion);
432 new_payload.* = .{
433 .base = payload.base,
434
435 .error_set = try payload.error_set.copy(allocator),
436 .payload = try payload.payload.copy(allocator),
437 };
438 return Type{ .ptr_otherwise = &new_payload.base };
439 },
440 .error_set => return self.copyPayloadShallow(allocator, Payload.ErrorSet),
441 .error_set_single => return self.copyPayloadShallow(allocator, Payload.ErrorSetSingle),
419 }442 }
420 }443 }
421444
...@@ -482,6 +505,8 @@ pub const Type = extern union {...@@ -482,6 +505,8 @@ pub const Type = extern union {
482 .@"null" => return out_stream.writeAll("@TypeOf(null)"),505 .@"null" => return out_stream.writeAll("@TypeOf(null)"),
483 .@"undefined" => return out_stream.writeAll("@TypeOf(undefined)"),506 .@"undefined" => return out_stream.writeAll("@TypeOf(undefined)"),
484507
508 .@"anyframe" => return out_stream.writeAll("anyframe"),
509 .anyerror_void_error_union => return out_stream.writeAll("anyerror!void"),
485 .const_slice_u8 => return out_stream.writeAll("[]const u8"),510 .const_slice_u8 => return out_stream.writeAll("[]const u8"),
486 .fn_noreturn_no_args => return out_stream.writeAll("fn() noreturn"),511 .fn_noreturn_no_args => return out_stream.writeAll("fn() noreturn"),
487 .fn_void_no_args => return out_stream.writeAll("fn() void"),512 .fn_void_no_args => return out_stream.writeAll("fn() void"),
...@@ -500,6 +525,12 @@ pub const Type = extern union {...@@ -500,6 +525,12 @@ pub const Type = extern union {
500 continue;525 continue;
501 },526 },
502527
528 .anyframe_T => {
529 const payload = @fieldParentPtr(Payload.AnyFrame, "base", ty.ptr_otherwise);
530 try out_stream.print("anyframe->", .{});
531 ty = payload.return_type;
532 continue;
533 },
503 .array_u8 => {534 .array_u8 => {
504 const payload = @fieldParentPtr(Payload.Array_u8, "base", ty.ptr_otherwise);535 const payload = @fieldParentPtr(Payload.Array_u8, "base", ty.ptr_otherwise);
505 return out_stream.print("[{}]u8", .{payload.len});536 return out_stream.print("[{}]u8", .{payload.len});
...@@ -622,6 +653,21 @@ pub const Type = extern union {...@@ -622,6 +653,21 @@ pub const Type = extern union {
622 ty = payload.pointee_type;653 ty = payload.pointee_type;
623 continue;654 continue;
624 },655 },
656 .error_union => {
657 const payload = @fieldParentPtr(Payload.ErrorUnion, "base", ty.ptr_otherwise);
658 try payload.error_set.format("", .{}, out_stream);
659 try out_stream.writeAll("!");
660 ty = payload.payload;
661 continue;
662 },
663 .error_set => {
664 const payload = @fieldParentPtr(Payload.ErrorSet, "base", ty.ptr_otherwise);
665 return out_stream.writeAll(std.mem.spanZ(payload.decl.name));
666 },
667 .error_set_single => {
668 const payload = @fieldParentPtr(Payload.ErrorSetSingle, "base", ty.ptr_otherwise);
669 return out_stream.print("error{{{}}}", .{payload.name});
670 },
625 }671 }
626 unreachable;672 unreachable;
627 }673 }
...@@ -715,6 +761,11 @@ pub const Type = extern union {...@@ -715,6 +761,11 @@ pub const Type = extern union {
715 .optional,761 .optional,
716 .optional_single_mut_pointer,762 .optional_single_mut_pointer,
717 .optional_single_const_pointer,763 .optional_single_const_pointer,
764 .@"anyframe",
765 .anyframe_T,
766 .anyerror_void_error_union,
767 .error_set,
768 .error_set_single,
718 => true,769 => true,
719 // TODO lazy types770 // TODO lazy types
720 .array => self.elemType().hasCodeGenBits() and self.arrayLen() != 0,771 .array => self.elemType().hasCodeGenBits() and self.arrayLen() != 0,
...@@ -723,6 +774,11 @@ pub const Type = extern union {...@@ -723,6 +774,11 @@ pub const Type = extern union {
723 .int_signed => self.cast(Payload.IntSigned).?.bits == 0,774 .int_signed => self.cast(Payload.IntSigned).?.bits == 0,
724 .int_unsigned => self.cast(Payload.IntUnsigned).?.bits == 0,775 .int_unsigned => self.cast(Payload.IntUnsigned).?.bits == 0,
725776
777 .error_union => {
778 const payload = self.cast(Payload.ErrorUnion).?;
779 return payload.error_set.hasCodeGenBits() or payload.payload.hasCodeGenBits();
780 },
781
726 .c_void,782 .c_void,
727 .void,783 .void,
728 .type,784 .type,
...@@ -779,6 +835,8 @@ pub const Type = extern union {...@@ -779,6 +835,8 @@ pub const Type = extern union {
779 .mut_slice,835 .mut_slice,
780 .optional_single_const_pointer,836 .optional_single_const_pointer,
781 .optional_single_mut_pointer,837 .optional_single_mut_pointer,
838 .@"anyframe",
839 .anyframe_T,
782 => return @divExact(target.cpu.arch.ptrBitWidth(), 8),840 => return @divExact(target.cpu.arch.ptrBitWidth(), 8),
783841
784 .pointer => {842 .pointer => {
...@@ -803,7 +861,11 @@ pub const Type = extern union {...@@ -803,7 +861,11 @@ pub const Type = extern union {
803 .f128 => return 16,861 .f128 => return 16,
804 .c_longdouble => return 16,862 .c_longdouble => return 16,
805863
806 .anyerror => return 2, // TODO revisit this when we have the concept of the error tag type864 .error_set,
865 .error_set_single,
866 .anyerror_void_error_union,
867 .anyerror,
868 => return 2, // TODO revisit this when we have the concept of the error tag type
807869
808 .array, .array_sentinel => return self.elemType().abiAlignment(target),870 .array, .array_sentinel => return self.elemType().abiAlignment(target),
809871
...@@ -829,6 +891,16 @@ pub const Type = extern union {...@@ -829,6 +891,16 @@ pub const Type = extern union {
829 return child_type.abiAlignment(target);891 return child_type.abiAlignment(target);
830 },892 },
831893
894 .error_union => {
895 const payload = self.cast(Payload.ErrorUnion).?;
896 if (!payload.error_set.hasCodeGenBits()) {
897 return payload.payload.abiAlignment(target);
898 } else if (!payload.payload.hasCodeGenBits()) {
899 return payload.error_set.abiAlignment(target);
900 }
901 @panic("TODO abiAlignment error union");
902 },
903
832 .c_void,904 .c_void,
833 .void,905 .void,
834 .type,906 .type,
...@@ -882,12 +954,15 @@ pub const Type = extern union {...@@ -882,12 +954,15 @@ pub const Type = extern union {
882 .i32, .u32 => return 4,954 .i32, .u32 => return 4,
883 .i64, .u64 => return 8,955 .i64, .u64 => return 8,
884956
885 .isize, .usize => return @divExact(target.cpu.arch.ptrBitWidth(), 8),957 .@"anyframe", .anyframe_T, .isize, .usize => return @divExact(target.cpu.arch.ptrBitWidth(), 8),
886958
887 .const_slice,959 .const_slice,
888 .mut_slice,960 .mut_slice,
889 .const_slice_u8,961 => {
890 => return @divExact(target.cpu.arch.ptrBitWidth(), 8) * 2,962 if (self.elemType().hasCodeGenBits()) return @divExact(target.cpu.arch.ptrBitWidth(), 8) * 2;
963 return @divExact(target.cpu.arch.ptrBitWidth(), 8);
964 },
965 .const_slice_u8 => return @divExact(target.cpu.arch.ptrBitWidth(), 8) * 2,
891966
892 .optional_single_const_pointer,967 .optional_single_const_pointer,
893 .optional_single_mut_pointer,968 .optional_single_mut_pointer,
...@@ -923,7 +998,11 @@ pub const Type = extern union {...@@ -923,7 +998,11 @@ pub const Type = extern union {
923 .f128 => return 16,998 .f128 => return 16,
924 .c_longdouble => return 16,999 .c_longdouble => return 16,
9251000
926 .anyerror => return 2, // TODO revisit this when we have the concept of the error tag type1001 .error_set,
1002 .error_set_single,
1003 .anyerror_void_error_union,
1004 .anyerror,
1005 => return 2, // TODO revisit this when we have the concept of the error tag type
9271006
928 .int_signed, .int_unsigned => {1007 .int_signed, .int_unsigned => {
929 const bits: u16 = if (self.cast(Payload.IntSigned)) |pl|1008 const bits: u16 = if (self.cast(Payload.IntSigned)) |pl|
...@@ -950,6 +1029,18 @@ pub const Type = extern union {...@@ -950,6 +1029,18 @@ pub const Type = extern union {
950 // to the child type's ABI alignment.1029 // to the child type's ABI alignment.
951 return child_type.abiAlignment(target) + child_type.abiSize(target);1030 return child_type.abiAlignment(target) + child_type.abiSize(target);
952 },1031 },
1032
1033 .error_union => {
1034 const payload = self.cast(Payload.ErrorUnion).?;
1035 if (!payload.error_set.hasCodeGenBits() and !payload.payload.hasCodeGenBits()) {
1036 return 0;
1037 } else if (!payload.error_set.hasCodeGenBits()) {
1038 return payload.payload.abiSize(target);
1039 } else if (!payload.payload.hasCodeGenBits()) {
1040 return payload.error_set.abiSize(target);
1041 }
1042 @panic("TODO abiSize error union");
1043 },
953 };1044 };
954 }1045 }
9551046
...@@ -1010,6 +1101,12 @@ pub const Type = extern union {...@@ -1010,6 +1101,12 @@ pub const Type = extern union {
1010 .c_mut_pointer,1101 .c_mut_pointer,
1011 .const_slice,1102 .const_slice,
1012 .mut_slice,1103 .mut_slice,
1104 .error_union,
1105 .@"anyframe",
1106 .anyframe_T,
1107 .anyerror_void_error_union,
1108 .error_set,
1109 .error_set_single,
1013 => false,1110 => false,
10141111
1015 .single_const_pointer,1112 .single_const_pointer,
...@@ -1078,6 +1175,12 @@ pub const Type = extern union {...@@ -1078,6 +1175,12 @@ pub const Type = extern union {
1078 .optional_single_mut_pointer,1175 .optional_single_mut_pointer,
1079 .optional_single_const_pointer,1176 .optional_single_const_pointer,
1080 .enum_literal,1177 .enum_literal,
1178 .error_union,
1179 .@"anyframe",
1180 .anyframe_T,
1181 .anyerror_void_error_union,
1182 .error_set,
1183 .error_set_single,
1081 => false,1184 => false,
10821185
1083 .const_slice,1186 .const_slice,
...@@ -1143,6 +1246,12 @@ pub const Type = extern union {...@@ -1143,6 +1246,12 @@ pub const Type = extern union {
1143 .optional_single_const_pointer,1246 .optional_single_const_pointer,
1144 .enum_literal,1247 .enum_literal,
1145 .mut_slice,1248 .mut_slice,
1249 .error_union,
1250 .@"anyframe",
1251 .anyframe_T,
1252 .anyerror_void_error_union,
1253 .error_set,
1254 .error_set_single,
1146 => false,1255 => false,
11471256
1148 .single_const_pointer,1257 .single_const_pointer,
...@@ -1217,6 +1326,12 @@ pub const Type = extern union {...@@ -1217,6 +1326,12 @@ pub const Type = extern union {
1217 .optional_single_mut_pointer,1326 .optional_single_mut_pointer,
1218 .optional_single_const_pointer,1327 .optional_single_const_pointer,
1219 .enum_literal,1328 .enum_literal,
1329 .error_union,
1330 .@"anyframe",
1331 .anyframe_T,
1332 .anyerror_void_error_union,
1333 .error_set,
1334 .error_set_single,
1220 => false,1335 => false,
12211336
1222 .pointer => {1337 .pointer => {
...@@ -1328,6 +1443,12 @@ pub const Type = extern union {...@@ -1328,6 +1443,12 @@ pub const Type = extern union {
1328 .optional_single_const_pointer,1443 .optional_single_const_pointer,
1329 .optional_single_mut_pointer,1444 .optional_single_mut_pointer,
1330 .enum_literal,1445 .enum_literal,
1446 .error_union,
1447 .@"anyframe",
1448 .anyframe_T,
1449 .anyerror_void_error_union,
1450 .error_set,
1451 .error_set_single,
1331 => unreachable,1452 => unreachable,
13321453
1333 .array => self.cast(Payload.Array).?.elem_type,1454 .array => self.cast(Payload.Array).?.elem_type,
...@@ -1449,6 +1570,12 @@ pub const Type = extern union {...@@ -1449,6 +1570,12 @@ pub const Type = extern union {
1449 .optional_single_mut_pointer,1570 .optional_single_mut_pointer,
1450 .optional_single_const_pointer,1571 .optional_single_const_pointer,
1451 .enum_literal,1572 .enum_literal,
1573 .error_union,
1574 .@"anyframe",
1575 .anyframe_T,
1576 .anyerror_void_error_union,
1577 .error_set,
1578 .error_set_single,
1452 => unreachable,1579 => unreachable,
14531580
1454 .array => self.cast(Payload.Array).?.len,1581 .array => self.cast(Payload.Array).?.len,
...@@ -1516,6 +1643,12 @@ pub const Type = extern union {...@@ -1516,6 +1643,12 @@ pub const Type = extern union {
1516 .optional_single_mut_pointer,1643 .optional_single_mut_pointer,
1517 .optional_single_const_pointer,1644 .optional_single_const_pointer,
1518 .enum_literal,1645 .enum_literal,
1646 .error_union,
1647 .@"anyframe",
1648 .anyframe_T,
1649 .anyerror_void_error_union,
1650 .error_set,
1651 .error_set_single,
1519 => unreachable,1652 => unreachable,
15201653
1521 .array, .array_u8 => return null,1654 .array, .array_u8 => return null,
...@@ -1581,6 +1714,12 @@ pub const Type = extern union {...@@ -1581,6 +1714,12 @@ pub const Type = extern union {
1581 .optional_single_mut_pointer,1714 .optional_single_mut_pointer,
1582 .optional_single_const_pointer,1715 .optional_single_const_pointer,
1583 .enum_literal,1716 .enum_literal,
1717 .error_union,
1718 .@"anyframe",
1719 .anyframe_T,
1720 .anyerror_void_error_union,
1721 .error_set,
1722 .error_set_single,
1584 => false,1723 => false,
15851724
1586 .int_signed,1725 .int_signed,
...@@ -1649,6 +1788,12 @@ pub const Type = extern union {...@@ -1649,6 +1788,12 @@ pub const Type = extern union {
1649 .optional_single_mut_pointer,1788 .optional_single_mut_pointer,
1650 .optional_single_const_pointer,1789 .optional_single_const_pointer,
1651 .enum_literal,1790 .enum_literal,
1791 .error_union,
1792 .@"anyframe",
1793 .anyframe_T,
1794 .anyerror_void_error_union,
1795 .error_set,
1796 .error_set_single,
1652 => false,1797 => false,
16531798
1654 .int_unsigned,1799 .int_unsigned,
...@@ -1707,6 +1852,12 @@ pub const Type = extern union {...@@ -1707,6 +1852,12 @@ pub const Type = extern union {
1707 .optional_single_mut_pointer,1852 .optional_single_mut_pointer,
1708 .optional_single_const_pointer,1853 .optional_single_const_pointer,
1709 .enum_literal,1854 .enum_literal,
1855 .error_union,
1856 .@"anyframe",
1857 .anyframe_T,
1858 .anyerror_void_error_union,
1859 .error_set,
1860 .error_set_single,
1710 => unreachable,1861 => unreachable,
17111862
1712 .int_unsigned => .{ .signed = false, .bits = self.cast(Payload.IntUnsigned).?.bits },1863 .int_unsigned => .{ .signed = false, .bits = self.cast(Payload.IntUnsigned).?.bits },
...@@ -1783,6 +1934,12 @@ pub const Type = extern union {...@@ -1783,6 +1934,12 @@ pub const Type = extern union {
1783 .optional_single_mut_pointer,1934 .optional_single_mut_pointer,
1784 .optional_single_const_pointer,1935 .optional_single_const_pointer,
1785 .enum_literal,1936 .enum_literal,
1937 .error_union,
1938 .@"anyframe",
1939 .anyframe_T,
1940 .anyerror_void_error_union,
1941 .error_set,
1942 .error_set_single,
1786 => false,1943 => false,
17871944
1788 .usize,1945 .usize,
...@@ -1888,6 +2045,12 @@ pub const Type = extern union {...@@ -1888,6 +2045,12 @@ pub const Type = extern union {
1888 .optional_single_mut_pointer,2045 .optional_single_mut_pointer,
1889 .optional_single_const_pointer,2046 .optional_single_const_pointer,
1890 .enum_literal,2047 .enum_literal,
2048 .error_union,
2049 .@"anyframe",
2050 .anyframe_T,
2051 .anyerror_void_error_union,
2052 .error_set,
2053 .error_set_single,
1891 => unreachable,2054 => unreachable,
1892 };2055 };
1893 }2056 }
...@@ -1959,6 +2122,12 @@ pub const Type = extern union {...@@ -1959,6 +2122,12 @@ pub const Type = extern union {
1959 .optional_single_mut_pointer,2122 .optional_single_mut_pointer,
1960 .optional_single_const_pointer,2123 .optional_single_const_pointer,
1961 .enum_literal,2124 .enum_literal,
2125 .error_union,
2126 .@"anyframe",
2127 .anyframe_T,
2128 .anyerror_void_error_union,
2129 .error_set,
2130 .error_set_single,
1962 => unreachable,2131 => unreachable,
1963 }2132 }
1964 }2133 }
...@@ -2029,6 +2198,12 @@ pub const Type = extern union {...@@ -2029,6 +2198,12 @@ pub const Type = extern union {
2029 .optional_single_mut_pointer,2198 .optional_single_mut_pointer,
2030 .optional_single_const_pointer,2199 .optional_single_const_pointer,
2031 .enum_literal,2200 .enum_literal,
2201 .error_union,
2202 .@"anyframe",
2203 .anyframe_T,
2204 .anyerror_void_error_union,
2205 .error_set,
2206 .error_set_single,
2032 => unreachable,2207 => unreachable,
2033 }2208 }
2034 }2209 }
...@@ -2099,6 +2274,12 @@ pub const Type = extern union {...@@ -2099,6 +2274,12 @@ pub const Type = extern union {
2099 .optional_single_mut_pointer,2274 .optional_single_mut_pointer,
2100 .optional_single_const_pointer,2275 .optional_single_const_pointer,
2101 .enum_literal,2276 .enum_literal,
2277 .error_union,
2278 .@"anyframe",
2279 .anyframe_T,
2280 .anyerror_void_error_union,
2281 .error_set,
2282 .error_set_single,
2102 => unreachable,2283 => unreachable,
2103 };2284 };
2104 }2285 }
...@@ -2166,6 +2347,12 @@ pub const Type = extern union {...@@ -2166,6 +2347,12 @@ pub const Type = extern union {
2166 .optional_single_mut_pointer,2347 .optional_single_mut_pointer,
2167 .optional_single_const_pointer,2348 .optional_single_const_pointer,
2168 .enum_literal,2349 .enum_literal,
2350 .error_union,
2351 .@"anyframe",
2352 .anyframe_T,
2353 .anyerror_void_error_union,
2354 .error_set,
2355 .error_set_single,
2169 => unreachable,2356 => unreachable,
2170 };2357 };
2171 }2358 }
...@@ -2233,6 +2420,12 @@ pub const Type = extern union {...@@ -2233,6 +2420,12 @@ pub const Type = extern union {
2233 .optional_single_mut_pointer,2420 .optional_single_mut_pointer,
2234 .optional_single_const_pointer,2421 .optional_single_const_pointer,
2235 .enum_literal,2422 .enum_literal,
2423 .error_union,
2424 .@"anyframe",
2425 .anyframe_T,
2426 .anyerror_void_error_union,
2427 .error_set,
2428 .error_set_single,
2236 => unreachable,2429 => unreachable,
2237 };2430 };
2238 }2431 }
...@@ -2300,6 +2493,12 @@ pub const Type = extern union {...@@ -2300,6 +2493,12 @@ pub const Type = extern union {
2300 .optional_single_mut_pointer,2493 .optional_single_mut_pointer,
2301 .optional_single_const_pointer,2494 .optional_single_const_pointer,
2302 .enum_literal,2495 .enum_literal,
2496 .error_union,
2497 .@"anyframe",
2498 .anyframe_T,
2499 .anyerror_void_error_union,
2500 .error_set,
2501 .error_set_single,
2303 => false,2502 => false,
2304 };2503 };
2305 }2504 }
...@@ -2351,6 +2550,12 @@ pub const Type = extern union {...@@ -2351,6 +2550,12 @@ pub const Type = extern union {
2351 .optional_single_mut_pointer,2550 .optional_single_mut_pointer,
2352 .optional_single_const_pointer,2551 .optional_single_const_pointer,
2353 .enum_literal,2552 .enum_literal,
2553 .anyerror_void_error_union,
2554 .anyframe_T,
2555 .@"anyframe",
2556 .error_union,
2557 .error_set,
2558 .error_set_single,
2354 => return null,2559 => return null,
23552560
2356 .void => return Value.initTag(.void_value),2561 .void => return Value.initTag(.void_value),
...@@ -2454,6 +2659,12 @@ pub const Type = extern union {...@@ -2454,6 +2659,12 @@ pub const Type = extern union {
2454 .optional_single_mut_pointer,2659 .optional_single_mut_pointer,
2455 .optional_single_const_pointer,2660 .optional_single_const_pointer,
2456 .enum_literal,2661 .enum_literal,
2662 .error_union,
2663 .@"anyframe",
2664 .anyframe_T,
2665 .anyerror_void_error_union,
2666 .error_set,
2667 .error_set_single,
2457 => return false,2668 => return false,
24582669
2459 .c_const_pointer,2670 .c_const_pointer,
...@@ -2511,6 +2722,8 @@ pub const Type = extern union {...@@ -2511,6 +2722,8 @@ pub const Type = extern union {
2511 fn_naked_noreturn_no_args,2722 fn_naked_noreturn_no_args,
2512 fn_ccc_void_no_args,2723 fn_ccc_void_no_args,
2513 single_const_pointer_to_comptime_int,2724 single_const_pointer_to_comptime_int,
2725 anyerror_void_error_union,
2726 @"anyframe",
2514 const_slice_u8, // See last_no_payload_tag below.2727 const_slice_u8, // See last_no_payload_tag below.
2515 // After this, the tag requires a payload.2728 // After this, the tag requires a payload.
25162729
...@@ -2533,6 +2746,10 @@ pub const Type = extern union {...@@ -2533,6 +2746,10 @@ pub const Type = extern union {
2533 optional,2746 optional,
2534 optional_single_mut_pointer,2747 optional_single_mut_pointer,
2535 optional_single_const_pointer,2748 optional_single_const_pointer,
2749 error_union,
2750 anyframe_T,
2751 error_set,
2752 error_set_single,
25362753
2537 pub const last_no_payload_tag = Tag.const_slice_u8;2754 pub const last_no_payload_tag = Tag.const_slice_u8;
2538 pub const no_payload_count = @enumToInt(last_no_payload_tag) + 1;2755 pub const no_payload_count = @enumToInt(last_no_payload_tag) + 1;
...@@ -2614,6 +2831,32 @@ pub const Type = extern union {...@@ -2614,6 +2831,32 @@ pub const Type = extern union {
2614 @"volatile": bool,2831 @"volatile": bool,
2615 size: std.builtin.TypeInfo.Pointer.Size,2832 size: std.builtin.TypeInfo.Pointer.Size,
2616 };2833 };
2834
2835 pub const ErrorUnion = struct {
2836 base: Payload = .{ .tag = .error_union },
2837
2838 error_set: Type,
2839 payload: Type,
2840 };
2841
2842 pub const AnyFrame = struct {
2843 base: Payload = .{ .tag = .anyframe_T },
2844
2845 return_type: Type,
2846 };
2847
2848 pub const ErrorSet = struct {
2849 base: Payload = .{ .tag = .error_set },
2850
2851 decl: *Module.Decl,
2852 };
2853
2854 pub const ErrorSetSingle = struct {
2855 base: Payload = .{ .tag = .error_set_single },
2856
2857 /// memory is owned by `Module`
2858 name: []const u8,
2859 };
2617 };2860 };
2618};2861};
26192862
src-self-hosted/value.zig+88-3
...@@ -61,6 +61,7 @@ pub const Value = extern union {...@@ -61,6 +61,7 @@ pub const Value = extern union {
61 single_const_pointer_to_comptime_int_type,61 single_const_pointer_to_comptime_int_type,
62 const_slice_u8_type,62 const_slice_u8_type,
63 enum_literal_type,63 enum_literal_type,
64 anyframe_type,
6465
65 undef,66 undef,
66 zero,67 zero,
...@@ -90,6 +91,8 @@ pub const Value = extern union {...@@ -90,6 +91,8 @@ pub const Value = extern union {
90 float_64,91 float_64,
91 float_128,92 float_128,
92 enum_literal,93 enum_literal,
94 error_set,
95 @"error",
9396
94 pub const last_no_payload_tag = Tag.bool_false;97 pub const last_no_payload_tag = Tag.bool_false;
95 pub const no_payload_count = @enumToInt(last_no_payload_tag) + 1;98 pub const no_payload_count = @enumToInt(last_no_payload_tag) + 1;
...@@ -168,6 +171,7 @@ pub const Value = extern union {...@@ -168,6 +171,7 @@ pub const Value = extern union {
168 .single_const_pointer_to_comptime_int_type,171 .single_const_pointer_to_comptime_int_type,
169 .const_slice_u8_type,172 .const_slice_u8_type,
170 .enum_literal_type,173 .enum_literal_type,
174 .anyframe_type,
171 .undef,175 .undef,
172 .zero,176 .zero,
173 .void_value,177 .void_value,
...@@ -241,6 +245,10 @@ pub const Value = extern union {...@@ -241,6 +245,10 @@ pub const Value = extern union {
241 };245 };
242 return Value{ .ptr_otherwise = &new_payload.base };246 return Value{ .ptr_otherwise = &new_payload.base };
243 },247 },
248 .@"error" => return self.copyPayloadShallow(allocator, Payload.Error),
249
250 // memory is managed by the declaration
251 .error_set => return self.copyPayloadShallow(allocator, Payload.ErrorSet),
244 }252 }
245 }253 }
246254
...@@ -300,6 +308,7 @@ pub const Value = extern union {...@@ -300,6 +308,7 @@ pub const Value = extern union {
300 .single_const_pointer_to_comptime_int_type => return out_stream.writeAll("*const comptime_int"),308 .single_const_pointer_to_comptime_int_type => return out_stream.writeAll("*const comptime_int"),
301 .const_slice_u8_type => return out_stream.writeAll("[]const u8"),309 .const_slice_u8_type => return out_stream.writeAll("[]const u8"),
302 .enum_literal_type => return out_stream.writeAll("@TypeOf(.EnumLiteral)"),310 .enum_literal_type => return out_stream.writeAll("@TypeOf(.EnumLiteral)"),
311 .anyframe_type => return out_stream.writeAll("anyframe"),
303312
304 .null_value => return out_stream.writeAll("null"),313 .null_value => return out_stream.writeAll("null"),
305 .undef => return out_stream.writeAll("undefined"),314 .undef => return out_stream.writeAll("undefined"),
...@@ -343,6 +352,15 @@ pub const Value = extern union {...@@ -343,6 +352,15 @@ pub const Value = extern union {
343 .float_32 => return out_stream.print("{}", .{val.cast(Payload.Float_32).?.val}),352 .float_32 => return out_stream.print("{}", .{val.cast(Payload.Float_32).?.val}),
344 .float_64 => return out_stream.print("{}", .{val.cast(Payload.Float_64).?.val}),353 .float_64 => return out_stream.print("{}", .{val.cast(Payload.Float_64).?.val}),
345 .float_128 => return out_stream.print("{}", .{val.cast(Payload.Float_128).?.val}),354 .float_128 => return out_stream.print("{}", .{val.cast(Payload.Float_128).?.val}),
355 .error_set => {
356 const error_set = val.cast(Payload.ErrorSet).?;
357 try out_stream.writeAll("error{");
358 for (error_set.fields.items()) |entry| {
359 try out_stream.print("{},", .{entry.value});
360 }
361 return out_stream.writeAll("}");
362 },
363 .@"error" => return out_stream.print("error.{}", .{val.cast(Payload.Error).?.name}),
346 };364 };
347 }365 }
348366
...@@ -363,11 +381,9 @@ pub const Value = extern union {...@@ -363,11 +381,9 @@ pub const Value = extern union {
363 }381 }
364382
365 /// Asserts that the value is representable as a type.383 /// Asserts that the value is representable as a type.
366 pub fn toType(self: Value) Type {384 pub fn toType(self: Value, allocator: *Allocator) !Type {
367 return switch (self.tag()) {385 return switch (self.tag()) {
368 .ty => self.cast(Payload.Ty).?.ty,386 .ty => self.cast(Payload.Ty).?.ty,
369 .int_type => @panic("TODO int type to type"),
370
371 .u8_type => Type.initTag(.u8),387 .u8_type => Type.initTag(.u8),
372 .i8_type => Type.initTag(.i8),388 .i8_type => Type.initTag(.i8),
373 .u16_type => Type.initTag(.u16),389 .u16_type => Type.initTag(.u16),
...@@ -408,6 +424,26 @@ pub const Value = extern union {...@@ -408,6 +424,26 @@ pub const Value = extern union {
408 .single_const_pointer_to_comptime_int_type => Type.initTag(.single_const_pointer_to_comptime_int),424 .single_const_pointer_to_comptime_int_type => Type.initTag(.single_const_pointer_to_comptime_int),
409 .const_slice_u8_type => Type.initTag(.const_slice_u8),425 .const_slice_u8_type => Type.initTag(.const_slice_u8),
410 .enum_literal_type => Type.initTag(.enum_literal),426 .enum_literal_type => Type.initTag(.enum_literal),
427 .anyframe_type => Type.initTag(.@"anyframe"),
428
429 .int_type => {
430 const payload = self.cast(Payload.IntType).?;
431 if (payload.signed) {
432 const new = try allocator.create(Type.Payload.IntSigned);
433 new.* = .{ .bits = payload.bits };
434 return Type.initPayload(&new.base);
435 } else {
436 const new = try allocator.create(Type.Payload.IntUnsigned);
437 new.* = .{ .bits = payload.bits };
438 return Type.initPayload(&new.base);
439 }
440 },
441 .error_set => {
442 const payload = self.cast(Payload.ErrorSet).?;
443 const new = try allocator.create(Type.Payload.ErrorSet);
444 new.* = .{ .decl = payload.decl };
445 return Type.initPayload(&new.base);
446 },
411447
412 .undef,448 .undef,
413 .zero,449 .zero,
...@@ -433,6 +469,7 @@ pub const Value = extern union {...@@ -433,6 +469,7 @@ pub const Value = extern union {
433 .float_64,469 .float_64,
434 .float_128,470 .float_128,
435 .enum_literal,471 .enum_literal,
472 .@"error",
436 => unreachable,473 => unreachable,
437 };474 };
438 }475 }
...@@ -482,6 +519,7 @@ pub const Value = extern union {...@@ -482,6 +519,7 @@ pub const Value = extern union {
482 .single_const_pointer_to_comptime_int_type,519 .single_const_pointer_to_comptime_int_type,
483 .const_slice_u8_type,520 .const_slice_u8_type,
484 .enum_literal_type,521 .enum_literal_type,
522 .anyframe_type,
485 .null_value,523 .null_value,
486 .function,524 .function,
487 .variable,525 .variable,
...@@ -498,6 +536,8 @@ pub const Value = extern union {...@@ -498,6 +536,8 @@ pub const Value = extern union {
498 .unreachable_value,536 .unreachable_value,
499 .empty_array,537 .empty_array,
500 .enum_literal,538 .enum_literal,
539 .error_set,
540 .@"error",
501 => unreachable,541 => unreachable,
502542
503 .undef => unreachable,543 .undef => unreachable,
...@@ -560,6 +600,7 @@ pub const Value = extern union {...@@ -560,6 +600,7 @@ pub const Value = extern union {
560 .single_const_pointer_to_comptime_int_type,600 .single_const_pointer_to_comptime_int_type,
561 .const_slice_u8_type,601 .const_slice_u8_type,
562 .enum_literal_type,602 .enum_literal_type,
603 .anyframe_type,
563 .null_value,604 .null_value,
564 .function,605 .function,
565 .variable,606 .variable,
...@@ -576,6 +617,8 @@ pub const Value = extern union {...@@ -576,6 +617,8 @@ pub const Value = extern union {
576 .unreachable_value,617 .unreachable_value,
577 .empty_array,618 .empty_array,
578 .enum_literal,619 .enum_literal,
620 .error_set,
621 .@"error",
579 => unreachable,622 => unreachable,
580623
581 .undef => unreachable,624 .undef => unreachable,
...@@ -638,6 +681,7 @@ pub const Value = extern union {...@@ -638,6 +681,7 @@ pub const Value = extern union {
638 .single_const_pointer_to_comptime_int_type,681 .single_const_pointer_to_comptime_int_type,
639 .const_slice_u8_type,682 .const_slice_u8_type,
640 .enum_literal_type,683 .enum_literal_type,
684 .anyframe_type,
641 .null_value,685 .null_value,
642 .function,686 .function,
643 .variable,687 .variable,
...@@ -654,6 +698,8 @@ pub const Value = extern union {...@@ -654,6 +698,8 @@ pub const Value = extern union {
654 .unreachable_value,698 .unreachable_value,
655 .empty_array,699 .empty_array,
656 .enum_literal,700 .enum_literal,
701 .error_set,
702 .@"error",
657 => unreachable,703 => unreachable,
658704
659 .undef => unreachable,705 .undef => unreachable,
...@@ -742,6 +788,7 @@ pub const Value = extern union {...@@ -742,6 +788,7 @@ pub const Value = extern union {
742 .single_const_pointer_to_comptime_int_type,788 .single_const_pointer_to_comptime_int_type,
743 .const_slice_u8_type,789 .const_slice_u8_type,
744 .enum_literal_type,790 .enum_literal_type,
791 .anyframe_type,
745 .null_value,792 .null_value,
746 .function,793 .function,
747 .variable,794 .variable,
...@@ -759,6 +806,8 @@ pub const Value = extern union {...@@ -759,6 +806,8 @@ pub const Value = extern union {
759 .unreachable_value,806 .unreachable_value,
760 .empty_array,807 .empty_array,
761 .enum_literal,808 .enum_literal,
809 .error_set,
810 .@"error",
762 => unreachable,811 => unreachable,
763812
764 .zero,813 .zero,
...@@ -825,6 +874,7 @@ pub const Value = extern union {...@@ -825,6 +874,7 @@ pub const Value = extern union {
825 .single_const_pointer_to_comptime_int_type,874 .single_const_pointer_to_comptime_int_type,
826 .const_slice_u8_type,875 .const_slice_u8_type,
827 .enum_literal_type,876 .enum_literal_type,
877 .anyframe_type,
828 .null_value,878 .null_value,
829 .function,879 .function,
830 .variable,880 .variable,
...@@ -841,6 +891,8 @@ pub const Value = extern union {...@@ -841,6 +891,8 @@ pub const Value = extern union {
841 .unreachable_value,891 .unreachable_value,
842 .empty_array,892 .empty_array,
843 .enum_literal,893 .enum_literal,
894 .error_set,
895 .@"error",
844 => unreachable,896 => unreachable,
845897
846 .zero,898 .zero,
...@@ -988,6 +1040,7 @@ pub const Value = extern union {...@@ -988,6 +1040,7 @@ pub const Value = extern union {
988 .single_const_pointer_to_comptime_int_type,1040 .single_const_pointer_to_comptime_int_type,
989 .const_slice_u8_type,1041 .const_slice_u8_type,
990 .enum_literal_type,1042 .enum_literal_type,
1043 .anyframe_type,
991 .bool_true,1044 .bool_true,
992 .bool_false,1045 .bool_false,
993 .null_value,1046 .null_value,
...@@ -1007,6 +1060,8 @@ pub const Value = extern union {...@@ -1007,6 +1060,8 @@ pub const Value = extern union {
1007 .void_value,1060 .void_value,
1008 .unreachable_value,1061 .unreachable_value,
1009 .enum_literal,1062 .enum_literal,
1063 .error_set,
1064 .@"error",
1010 => unreachable,1065 => unreachable,
10111066
1012 .zero => false,1067 .zero => false,
...@@ -1063,6 +1118,7 @@ pub const Value = extern union {...@@ -1063,6 +1118,7 @@ pub const Value = extern union {
1063 .single_const_pointer_to_comptime_int_type,1118 .single_const_pointer_to_comptime_int_type,
1064 .const_slice_u8_type,1119 .const_slice_u8_type,
1065 .enum_literal_type,1120 .enum_literal_type,
1121 .anyframe_type,
1066 .null_value,1122 .null_value,
1067 .function,1123 .function,
1068 .variable,1124 .variable,
...@@ -1076,6 +1132,8 @@ pub const Value = extern union {...@@ -1076,6 +1132,8 @@ pub const Value = extern union {
1076 .unreachable_value,1132 .unreachable_value,
1077 .empty_array,1133 .empty_array,
1078 .enum_literal,1134 .enum_literal,
1135 .error_set,
1136 .@"error",
1079 => unreachable,1137 => unreachable,
10801138
1081 .zero,1139 .zero,
...@@ -1197,6 +1255,7 @@ pub const Value = extern union {...@@ -1197,6 +1255,7 @@ pub const Value = extern union {
1197 .single_const_pointer_to_comptime_int_type,1255 .single_const_pointer_to_comptime_int_type,
1198 .const_slice_u8_type,1256 .const_slice_u8_type,
1199 .enum_literal_type,1257 .enum_literal_type,
1258 .anyframe_type,
1200 .zero,1259 .zero,
1201 .bool_true,1260 .bool_true,
1202 .bool_false,1261 .bool_false,
...@@ -1218,6 +1277,8 @@ pub const Value = extern union {...@@ -1218,6 +1277,8 @@ pub const Value = extern union {
1218 .unreachable_value,1277 .unreachable_value,
1219 .empty_array,1278 .empty_array,
1220 .enum_literal,1279 .enum_literal,
1280 .error_set,
1281 .@"error",
1221 => unreachable,1282 => unreachable,
12221283
1223 .ref_val => self.cast(Payload.RefVal).?.val,1284 .ref_val => self.cast(Payload.RefVal).?.val,
...@@ -1276,6 +1337,7 @@ pub const Value = extern union {...@@ -1276,6 +1337,7 @@ pub const Value = extern union {
1276 .single_const_pointer_to_comptime_int_type,1337 .single_const_pointer_to_comptime_int_type,
1277 .const_slice_u8_type,1338 .const_slice_u8_type,
1278 .enum_literal_type,1339 .enum_literal_type,
1340 .anyframe_type,
1279 .zero,1341 .zero,
1280 .bool_true,1342 .bool_true,
1281 .bool_false,1343 .bool_false,
...@@ -1297,6 +1359,8 @@ pub const Value = extern union {...@@ -1297,6 +1359,8 @@ pub const Value = extern union {
1297 .void_value,1359 .void_value,
1298 .unreachable_value,1360 .unreachable_value,
1299 .enum_literal,1361 .enum_literal,
1362 .error_set,
1363 .@"error",
1300 => unreachable,1364 => unreachable,
13011365
1302 .empty_array => unreachable, // out of bounds array index1366 .empty_array => unreachable, // out of bounds array index
...@@ -1372,6 +1436,7 @@ pub const Value = extern union {...@@ -1372,6 +1436,7 @@ pub const Value = extern union {
1372 .single_const_pointer_to_comptime_int_type,1436 .single_const_pointer_to_comptime_int_type,
1373 .const_slice_u8_type,1437 .const_slice_u8_type,
1374 .enum_literal_type,1438 .enum_literal_type,
1439 .anyframe_type,
1375 .zero,1440 .zero,
1376 .empty_array,1441 .empty_array,
1377 .bool_true,1442 .bool_true,
...@@ -1393,6 +1458,8 @@ pub const Value = extern union {...@@ -1393,6 +1458,8 @@ pub const Value = extern union {
1393 .float_128,1458 .float_128,
1394 .void_value,1459 .void_value,
1395 .enum_literal,1460 .enum_literal,
1461 .error_set,
1462 .@"error",
1396 => false,1463 => false,
13971464
1398 .undef => unreachable,1465 .undef => unreachable,
...@@ -1522,6 +1589,24 @@ pub const Value = extern union {...@@ -1522,6 +1589,24 @@ pub const Value = extern union {
1522 base: Payload = .{ .tag = .float_128 },1589 base: Payload = .{ .tag = .float_128 },
1523 val: f128,1590 val: f128,
1524 };1591 };
1592
1593 pub const ErrorSet = struct {
1594 base: Payload = .{ .tag = .error_set },
1595
1596 // TODO revisit this when we have the concept of the error tag type
1597 fields: std.StringHashMapUnmanaged(u16),
1598 decl: *Module.Decl,
1599 };
1600
1601 pub const Error = struct {
1602 base: Payload = .{ .tag = .@"error" },
1603
1604 // TODO revisit this when we have the concept of the error tag type
1605 /// `name` is owned by `Module` and will be valid for the entire
1606 /// duration of the compilation.
1607 name: []const u8,
1608 value: u16,
1609 };
1525 };1610 };
15261611
1527 /// Big enough to fit any non-BigInt value1612 /// Big enough to fit any non-BigInt value
src-self-hosted/zir.zig+56-1
...@@ -43,6 +43,8 @@ pub const Inst = struct {...@@ -43,6 +43,8 @@ pub const Inst = struct {
43 alloc,43 alloc,
44 /// Same as `alloc` except the type is inferred.44 /// Same as `alloc` except the type is inferred.
45 alloc_inferred,45 alloc_inferred,
46 /// Create an `anyframe->T`.
47 anyframe_type,
46 /// Array concatenation. `a ++ b`48 /// Array concatenation. `a ++ b`
47 array_cat,49 array_cat,
48 /// Array multiplication `a ** b`50 /// Array multiplication `a ** b`
...@@ -70,6 +72,8 @@ pub const Inst = struct {...@@ -70,6 +72,8 @@ pub const Inst = struct {
70 /// A typed result location pointer is bitcasted to a new result location pointer.72 /// A typed result location pointer is bitcasted to a new result location pointer.
71 /// The new result location pointer has an inferred type.73 /// The new result location pointer has an inferred type.
72 bitcast_result_ptr,74 bitcast_result_ptr,
75 /// Bitwise NOT. `~`
76 bitnot,
73 /// Bitwise OR. `|`77 /// Bitwise OR. `|`
74 bitor,78 bitor,
75 /// A labeled block of code, which can return a value.79 /// A labeled block of code, which can return a value.
...@@ -133,6 +137,10 @@ pub const Inst = struct {...@@ -133,6 +137,10 @@ pub const Inst = struct {
133 ensure_result_used,137 ensure_result_used,
134 /// Emits a compile error if an error is ignored.138 /// Emits a compile error if an error is ignored.
135 ensure_result_non_error,139 ensure_result_non_error,
140 /// Create a `E!T` type.
141 error_union_type,
142 /// Create an error set.
143 error_set,
136 /// Export the provided Decl as the provided name in the compilation's output object file.144 /// Export the provided Decl as the provided name in the compilation's output object file.
137 @"export",145 @"export",
138 /// Given a pointer to a struct or object that contains virtual fields, returns a pointer146 /// Given a pointer to a struct or object that contains virtual fields, returns a pointer
...@@ -160,6 +168,8 @@ pub const Inst = struct {...@@ -160,6 +168,8 @@ pub const Inst = struct {
160 /// A labeled block of code that loops forever. At the end of the body it is implied168 /// A labeled block of code that loops forever. At the end of the body it is implied
161 /// to repeat; no explicit "repeat" instruction terminates loop bodies.169 /// to repeat; no explicit "repeat" instruction terminates loop bodies.
162 loop,170 loop,
171 /// Merge two error sets into one, `E1 || E2`.
172 merge_error_sets,
163 /// Ambiguously remainder division or modulus. If the computation would possibly have173 /// Ambiguously remainder division or modulus. If the computation would possibly have
164 /// a different value depending on whether the operation is remainder division or modulus,174 /// a different value depending on whether the operation is remainder division or modulus,
165 /// a compile error is emitted. Otherwise the computation is performed.175 /// a compile error is emitted. Otherwise the computation is performed.
...@@ -286,6 +296,8 @@ pub const Inst = struct {...@@ -286,6 +296,8 @@ pub const Inst = struct {
286 .unwrap_err_safe,296 .unwrap_err_safe,
287 .unwrap_err_unsafe,297 .unwrap_err_unsafe,
288 .ensure_err_payload_void,298 .ensure_err_payload_void,
299 .anyframe_type,
300 .bitnot,
289 => UnOp,301 => UnOp,
290302
291 .add,303 .add,
...@@ -316,6 +328,8 @@ pub const Inst = struct {...@@ -316,6 +328,8 @@ pub const Inst = struct {
316 .bitcast,328 .bitcast,
317 .coerce_result_ptr,329 .coerce_result_ptr,
318 .xor,330 .xor,
331 .error_union_type,
332 .merge_error_sets,
319 => BinOp,333 => BinOp,
320334
321 .arg => Arg,335 .arg => Arg,
...@@ -347,6 +361,7 @@ pub const Inst = struct {...@@ -347,6 +361,7 @@ pub const Inst = struct {
347 .condbr => CondBr,361 .condbr => CondBr,
348 .ptr_type => PtrType,362 .ptr_type => PtrType,
349 .enum_literal => EnumLiteral,363 .enum_literal => EnumLiteral,
364 .error_set => ErrorSet,
350 };365 };
351 }366 }
352367
...@@ -438,6 +453,11 @@ pub const Inst = struct {...@@ -438,6 +453,11 @@ pub const Inst = struct {
438 .ptr_type,453 .ptr_type,
439 .ensure_err_payload_void,454 .ensure_err_payload_void,
440 .enum_literal,455 .enum_literal,
456 .merge_error_sets,
457 .anyframe_type,
458 .error_union_type,
459 .bitnot,
460 .error_set,
441 => false,461 => false,
442462
443 .@"break",463 .@"break",
...@@ -908,6 +928,16 @@ pub const Inst = struct {...@@ -908,6 +928,16 @@ pub const Inst = struct {
908 },928 },
909 kw_args: struct {},929 kw_args: struct {},
910 };930 };
931
932 pub const ErrorSet = struct {
933 pub const base_tag = Tag.error_set;
934 base: Inst,
935
936 positionals: struct {
937 fields: [][]const u8,
938 },
939 kw_args: struct {},
940 };
911};941};
912942
913pub const ErrorMsg = struct {943pub const ErrorMsg = struct {
...@@ -1142,6 +1172,16 @@ const Writer = struct {...@@ -1142,6 +1172,16 @@ const Writer = struct {
1142 const name = self.loop_table.get(param).?;1172 const name = self.loop_table.get(param).?;
1143 return std.zig.renderStringLiteral(name, stream);1173 return std.zig.renderStringLiteral(name, stream);
1144 },1174 },
1175 [][]const u8 => {
1176 try stream.writeByte('[');
1177 for (param) |str, i| {
1178 if (i != 0) {
1179 try stream.writeAll(", ");
1180 }
1181 try std.zig.renderStringLiteral(str, stream);
1182 }
1183 try stream.writeByte(']');
1184 },
1145 else => |T| @compileError("unimplemented: rendering parameter of type " ++ @typeName(T)),1185 else => |T| @compileError("unimplemented: rendering parameter of type " ++ @typeName(T)),
1146 }1186 }
1147 }1187 }
...@@ -1539,6 +1579,21 @@ const Parser = struct {...@@ -1539,6 +1579,21 @@ const Parser = struct {
1539 const name = try self.parseStringLiteral();1579 const name = try self.parseStringLiteral();
1540 return self.loop_table.get(name).?;1580 return self.loop_table.get(name).?;
1541 },1581 },
1582 [][]const u8 => {
1583 try requireEatBytes(self, "[");
1584 skipSpace(self);
1585 if (eatByte(self, ']')) return &[0][]const u8{};
1586
1587 var strings = std.ArrayList([]const u8).init(&self.arena.allocator);
1588 while (true) {
1589 skipSpace(self);
1590 try strings.append(try self.parseStringLiteral());
1591 skipSpace(self);
1592 if (!eatByte(self, ',')) break;
1593 }
1594 try requireEatBytes(self, "]");
1595 return strings.toOwnedSlice();
1596 },
1542 else => @compileError("Unimplemented: ir parseParameterGeneric for type " ++ @typeName(T)),1597 else => @compileError("Unimplemented: ir parseParameterGeneric for type " ++ @typeName(T)),
1543 }1598 }
1544 return self.fail("TODO parse parameter {}", .{@typeName(T)});1599 return self.fail("TODO parse parameter {}", .{@typeName(T)});
...@@ -1961,7 +2016,7 @@ const EmitZIR = struct {...@@ -1961,7 +2016,7 @@ const EmitZIR = struct {
1961 return self.emitUnnamedDecl(&as_inst.base);2016 return self.emitUnnamedDecl(&as_inst.base);
1962 },2017 },
1963 .Type => {2018 .Type => {
1964 const ty = typed_value.val.toType();2019 const ty = try typed_value.val.toType(&self.arena.allocator);
1965 return self.emitType(src, ty);2020 return self.emitType(src, ty);
1966 },2021 },
1967 .Fn => {2022 .Fn => {
src-self-hosted/zir_sema.zig+126-4
...@@ -97,6 +97,7 @@ pub fn analyzeInst(mod: *Module, scope: *Scope, old_inst: *zir.Inst) InnerError!...@@ -97,6 +97,7 @@ pub fn analyzeInst(mod: *Module, scope: *Scope, old_inst: *zir.Inst) InnerError!
97 .array_cat => return analyzeInstArrayCat(mod, scope, old_inst.castTag(.array_cat).?),97 .array_cat => return analyzeInstArrayCat(mod, scope, old_inst.castTag(.array_cat).?),
98 .array_mul => return analyzeInstArrayMul(mod, scope, old_inst.castTag(.array_mul).?),98 .array_mul => return analyzeInstArrayMul(mod, scope, old_inst.castTag(.array_mul).?),
99 .bitand => return analyzeInstBitwise(mod, scope, old_inst.castTag(.bitand).?),99 .bitand => return analyzeInstBitwise(mod, scope, old_inst.castTag(.bitand).?),
100 .bitnot => return analyzeInstBitNot(mod, scope, old_inst.castTag(.bitnot).?),
100 .bitor => return analyzeInstBitwise(mod, scope, old_inst.castTag(.bitor).?),101 .bitor => return analyzeInstBitwise(mod, scope, old_inst.castTag(.bitor).?),
101 .xor => return analyzeInstBitwise(mod, scope, old_inst.castTag(.xor).?),102 .xor => return analyzeInstBitwise(mod, scope, old_inst.castTag(.xor).?),
102 .shl => return analyzeInstShl(mod, scope, old_inst.castTag(.shl).?),103 .shl => return analyzeInstShl(mod, scope, old_inst.castTag(.shl).?),
...@@ -122,6 +123,10 @@ pub fn analyzeInst(mod: *Module, scope: *Scope, old_inst: *zir.Inst) InnerError!...@@ -122,6 +123,10 @@ pub fn analyzeInst(mod: *Module, scope: *Scope, old_inst: *zir.Inst) InnerError!
122 .array_type => return analyzeInstArrayType(mod, scope, old_inst.castTag(.array_type).?),123 .array_type => return analyzeInstArrayType(mod, scope, old_inst.castTag(.array_type).?),
123 .array_type_sentinel => return analyzeInstArrayTypeSentinel(mod, scope, old_inst.castTag(.array_type_sentinel).?),124 .array_type_sentinel => return analyzeInstArrayTypeSentinel(mod, scope, old_inst.castTag(.array_type_sentinel).?),
124 .enum_literal => return analyzeInstEnumLiteral(mod, scope, old_inst.castTag(.enum_literal).?),125 .enum_literal => return analyzeInstEnumLiteral(mod, scope, old_inst.castTag(.enum_literal).?),
126 .merge_error_sets => return analyzeInstMergeErrorSets(mod, scope, old_inst.castTag(.merge_error_sets).?),
127 .error_union_type => return analyzeInstErrorUnionType(mod, scope, old_inst.castTag(.error_union_type).?),
128 .anyframe_type => return analyzeInstAnyframeType(mod, scope, old_inst.castTag(.anyframe_type).?),
129 .error_set => return analyzeInstErrorSet(mod, scope, old_inst.castTag(.error_set).?),
125 }130 }
126}131}
127132
...@@ -145,7 +150,7 @@ pub fn analyzeBodyValueAsType(mod: *Module, block_scope: *Scope.Block, body: zir...@@ -145,7 +150,7 @@ pub fn analyzeBodyValueAsType(mod: *Module, block_scope: *Scope.Block, body: zir
145 for (block_scope.instructions.items) |inst| {150 for (block_scope.instructions.items) |inst| {
146 if (inst.castTag(.ret)) |ret| {151 if (inst.castTag(.ret)) |ret| {
147 const val = try mod.resolveConstValue(&block_scope.base, ret.operand);152 const val = try mod.resolveConstValue(&block_scope.base, ret.operand);
148 return val.toType();153 return val.toType(block_scope.base.arena());
149 } else {154 } else {
150 return mod.fail(&block_scope.base, inst.src, "unable to resolve comptime value", .{});155 return mod.fail(&block_scope.base, inst.src, "unable to resolve comptime value", .{});
151 }156 }
...@@ -270,7 +275,7 @@ fn resolveType(mod: *Module, scope: *Scope, old_inst: *zir.Inst) !Type {...@@ -270,7 +275,7 @@ fn resolveType(mod: *Module, scope: *Scope, old_inst: *zir.Inst) !Type {
270 const wanted_type = Type.initTag(.@"type");275 const wanted_type = Type.initTag(.@"type");
271 const coerced_inst = try mod.coerce(scope, wanted_type, new_inst);276 const coerced_inst = try mod.coerce(scope, wanted_type, new_inst);
272 const val = try mod.resolveConstValue(scope, coerced_inst);277 const val = try mod.resolveConstValue(scope, coerced_inst);
273 return val.toType();278 return val.toType(scope.arena());
274}279}
275280
276fn resolveInt(mod: *Module, scope: *Scope, old_inst: *zir.Inst, dest_type: Type) !u64 {281fn resolveInt(mod: *Module, scope: *Scope, old_inst: *zir.Inst, dest_type: Type) !u64 {
...@@ -431,6 +436,7 @@ fn analyzeInstStr(mod: *Module, scope: *Scope, str_inst: *zir.Inst.Str) InnerErr...@@ -431,6 +436,7 @@ fn analyzeInstStr(mod: *Module, scope: *Scope, str_inst: *zir.Inst.Str) InnerErr
431 // The bytes references memory inside the ZIR module, which can get deallocated436 // The bytes references memory inside the ZIR module, which can get deallocated
432 // after semantic analysis is complete. We need the memory to be in the new anonymous Decl's arena.437 // after semantic analysis is complete. We need the memory to be in the new anonymous Decl's arena.
433 var new_decl_arena = std.heap.ArenaAllocator.init(mod.gpa);438 var new_decl_arena = std.heap.ArenaAllocator.init(mod.gpa);
439 errdefer new_decl_arena.deinit();
434 const arena_bytes = try new_decl_arena.allocator.dupe(u8, str_inst.positionals.bytes);440 const arena_bytes = try new_decl_arena.allocator.dupe(u8, str_inst.positionals.bytes);
435441
436 const ty_payload = try scope.arena().create(Type.Payload.Array_u8_Sentinel0);442 const ty_payload = try scope.arena().create(Type.Payload.Array_u8_Sentinel0);
...@@ -716,6 +722,54 @@ fn analyzeInstArrayTypeSentinel(mod: *Module, scope: *Scope, array: *zir.Inst.Ar...@@ -716,6 +722,54 @@ fn analyzeInstArrayTypeSentinel(mod: *Module, scope: *Scope, array: *zir.Inst.Ar
716 return mod.constType(scope, array.base.src, try mod.arrayType(scope, len.val.toUnsignedInt(), sentinel.val, elem_type));722 return mod.constType(scope, array.base.src, try mod.arrayType(scope, len.val.toUnsignedInt(), sentinel.val, elem_type));
717}723}
718724
725fn analyzeInstErrorUnionType(mod: *Module, scope: *Scope, inst: *zir.Inst.BinOp) InnerError!*Inst {
726 const error_union = try resolveType(mod, scope, inst.positionals.lhs);
727 const payload = try resolveType(mod, scope, inst.positionals.rhs);
728
729 if (error_union.zigTypeTag() != .ErrorSet) {
730 return mod.fail(scope, inst.base.src, "expected error set type, found {}", .{error_union.elemType()});
731 }
732
733 return mod.constType(scope, inst.base.src, try mod.errorUnionType(scope, error_union, payload));
734}
735
736fn analyzeInstAnyframeType(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp) InnerError!*Inst {
737 const return_type = try resolveType(mod, scope, inst.positionals.operand);
738
739 return mod.constType(scope, inst.base.src, try mod.anyframeType(scope, return_type));
740}
741
742fn analyzeInstErrorSet(mod: *Module, scope: *Scope, inst: *zir.Inst.ErrorSet) InnerError!*Inst {
743 // The declarations arena will store the hashmap.
744 var new_decl_arena = std.heap.ArenaAllocator.init(mod.gpa);
745 errdefer new_decl_arena.deinit();
746
747 const payload = try scope.arena().create(Value.Payload.ErrorSet);
748 payload.* = .{
749 .fields = .{},
750 .decl = undefined, // populated below
751 };
752 try payload.fields.ensureCapacity(&new_decl_arena.allocator, inst.positionals.fields.len);
753
754 for (inst.positionals.fields) |field_name| {
755 const entry = try mod.getErrorValue(field_name);
756 if (payload.fields.fetchPutAssumeCapacity(entry.key, entry.value)) |prev| {
757 return mod.fail(scope, inst.base.src, "duplicate error: '{}'", .{field_name});
758 }
759 }
760 // TODO create name in format "error:line:column"
761 const new_decl = try mod.createAnonymousDecl(scope, &new_decl_arena, .{
762 .ty = Type.initTag(.type),
763 .val = Value.initPayload(&payload.base),
764 });
765 payload.decl = new_decl;
766 return mod.analyzeDeclRef(scope, inst.base.src, new_decl);
767}
768
769fn analyzeInstMergeErrorSets(mod: *Module, scope: *Scope, inst: *zir.Inst.BinOp) InnerError!*Inst {
770 return mod.fail(scope, inst.base.src, "TODO implement merge_error_sets", .{});
771}
772
719fn analyzeInstEnumLiteral(mod: *Module, scope: *Scope, inst: *zir.Inst.EnumLiteral) InnerError!*Inst {773fn analyzeInstEnumLiteral(mod: *Module, scope: *Scope, inst: *zir.Inst.EnumLiteral) InnerError!*Inst {
720 const payload = try scope.arena().create(Value.Payload.Bytes);774 const payload = try scope.arena().create(Value.Payload.Bytes);
721 payload.* = .{775 payload.* = .{
...@@ -858,8 +912,72 @@ fn analyzeInstFieldPtr(mod: *Module, scope: *Scope, fieldptr: *zir.Inst.FieldPtr...@@ -858,8 +912,72 @@ fn analyzeInstFieldPtr(mod: *Module, scope: *Scope, fieldptr: *zir.Inst.FieldPtr
858 );912 );
859 }913 }
860 },914 },
861 else => return mod.fail(scope, fieldptr.base.src, "type '{}' does not support field access", .{elem_ty}),915 .Pointer => {
916 const ptr_child = elem_ty.elemType();
917 switch (ptr_child.zigTypeTag()) {
918 .Array => {
919 if (mem.eql(u8, field_name, "len")) {
920 const len_payload = try scope.arena().create(Value.Payload.Int_u64);
921 len_payload.* = .{ .int = ptr_child.arrayLen() };
922
923 const ref_payload = try scope.arena().create(Value.Payload.RefVal);
924 ref_payload.* = .{ .val = Value.initPayload(&len_payload.base) };
925
926 return mod.constInst(scope, fieldptr.base.src, .{
927 .ty = Type.initTag(.single_const_pointer_to_comptime_int),
928 .val = Value.initPayload(&ref_payload.base),
929 });
930 } else {
931 return mod.fail(
932 scope,
933 fieldptr.positionals.field_name.src,
934 "no member named '{}' in '{}'",
935 .{ field_name, elem_ty },
936 );
937 }
938 },
939 else => {},
940 }
941 },
942 .Type => {
943 _ = try mod.resolveConstValue(scope, object_ptr);
944 const result = try mod.analyzeDeref(scope, fieldptr.base.src, object_ptr, object_ptr.src);
945 const val = result.value().?;
946 const child_type = try val.toType(scope.arena());
947 switch (child_type.zigTypeTag()) {
948 .ErrorSet => {
949 // TODO resolve inferred error sets
950 const entry = if (val.cast(Value.Payload.ErrorSet)) |payload|
951 (payload.fields.getEntry(field_name) orelse
952 return mod.fail(scope, fieldptr.base.src, "no error named '{}' in '{}'", .{ field_name, child_type })).*
953 else try mod.getErrorValue(field_name);
954
955 const error_payload = try scope.arena().create(Value.Payload.Error);
956 error_payload.* = .{
957 .name = entry.key,
958 .value = entry.value,
959 };
960
961 const ref_payload = try scope.arena().create(Value.Payload.RefVal);
962 ref_payload.* = .{ .val = Value.initPayload(&error_payload.base) };
963
964 const result_type = if (child_type.tag() == .anyerror) blk: {
965 const result_payload = try scope.arena().create(Type.Payload.ErrorSetSingle);
966 result_payload.* = .{ .name = entry.key };
967 break :blk Type.initPayload(&result_payload.base);
968 } else child_type;
969
970 return mod.constInst(scope, fieldptr.base.src, .{
971 .ty = try mod.simplePtrType(scope, fieldptr.base.src, result_type, false, .One),
972 .val = Value.initPayload(&ref_payload.base),
973 });
974 },
975 else => return mod.fail(scope, fieldptr.base.src, "type '{}' does not support field access", .{child_type}),
976 }
977 },
978 else => {},
862 }979 }
980 return mod.fail(scope, fieldptr.base.src, "type '{}' does not support field access", .{elem_ty});
863}981}
864982
865fn analyzeInstIntCast(mod: *Module, scope: *Scope, inst: *zir.Inst.BinOp) InnerError!*Inst {983fn analyzeInstIntCast(mod: *Module, scope: *Scope, inst: *zir.Inst.BinOp) InnerError!*Inst {
...@@ -983,6 +1101,10 @@ fn analyzeInstBitwise(mod: *Module, scope: *Scope, inst: *zir.Inst.BinOp) InnerE...@@ -983,6 +1101,10 @@ fn analyzeInstBitwise(mod: *Module, scope: *Scope, inst: *zir.Inst.BinOp) InnerE
983 return mod.fail(scope, inst.base.src, "TODO implement analyzeInstBitwise", .{});1101 return mod.fail(scope, inst.base.src, "TODO implement analyzeInstBitwise", .{});
984}1102}
9851103
1104fn analyzeInstBitNot(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp) InnerError!*Inst {
1105 return mod.fail(scope, inst.base.src, "TODO implement analyzeInstBitNot", .{});
1106}
1107
986fn analyzeInstArrayCat(mod: *Module, scope: *Scope, inst: *zir.Inst.BinOp) InnerError!*Inst {1108fn analyzeInstArrayCat(mod: *Module, scope: *Scope, inst: *zir.Inst.BinOp) InnerError!*Inst {
987 return mod.fail(scope, inst.base.src, "TODO implement analyzeInstArrayCat", .{});1109 return mod.fail(scope, inst.base.src, "TODO implement analyzeInstArrayCat", .{});
988}1110}
...@@ -1348,7 +1470,7 @@ fn analyzeInstPtrType(mod: *Module, scope: *Scope, inst: *zir.Inst.PtrType) Inne...@@ -1348,7 +1470,7 @@ fn analyzeInstPtrType(mod: *Module, scope: *Scope, inst: *zir.Inst.PtrType) Inne
13481470
1349 if (host_size != 0 and bit_offset >= host_size * 8)1471 if (host_size != 0 and bit_offset >= host_size * 8)
1350 return mod.fail(scope, inst.base.src, "bit offset starts after end of host integer", .{});1472 return mod.fail(scope, inst.base.src, "bit offset starts after end of host integer", .{});
1351 1473
1352 const sentinel = if (inst.kw_args.sentinel) |some|1474 const sentinel = if (inst.kw_args.sentinel) |some|
1353 (try resolveInstConst(mod, scope, some)).val1475 (try resolveInstConst(mod, scope, some)).val
1354 else1476 else