| author | |
| committer | |
| log | 16d7db59ed9b0b1be6790bdb80777fbe5f80c7ed |
| tree | deded38af34d9e77fc9a62639a15a03c5f6c78d5 |
| parent | d62c12e077e4e3993864317bf8af5f0fcc631515 |
6 files changed, 287 insertions(+), 13 deletions(-)
src-self-hosted/Module.zig+22| ... | ... | @@ -3309,6 +3309,28 @@ pub fn arrayType(self: *Module, scope: *Scope, len: u64, sentinel: ?Value, elem_ |
| 3309 | 3309 | return Type.initPayload(&payload.base); |
| 3310 | 3310 | } |
| 3311 | 3311 | |
| 3312 | pub fn errorUnionType(self: *Module, scope: *Scope, error_set: Type, payload: Type) Allocator.Error!Type { | |
| 3313 | assert(error_set.zigTypeTag() == .ErrorSet); | |
| 3314 | if (error_set.eql(Type.initTag(.anyerror)) and payload.eql(Type.initTag(.void))) { | |
| 3315 | return Type.initTag(.anyerror_void_error_union); | |
| 3316 | } | |
| 3317 | ||
| 3318 | const result = try scope.arena().create(Type.Payload.ErrorUnion); | |
| 3319 | result.* = .{ | |
| 3320 | .error_set = error_set, | |
| 3321 | .payload = payload, | |
| 3322 | }; | |
| 3323 | return Type.initPayload(&result.base); | |
| 3324 | } | |
| 3325 | ||
| 3326 | pub fn anyframeType(self: *Module, scope: *Scope, return_type: Type) Allocator.Error!Type { | |
| 3327 | const result = try scope.arena().create(Type.Payload.AnyFrame); | |
| 3328 | result.* = .{ | |
| 3329 | .return_type = return_type, | |
| 3330 | }; | |
| 3331 | return Type.initPayload(&result.base); | |
| 3332 | } | |
| 3333 | ||
| 3312 | 3334 | pub fn dumpInst(self: *Module, scope: *Scope, inst: *Inst) void { |
| 3313 | 3335 | const zir_module = scope.namespace(); |
| 3314 | 3336 | const source = zir_module.getSource(self) catch @panic("dumpInst failed to get source"); |
src-self-hosted/astgen.zig+35-6| ... | ... | @@ -267,11 +267,12 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node) InnerEr |
| 267 | 267 | .MultilineStringLiteral => return rlWrap(mod, scope, rl, try multilineStrLiteral(mod, scope, node.castTag(.MultilineStringLiteral).?)), |
| 268 | 268 | .CharLiteral => return rlWrap(mod, scope, rl, try charLiteral(mod, scope, node.castTag(.CharLiteral).?)), |
| 269 | 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).?)), | |
| 270 | 273 | |
| 271 | 274 | .Defer => return mod.failNode(scope, node, "TODO implement astgen.expr for .Defer", .{}), |
| 272 | 275 | .Catch => return mod.failNode(scope, node, "TODO implement astgen.expr for .Catch", .{}), |
| 273 | .ErrorUnion => return mod.failNode(scope, node, "TODO implement astgen.expr for .ErrorUnion", .{}), | |
| 274 | .MergeErrorSets => return mod.failNode(scope, node, "TODO implement astgen.expr for .MergeErrorSets", .{}), | |
| 275 | 276 | .Range => return mod.failNode(scope, node, "TODO implement astgen.expr for .Range", .{}), |
| 276 | 277 | .OrElse => return mod.failNode(scope, node, "TODO implement astgen.expr for .OrElse", .{}), |
| 277 | 278 | .Await => return mod.failNode(scope, node, "TODO implement astgen.expr for .Await", .{}), |
| ... | ... | @@ -290,7 +291,6 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node) InnerEr |
| 290 | 291 | .AnyType => return mod.failNode(scope, node, "TODO implement astgen.expr for .AnyType", .{}), |
| 291 | 292 | .ErrorType => return mod.failNode(scope, node, "TODO implement astgen.expr for .ErrorType", .{}), |
| 292 | 293 | .FnProto => return mod.failNode(scope, node, "TODO implement astgen.expr for .FnProto", .{}), |
| 293 | .AnyFrameType => return mod.failNode(scope, node, "TODO implement astgen.expr for .AnyFrameType", .{}), | |
| 294 | 294 | .ErrorSetDecl => return mod.failNode(scope, node, "TODO implement astgen.expr for .ErrorSetDecl", .{}), |
| 295 | 295 | .ContainerDecl => return mod.failNode(scope, node, "TODO implement astgen.expr for .ContainerDecl", .{}), |
| 296 | 296 | .Comptime => return mod.failNode(scope, node, "TODO implement astgen.expr for .Comptime", .{}), |
| ... | ... | @@ -566,14 +566,13 @@ fn negation(mod: *Module, scope: *Scope, node: *ast.Node.SimplePrefixOp, op_inst |
| 566 | 566 | const tree = scope.tree(); |
| 567 | 567 | const src = tree.token_locs[node.op_token].start; |
| 568 | 568 | |
| 569 | const lhs = addZIRInstConst(mod, scope, src, .{ | |
| 569 | const lhs = try addZIRInstConst(mod, scope, src, .{ | |
| 570 | 570 | .ty = Type.initTag(.comptime_int), |
| 571 | 571 | .val = Value.initTag(.zero), |
| 572 | 572 | }); |
| 573 | 573 | const rhs = try expr(mod, scope, .none, node.rhs); |
| 574 | 574 | |
| 575 | const result = try addZIRBinOp(mod, scope, src, op_inst_tag, lhs, rhs); | |
| 576 | return rlWrap(mod, scope, rl, result); | |
| 575 | return addZIRBinOp(mod, scope, src, op_inst_tag, lhs, rhs); | |
| 577 | 576 | } |
| 578 | 577 | |
| 579 | 578 | fn addressOf(mod: *Module, scope: *Scope, node: *ast.Node.SimplePrefixOp) InnerError!*zir.Inst { |
| ... | ... | @@ -703,6 +702,36 @@ fn arrayTypeSentinel(mod: *Module, scope: *Scope, node: *ast.Node.ArrayTypeSenti |
| 703 | 702 | }, .{}); |
| 704 | 703 | } |
| 705 | 704 | |
| 705 | fn anyFrameType(mod: *Module, scope: *Scope, node: *ast.Node.AnyFrameType) InnerError!*zir.Inst { | |
| 706 | const tree = scope.tree(); | |
| 707 | const src = tree.token_locs[node.anyframe_token].start; | |
| 708 | if (node.result) |some| { | |
| 709 | const meta_type = try addZIRInstConst(mod, scope, src, .{ | |
| 710 | .ty = Type.initTag(.type), | |
| 711 | .val = Value.initTag(.type_type), | |
| 712 | }); | |
| 713 | const return_type = try expr(mod, scope, .{ .ty = meta_type}, some.return_type); | |
| 714 | return addZIRUnOp(mod, scope, src, .anyframe_type, return_type); | |
| 715 | } else { | |
| 716 | return addZIRInstConst(mod, scope, src, .{ | |
| 717 | .ty = Type.initTag(.type), | |
| 718 | .val = Value.initTag(.anyframe_type), | |
| 719 | }); | |
| 720 | } | |
| 721 | } | |
| 722 | ||
| 723 | fn typeInixOp(mod: *Module, scope: *Scope, node: *ast.Node.SimpleInfixOp, op_inst_tag: zir.Inst.Tag) InnerError!*zir.Inst { | |
| 724 | const tree = scope.tree(); | |
| 725 | const src = tree.token_locs[node.op_token].start; | |
| 726 | const meta_type = try addZIRInstConst(mod, scope, src, .{ | |
| 727 | .ty = Type.initTag(.type), | |
| 728 | .val = Value.initTag(.type_type), | |
| 729 | }); | |
| 730 | const error_set = try expr(mod, scope, .{ .ty = meta_type }, node.lhs); | |
| 731 | const payload = try expr(mod, scope, .{ .ty = meta_type }, node.rhs); | |
| 732 | return addZIRBinOp(mod, scope, src, op_inst_tag, error_set, payload); | |
| 733 | } | |
| 734 | ||
| 706 | 735 | fn enumLiteral(mod: *Module, scope: *Scope, node: *ast.Node.EnumLiteral) !*zir.Inst { |
| 707 | 736 | const tree = scope.tree(); |
| 708 | 737 | const src = tree.token_locs[node.name].start; |
src-self-hosted/type.zig+173-6| ... | ... | @@ -84,6 +84,10 @@ pub const Type = extern union { |
| 84 | 84 | .optional_single_mut_pointer, |
| 85 | 85 | => return .Optional, |
| 86 | 86 | .enum_literal => return .EnumLiteral, |
| 87 | ||
| 88 | .anyerror_void_error_union, .error_union => return .ErrorUnion, | |
| 89 | ||
| 90 | .anyframe_T, .@"anyframe" => return .AnyFrame, | |
| 87 | 91 | } |
| 88 | 92 | } |
| 89 | 93 | |
| ... | ... | @@ -151,6 +155,9 @@ pub const Type = extern union { |
| 151 | 155 | .ComptimeInt => return true, |
| 152 | 156 | .Undefined => return true, |
| 153 | 157 | .Null => return true, |
| 158 | .AnyFrame => { | |
| 159 | return a.elemType().eql(b.elemType()); | |
| 160 | }, | |
| 154 | 161 | .Pointer => { |
| 155 | 162 | // Hot path for common case: |
| 156 | 163 | if (a.castPointer()) |a_payload| { |
| ... | ... | @@ -225,7 +232,6 @@ pub const Type = extern union { |
| 225 | 232 | .BoundFn, |
| 226 | 233 | .Opaque, |
| 227 | 234 | .Frame, |
| 228 | .AnyFrame, | |
| 229 | 235 | .Vector, |
| 230 | 236 | => std.debug.panic("TODO implement Type equality comparison of {} and {}", .{ a, b }), |
| 231 | 237 | } |
| ... | ... | @@ -343,6 +349,8 @@ pub const Type = extern union { |
| 343 | 349 | .single_const_pointer_to_comptime_int, |
| 344 | 350 | .const_slice_u8, |
| 345 | 351 | .enum_literal, |
| 352 | .anyerror_void_error_union, | |
| 353 | .@"anyframe", | |
| 346 | 354 | => unreachable, |
| 347 | 355 | |
| 348 | 356 | .array_u8_sentinel_0 => return self.copyPayloadShallow(allocator, Payload.Array_u8_Sentinel0), |
| ... | ... | @@ -397,6 +405,7 @@ pub const Type = extern union { |
| 397 | 405 | .optional_single_mut_pointer, |
| 398 | 406 | .optional_single_const_pointer, |
| 399 | 407 | => return self.copyPayloadSingleField(allocator, Payload.PointerSimple, "pointee_type"), |
| 408 | .anyframe_T => return self.copyPayloadSingleField(allocator, Payload.AnyFrame, "return_type"), | |
| 400 | 409 | |
| 401 | 410 | .pointer => { |
| 402 | 411 | const payload = @fieldParentPtr(Payload.Pointer, "base", self.ptr_otherwise); |
| ... | ... | @@ -416,6 +425,17 @@ pub const Type = extern union { |
| 416 | 425 | }; |
| 417 | 426 | return Type{ .ptr_otherwise = &new_payload.base }; |
| 418 | 427 | }, |
| 428 | .error_union => { | |
| 429 | const payload = @fieldParentPtr(Payload.ErrorUnion, "base", self.ptr_otherwise); | |
| 430 | const new_payload = try allocator.create(Payload.ErrorUnion); | |
| 431 | new_payload.* = .{ | |
| 432 | .base = payload.base, | |
| 433 | ||
| 434 | .error_set = try payload.error_set.copy(allocator), | |
| 435 | .payload = try payload.payload.copy(allocator), | |
| 436 | }; | |
| 437 | return Type{ .ptr_otherwise = &new_payload.base }; | |
| 438 | }, | |
| 419 | 439 | } |
| 420 | 440 | } |
| 421 | 441 | |
| ... | ... | @@ -482,6 +502,8 @@ pub const Type = extern union { |
| 482 | 502 | .@"null" => return out_stream.writeAll("@TypeOf(null)"), |
| 483 | 503 | .@"undefined" => return out_stream.writeAll("@TypeOf(undefined)"), |
| 484 | 504 | |
| 505 | .@"anyframe" => return out_stream.writeAll("anyframe"), | |
| 506 | .anyerror_void_error_union => return out_stream.writeAll("anyerror!void"), | |
| 485 | 507 | .const_slice_u8 => return out_stream.writeAll("[]const u8"), |
| 486 | 508 | .fn_noreturn_no_args => return out_stream.writeAll("fn() noreturn"), |
| 487 | 509 | .fn_void_no_args => return out_stream.writeAll("fn() void"), |
| ... | ... | @@ -500,6 +522,12 @@ pub const Type = extern union { |
| 500 | 522 | continue; |
| 501 | 523 | }, |
| 502 | 524 | |
| 525 | .anyframe_T => { | |
| 526 | const payload = @fieldParentPtr(Payload.AnyFrame, "base", ty.ptr_otherwise); | |
| 527 | try out_stream.print("anyframe->", .{}); | |
| 528 | ty = payload.return_type; | |
| 529 | continue; | |
| 530 | }, | |
| 503 | 531 | .array_u8 => { |
| 504 | 532 | const payload = @fieldParentPtr(Payload.Array_u8, "base", ty.ptr_otherwise); |
| 505 | 533 | return out_stream.print("[{}]u8", .{payload.len}); |
| ... | ... | @@ -622,6 +650,13 @@ pub const Type = extern union { |
| 622 | 650 | ty = payload.pointee_type; |
| 623 | 651 | continue; |
| 624 | 652 | }, |
| 653 | .error_union => { | |
| 654 | const payload = @fieldParentPtr(Payload.ErrorUnion, "base", ty.ptr_otherwise); | |
| 655 | try payload.error_set.format("", .{}, out_stream); | |
| 656 | try out_stream.writeAll("!"); | |
| 657 | ty = payload.payload; | |
| 658 | continue; | |
| 659 | }, | |
| 625 | 660 | } |
| 626 | 661 | unreachable; |
| 627 | 662 | } |
| ... | ... | @@ -715,6 +750,9 @@ pub const Type = extern union { |
| 715 | 750 | .optional, |
| 716 | 751 | .optional_single_mut_pointer, |
| 717 | 752 | .optional_single_const_pointer, |
| 753 | .@"anyframe", | |
| 754 | .anyframe_T, | |
| 755 | .anyerror_void_error_union, | |
| 718 | 756 | => true, |
| 719 | 757 | // TODO lazy types |
| 720 | 758 | .array => self.elemType().hasCodeGenBits() and self.arrayLen() != 0, |
| ... | ... | @@ -723,6 +761,11 @@ pub const Type = extern union { |
| 723 | 761 | .int_signed => self.cast(Payload.IntSigned).?.bits == 0, |
| 724 | 762 | .int_unsigned => self.cast(Payload.IntUnsigned).?.bits == 0, |
| 725 | 763 | |
| 764 | .error_union => { | |
| 765 | const payload = self.cast(Payload.ErrorUnion).?; | |
| 766 | return payload.error_set.hasCodeGenBits() or payload.payload.hasCodeGenBits(); | |
| 767 | }, | |
| 768 | ||
| 726 | 769 | .c_void, |
| 727 | 770 | .void, |
| 728 | 771 | .type, |
| ... | ... | @@ -779,6 +822,8 @@ pub const Type = extern union { |
| 779 | 822 | .mut_slice, |
| 780 | 823 | .optional_single_const_pointer, |
| 781 | 824 | .optional_single_mut_pointer, |
| 825 | .@"anyframe", | |
| 826 | .anyframe_T, | |
| 782 | 827 | => return @divExact(target.cpu.arch.ptrBitWidth(), 8), |
| 783 | 828 | |
| 784 | 829 | .pointer => { |
| ... | ... | @@ -803,7 +848,7 @@ pub const Type = extern union { |
| 803 | 848 | .f128 => return 16, |
| 804 | 849 | .c_longdouble => return 16, |
| 805 | 850 | |
| 806 | .anyerror => return 2, // TODO revisit this when we have the concept of the error tag type | |
| 851 | .anyerror_void_error_union, .anyerror => return 2, // TODO revisit this when we have the concept of the error tag type | |
| 807 | 852 | |
| 808 | 853 | .array, .array_sentinel => return self.elemType().abiAlignment(target), |
| 809 | 854 | |
| ... | ... | @@ -829,6 +874,16 @@ pub const Type = extern union { |
| 829 | 874 | return child_type.abiAlignment(target); |
| 830 | 875 | }, |
| 831 | 876 | |
| 877 | .error_union => { | |
| 878 | const payload = self.cast(Payload.ErrorUnion).?; | |
| 879 | if (!payload.error_set.hasCodeGenBits()) { | |
| 880 | return payload.payload.abiAlignment(target); | |
| 881 | } else if (!payload.payload.hasCodeGenBits()) { | |
| 882 | return payload.error_set.abiAlignment(target); | |
| 883 | } | |
| 884 | @panic("TODO abiAlignment error union"); | |
| 885 | }, | |
| 886 | ||
| 832 | 887 | .c_void, |
| 833 | 888 | .void, |
| 834 | 889 | .type, |
| ... | ... | @@ -882,12 +937,15 @@ pub const Type = extern union { |
| 882 | 937 | .i32, .u32 => return 4, |
| 883 | 938 | .i64, .u64 => return 8, |
| 884 | 939 | |
| 885 | .isize, .usize => return @divExact(target.cpu.arch.ptrBitWidth(), 8), | |
| 940 | .@"anyframe", .anyframe_T, .isize, .usize => return @divExact(target.cpu.arch.ptrBitWidth(), 8), | |
| 886 | 941 | |
| 887 | 942 | .const_slice, |
| 888 | 943 | .mut_slice, |
| 889 | .const_slice_u8, | |
| 890 | => return @divExact(target.cpu.arch.ptrBitWidth(), 8) * 2, | |
| 944 | => { | |
| 945 | if (self.elemType().hasCodeGenBits()) return @divExact(target.cpu.arch.ptrBitWidth(), 8) * 2; | |
| 946 | return @divExact(target.cpu.arch.ptrBitWidth(), 8); | |
| 947 | }, | |
| 948 | .const_slice_u8 => return @divExact(target.cpu.arch.ptrBitWidth(), 8) * 2, | |
| 891 | 949 | |
| 892 | 950 | .optional_single_const_pointer, |
| 893 | 951 | .optional_single_mut_pointer, |
| ... | ... | @@ -923,7 +981,7 @@ pub const Type = extern union { |
| 923 | 981 | .f128 => return 16, |
| 924 | 982 | .c_longdouble => return 16, |
| 925 | 983 | |
| 926 | .anyerror => return 2, // TODO revisit this when we have the concept of the error tag type | |
| 984 | .anyerror_void_error_union, .anyerror => return 2, // TODO revisit this when we have the concept of the error tag type | |
| 927 | 985 | |
| 928 | 986 | .int_signed, .int_unsigned => { |
| 929 | 987 | const bits: u16 = if (self.cast(Payload.IntSigned)) |pl| |
| ... | ... | @@ -950,6 +1008,18 @@ pub const Type = extern union { |
| 950 | 1008 | // to the child type's ABI alignment. |
| 951 | 1009 | return child_type.abiAlignment(target) + child_type.abiSize(target); |
| 952 | 1010 | }, |
| 1011 | ||
| 1012 | .error_union => { | |
| 1013 | const payload = self.cast(Payload.ErrorUnion).?; | |
| 1014 | if (!payload.error_set.hasCodeGenBits() and !payload.payload.hasCodeGenBits()) { | |
| 1015 | return 0; | |
| 1016 | } else if (!payload.error_set.hasCodeGenBits()) { | |
| 1017 | return payload.payload.abiSize(target); | |
| 1018 | } else if (!payload.payload.hasCodeGenBits()) { | |
| 1019 | return payload.error_set.abiSize(target); | |
| 1020 | } | |
| 1021 | @panic("TODO abiSize error union"); | |
| 1022 | }, | |
| 953 | 1023 | }; |
| 954 | 1024 | } |
| 955 | 1025 | |
| ... | ... | @@ -1010,6 +1080,10 @@ pub const Type = extern union { |
| 1010 | 1080 | .c_mut_pointer, |
| 1011 | 1081 | .const_slice, |
| 1012 | 1082 | .mut_slice, |
| 1083 | .error_union, | |
| 1084 | .@"anyframe", | |
| 1085 | .anyframe_T, | |
| 1086 | .anyerror_void_error_union, | |
| 1013 | 1087 | => false, |
| 1014 | 1088 | |
| 1015 | 1089 | .single_const_pointer, |
| ... | ... | @@ -1078,6 +1152,10 @@ pub const Type = extern union { |
| 1078 | 1152 | .optional_single_mut_pointer, |
| 1079 | 1153 | .optional_single_const_pointer, |
| 1080 | 1154 | .enum_literal, |
| 1155 | .error_union, | |
| 1156 | .@"anyframe", | |
| 1157 | .anyframe_T, | |
| 1158 | .anyerror_void_error_union, | |
| 1081 | 1159 | => false, |
| 1082 | 1160 | |
| 1083 | 1161 | .const_slice, |
| ... | ... | @@ -1143,6 +1221,10 @@ pub const Type = extern union { |
| 1143 | 1221 | .optional_single_const_pointer, |
| 1144 | 1222 | .enum_literal, |
| 1145 | 1223 | .mut_slice, |
| 1224 | .error_union, | |
| 1225 | .@"anyframe", | |
| 1226 | .anyframe_T, | |
| 1227 | .anyerror_void_error_union, | |
| 1146 | 1228 | => false, |
| 1147 | 1229 | |
| 1148 | 1230 | .single_const_pointer, |
| ... | ... | @@ -1217,6 +1299,10 @@ pub const Type = extern union { |
| 1217 | 1299 | .optional_single_mut_pointer, |
| 1218 | 1300 | .optional_single_const_pointer, |
| 1219 | 1301 | .enum_literal, |
| 1302 | .error_union, | |
| 1303 | .@"anyframe", | |
| 1304 | .anyframe_T, | |
| 1305 | .anyerror_void_error_union, | |
| 1220 | 1306 | => false, |
| 1221 | 1307 | |
| 1222 | 1308 | .pointer => { |
| ... | ... | @@ -1328,6 +1414,10 @@ pub const Type = extern union { |
| 1328 | 1414 | .optional_single_const_pointer, |
| 1329 | 1415 | .optional_single_mut_pointer, |
| 1330 | 1416 | .enum_literal, |
| 1417 | .error_union, | |
| 1418 | .@"anyframe", | |
| 1419 | .anyframe_T, | |
| 1420 | .anyerror_void_error_union, | |
| 1331 | 1421 | => unreachable, |
| 1332 | 1422 | |
| 1333 | 1423 | .array => self.cast(Payload.Array).?.elem_type, |
| ... | ... | @@ -1449,6 +1539,10 @@ pub const Type = extern union { |
| 1449 | 1539 | .optional_single_mut_pointer, |
| 1450 | 1540 | .optional_single_const_pointer, |
| 1451 | 1541 | .enum_literal, |
| 1542 | .error_union, | |
| 1543 | .@"anyframe", | |
| 1544 | .anyframe_T, | |
| 1545 | .anyerror_void_error_union, | |
| 1452 | 1546 | => unreachable, |
| 1453 | 1547 | |
| 1454 | 1548 | .array => self.cast(Payload.Array).?.len, |
| ... | ... | @@ -1516,6 +1610,10 @@ pub const Type = extern union { |
| 1516 | 1610 | .optional_single_mut_pointer, |
| 1517 | 1611 | .optional_single_const_pointer, |
| 1518 | 1612 | .enum_literal, |
| 1613 | .error_union, | |
| 1614 | .@"anyframe", | |
| 1615 | .anyframe_T, | |
| 1616 | .anyerror_void_error_union, | |
| 1519 | 1617 | => unreachable, |
| 1520 | 1618 | |
| 1521 | 1619 | .array, .array_u8 => return null, |
| ... | ... | @@ -1581,6 +1679,10 @@ pub const Type = extern union { |
| 1581 | 1679 | .optional_single_mut_pointer, |
| 1582 | 1680 | .optional_single_const_pointer, |
| 1583 | 1681 | .enum_literal, |
| 1682 | .error_union, | |
| 1683 | .@"anyframe", | |
| 1684 | .anyframe_T, | |
| 1685 | .anyerror_void_error_union, | |
| 1584 | 1686 | => false, |
| 1585 | 1687 | |
| 1586 | 1688 | .int_signed, |
| ... | ... | @@ -1649,6 +1751,10 @@ pub const Type = extern union { |
| 1649 | 1751 | .optional_single_mut_pointer, |
| 1650 | 1752 | .optional_single_const_pointer, |
| 1651 | 1753 | .enum_literal, |
| 1754 | .error_union, | |
| 1755 | .@"anyframe", | |
| 1756 | .anyframe_T, | |
| 1757 | .anyerror_void_error_union, | |
| 1652 | 1758 | => false, |
| 1653 | 1759 | |
| 1654 | 1760 | .int_unsigned, |
| ... | ... | @@ -1707,6 +1813,10 @@ pub const Type = extern union { |
| 1707 | 1813 | .optional_single_mut_pointer, |
| 1708 | 1814 | .optional_single_const_pointer, |
| 1709 | 1815 | .enum_literal, |
| 1816 | .error_union, | |
| 1817 | .@"anyframe", | |
| 1818 | .anyframe_T, | |
| 1819 | .anyerror_void_error_union, | |
| 1710 | 1820 | => unreachable, |
| 1711 | 1821 | |
| 1712 | 1822 | .int_unsigned => .{ .signed = false, .bits = self.cast(Payload.IntUnsigned).?.bits }, |
| ... | ... | @@ -1783,6 +1893,10 @@ pub const Type = extern union { |
| 1783 | 1893 | .optional_single_mut_pointer, |
| 1784 | 1894 | .optional_single_const_pointer, |
| 1785 | 1895 | .enum_literal, |
| 1896 | .error_union, | |
| 1897 | .@"anyframe", | |
| 1898 | .anyframe_T, | |
| 1899 | .anyerror_void_error_union, | |
| 1786 | 1900 | => false, |
| 1787 | 1901 | |
| 1788 | 1902 | .usize, |
| ... | ... | @@ -1888,6 +2002,10 @@ pub const Type = extern union { |
| 1888 | 2002 | .optional_single_mut_pointer, |
| 1889 | 2003 | .optional_single_const_pointer, |
| 1890 | 2004 | .enum_literal, |
| 2005 | .error_union, | |
| 2006 | .@"anyframe", | |
| 2007 | .anyframe_T, | |
| 2008 | .anyerror_void_error_union, | |
| 1891 | 2009 | => unreachable, |
| 1892 | 2010 | }; |
| 1893 | 2011 | } |
| ... | ... | @@ -1959,6 +2077,10 @@ pub const Type = extern union { |
| 1959 | 2077 | .optional_single_mut_pointer, |
| 1960 | 2078 | .optional_single_const_pointer, |
| 1961 | 2079 | .enum_literal, |
| 2080 | .error_union, | |
| 2081 | .@"anyframe", | |
| 2082 | .anyframe_T, | |
| 2083 | .anyerror_void_error_union, | |
| 1962 | 2084 | => unreachable, |
| 1963 | 2085 | } |
| 1964 | 2086 | } |
| ... | ... | @@ -2029,6 +2151,10 @@ pub const Type = extern union { |
| 2029 | 2151 | .optional_single_mut_pointer, |
| 2030 | 2152 | .optional_single_const_pointer, |
| 2031 | 2153 | .enum_literal, |
| 2154 | .error_union, | |
| 2155 | .@"anyframe", | |
| 2156 | .anyframe_T, | |
| 2157 | .anyerror_void_error_union, | |
| 2032 | 2158 | => unreachable, |
| 2033 | 2159 | } |
| 2034 | 2160 | } |
| ... | ... | @@ -2099,6 +2225,10 @@ pub const Type = extern union { |
| 2099 | 2225 | .optional_single_mut_pointer, |
| 2100 | 2226 | .optional_single_const_pointer, |
| 2101 | 2227 | .enum_literal, |
| 2228 | .error_union, | |
| 2229 | .@"anyframe", | |
| 2230 | .anyframe_T, | |
| 2231 | .anyerror_void_error_union, | |
| 2102 | 2232 | => unreachable, |
| 2103 | 2233 | }; |
| 2104 | 2234 | } |
| ... | ... | @@ -2166,6 +2296,10 @@ pub const Type = extern union { |
| 2166 | 2296 | .optional_single_mut_pointer, |
| 2167 | 2297 | .optional_single_const_pointer, |
| 2168 | 2298 | .enum_literal, |
| 2299 | .error_union, | |
| 2300 | .@"anyframe", | |
| 2301 | .anyframe_T, | |
| 2302 | .anyerror_void_error_union, | |
| 2169 | 2303 | => unreachable, |
| 2170 | 2304 | }; |
| 2171 | 2305 | } |
| ... | ... | @@ -2233,6 +2367,10 @@ pub const Type = extern union { |
| 2233 | 2367 | .optional_single_mut_pointer, |
| 2234 | 2368 | .optional_single_const_pointer, |
| 2235 | 2369 | .enum_literal, |
| 2370 | .error_union, | |
| 2371 | .@"anyframe", | |
| 2372 | .anyframe_T, | |
| 2373 | .anyerror_void_error_union, | |
| 2236 | 2374 | => unreachable, |
| 2237 | 2375 | }; |
| 2238 | 2376 | } |
| ... | ... | @@ -2300,6 +2438,10 @@ pub const Type = extern union { |
| 2300 | 2438 | .optional_single_mut_pointer, |
| 2301 | 2439 | .optional_single_const_pointer, |
| 2302 | 2440 | .enum_literal, |
| 2441 | .error_union, | |
| 2442 | .@"anyframe", | |
| 2443 | .anyframe_T, | |
| 2444 | .anyerror_void_error_union, | |
| 2303 | 2445 | => false, |
| 2304 | 2446 | }; |
| 2305 | 2447 | } |
| ... | ... | @@ -2351,6 +2493,10 @@ pub const Type = extern union { |
| 2351 | 2493 | .optional_single_mut_pointer, |
| 2352 | 2494 | .optional_single_const_pointer, |
| 2353 | 2495 | .enum_literal, |
| 2496 | .anyerror_void_error_union, | |
| 2497 | .anyframe_T, | |
| 2498 | .@"anyframe", | |
| 2499 | .error_union, | |
| 2354 | 2500 | => return null, |
| 2355 | 2501 | |
| 2356 | 2502 | .void => return Value.initTag(.void_value), |
| ... | ... | @@ -2454,6 +2600,10 @@ pub const Type = extern union { |
| 2454 | 2600 | .optional_single_mut_pointer, |
| 2455 | 2601 | .optional_single_const_pointer, |
| 2456 | 2602 | .enum_literal, |
| 2603 | .error_union, | |
| 2604 | .@"anyframe", | |
| 2605 | .anyframe_T, | |
| 2606 | .anyerror_void_error_union, | |
| 2457 | 2607 | => return false, |
| 2458 | 2608 | |
| 2459 | 2609 | .c_const_pointer, |
| ... | ... | @@ -2511,6 +2661,8 @@ pub const Type = extern union { |
| 2511 | 2661 | fn_naked_noreturn_no_args, |
| 2512 | 2662 | fn_ccc_void_no_args, |
| 2513 | 2663 | single_const_pointer_to_comptime_int, |
| 2664 | anyerror_void_error_union, | |
| 2665 | @"anyframe", | |
| 2514 | 2666 | const_slice_u8, // See last_no_payload_tag below. |
| 2515 | 2667 | // After this, the tag requires a payload. |
| 2516 | 2668 | |
| ... | ... | @@ -2533,6 +2685,8 @@ pub const Type = extern union { |
| 2533 | 2685 | optional, |
| 2534 | 2686 | optional_single_mut_pointer, |
| 2535 | 2687 | optional_single_const_pointer, |
| 2688 | error_union, | |
| 2689 | anyframe_T, | |
| 2536 | 2690 | |
| 2537 | 2691 | pub const last_no_payload_tag = Tag.const_slice_u8; |
| 2538 | 2692 | pub const no_payload_count = @enumToInt(last_no_payload_tag) + 1; |
| ... | ... | @@ -2614,6 +2768,19 @@ pub const Type = extern union { |
| 2614 | 2768 | @"volatile": bool, |
| 2615 | 2769 | size: std.builtin.TypeInfo.Pointer.Size, |
| 2616 | 2770 | }; |
| 2771 | ||
| 2772 | pub const ErrorUnion = struct { | |
| 2773 | base: Payload = .{ .tag = .error_union }, | |
| 2774 | ||
| 2775 | error_set: Type, | |
| 2776 | payload: Type, | |
| 2777 | }; | |
| 2778 | ||
| 2779 | pub const AnyFrame = struct { | |
| 2780 | base: Payload = .{ .tag = .anyframe_T }, | |
| 2781 | ||
| 2782 | return_type: Type, | |
| 2783 | }; | |
| 2617 | 2784 | }; |
| 2618 | 2785 | }; |
| 2619 | 2786 |
src-self-hosted/value.zig+14| ... | ... | @@ -61,6 +61,7 @@ pub const Value = extern union { |
| 61 | 61 | single_const_pointer_to_comptime_int_type, |
| 62 | 62 | const_slice_u8_type, |
| 63 | 63 | enum_literal_type, |
| 64 | anyframe_type, | |
| 64 | 65 | |
| 65 | 66 | undef, |
| 66 | 67 | zero, |
| ... | ... | @@ -168,6 +169,7 @@ pub const Value = extern union { |
| 168 | 169 | .single_const_pointer_to_comptime_int_type, |
| 169 | 170 | .const_slice_u8_type, |
| 170 | 171 | .enum_literal_type, |
| 172 | .anyframe_type, | |
| 171 | 173 | .undef, |
| 172 | 174 | .zero, |
| 173 | 175 | .void_value, |
| ... | ... | @@ -300,6 +302,7 @@ pub const Value = extern union { |
| 300 | 302 | .single_const_pointer_to_comptime_int_type => return out_stream.writeAll("*const comptime_int"), |
| 301 | 303 | .const_slice_u8_type => return out_stream.writeAll("[]const u8"), |
| 302 | 304 | .enum_literal_type => return out_stream.writeAll("@TypeOf(.EnumLiteral)"), |
| 305 | .anyframe_type => return out_stream.writeAll("anyframe"), | |
| 303 | 306 | |
| 304 | 307 | .null_value => return out_stream.writeAll("null"), |
| 305 | 308 | .undef => return out_stream.writeAll("undefined"), |
| ... | ... | @@ -408,6 +411,7 @@ pub const Value = extern union { |
| 408 | 411 | .single_const_pointer_to_comptime_int_type => Type.initTag(.single_const_pointer_to_comptime_int), |
| 409 | 412 | .const_slice_u8_type => Type.initTag(.const_slice_u8), |
| 410 | 413 | .enum_literal_type => Type.initTag(.enum_literal), |
| 414 | .anyframe_type => Type.initTag(.@"anyframe"), | |
| 411 | 415 | |
| 412 | 416 | .undef, |
| 413 | 417 | .zero, |
| ... | ... | @@ -482,6 +486,7 @@ pub const Value = extern union { |
| 482 | 486 | .single_const_pointer_to_comptime_int_type, |
| 483 | 487 | .const_slice_u8_type, |
| 484 | 488 | .enum_literal_type, |
| 489 | .anyframe_type, | |
| 485 | 490 | .null_value, |
| 486 | 491 | .function, |
| 487 | 492 | .variable, |
| ... | ... | @@ -560,6 +565,7 @@ pub const Value = extern union { |
| 560 | 565 | .single_const_pointer_to_comptime_int_type, |
| 561 | 566 | .const_slice_u8_type, |
| 562 | 567 | .enum_literal_type, |
| 568 | .anyframe_type, | |
| 563 | 569 | .null_value, |
| 564 | 570 | .function, |
| 565 | 571 | .variable, |
| ... | ... | @@ -638,6 +644,7 @@ pub const Value = extern union { |
| 638 | 644 | .single_const_pointer_to_comptime_int_type, |
| 639 | 645 | .const_slice_u8_type, |
| 640 | 646 | .enum_literal_type, |
| 647 | .anyframe_type, | |
| 641 | 648 | .null_value, |
| 642 | 649 | .function, |
| 643 | 650 | .variable, |
| ... | ... | @@ -742,6 +749,7 @@ pub const Value = extern union { |
| 742 | 749 | .single_const_pointer_to_comptime_int_type, |
| 743 | 750 | .const_slice_u8_type, |
| 744 | 751 | .enum_literal_type, |
| 752 | .anyframe_type, | |
| 745 | 753 | .null_value, |
| 746 | 754 | .function, |
| 747 | 755 | .variable, |
| ... | ... | @@ -825,6 +833,7 @@ pub const Value = extern union { |
| 825 | 833 | .single_const_pointer_to_comptime_int_type, |
| 826 | 834 | .const_slice_u8_type, |
| 827 | 835 | .enum_literal_type, |
| 836 | .anyframe_type, | |
| 828 | 837 | .null_value, |
| 829 | 838 | .function, |
| 830 | 839 | .variable, |
| ... | ... | @@ -988,6 +997,7 @@ pub const Value = extern union { |
| 988 | 997 | .single_const_pointer_to_comptime_int_type, |
| 989 | 998 | .const_slice_u8_type, |
| 990 | 999 | .enum_literal_type, |
| 1000 | .anyframe_type, | |
| 991 | 1001 | .bool_true, |
| 992 | 1002 | .bool_false, |
| 993 | 1003 | .null_value, |
| ... | ... | @@ -1063,6 +1073,7 @@ pub const Value = extern union { |
| 1063 | 1073 | .single_const_pointer_to_comptime_int_type, |
| 1064 | 1074 | .const_slice_u8_type, |
| 1065 | 1075 | .enum_literal_type, |
| 1076 | .anyframe_type, | |
| 1066 | 1077 | .null_value, |
| 1067 | 1078 | .function, |
| 1068 | 1079 | .variable, |
| ... | ... | @@ -1197,6 +1208,7 @@ pub const Value = extern union { |
| 1197 | 1208 | .single_const_pointer_to_comptime_int_type, |
| 1198 | 1209 | .const_slice_u8_type, |
| 1199 | 1210 | .enum_literal_type, |
| 1211 | .anyframe_type, | |
| 1200 | 1212 | .zero, |
| 1201 | 1213 | .bool_true, |
| 1202 | 1214 | .bool_false, |
| ... | ... | @@ -1276,6 +1288,7 @@ pub const Value = extern union { |
| 1276 | 1288 | .single_const_pointer_to_comptime_int_type, |
| 1277 | 1289 | .const_slice_u8_type, |
| 1278 | 1290 | .enum_literal_type, |
| 1291 | .anyframe_type, | |
| 1279 | 1292 | .zero, |
| 1280 | 1293 | .bool_true, |
| 1281 | 1294 | .bool_false, |
| ... | ... | @@ -1372,6 +1385,7 @@ pub const Value = extern union { |
| 1372 | 1385 | .single_const_pointer_to_comptime_int_type, |
| 1373 | 1386 | .const_slice_u8_type, |
| 1374 | 1387 | .enum_literal_type, |
| 1388 | .anyframe_type, | |
| 1375 | 1389 | .zero, |
| 1376 | 1390 | .empty_array, |
| 1377 | 1391 | .bool_true, |
src-self-hosted/zir.zig+14| ... | ... | @@ -43,6 +43,8 @@ pub const Inst = struct { |
| 43 | 43 | alloc, |
| 44 | 44 | /// Same as `alloc` except the type is inferred. |
| 45 | 45 | alloc_inferred, |
| 46 | /// Create an `anyframe->T`. | |
| 47 | anyframe_type, | |
| 46 | 48 | /// Array concatenation. `a ++ b` |
| 47 | 49 | array_cat, |
| 48 | 50 | /// Array multiplication `a ** b` |
| ... | ... | @@ -135,6 +137,8 @@ pub const Inst = struct { |
| 135 | 137 | ensure_result_used, |
| 136 | 138 | /// Emits a compile error if an error is ignored. |
| 137 | 139 | ensure_result_non_error, |
| 140 | /// Create a `E!T` type. | |
| 141 | error_union_type, | |
| 138 | 142 | /// Export the provided Decl as the provided name in the compilation's output object file. |
| 139 | 143 | @"export", |
| 140 | 144 | /// Given a pointer to a struct or object that contains virtual fields, returns a pointer |
| ... | ... | @@ -162,6 +166,8 @@ pub const Inst = struct { |
| 162 | 166 | /// A labeled block of code that loops forever. At the end of the body it is implied |
| 163 | 167 | /// to repeat; no explicit "repeat" instruction terminates loop bodies. |
| 164 | 168 | loop, |
| 169 | /// Merge two error sets into one, `E1 || E2`. | |
| 170 | merge_error_sets, | |
| 165 | 171 | /// Ambiguously remainder division or modulus. If the computation would possibly have |
| 166 | 172 | /// a different value depending on whether the operation is remainder division or modulus, |
| 167 | 173 | /// a compile error is emitted. Otherwise the computation is performed. |
| ... | ... | @@ -288,6 +294,8 @@ pub const Inst = struct { |
| 288 | 294 | .unwrap_err_safe, |
| 289 | 295 | .unwrap_err_unsafe, |
| 290 | 296 | .ensure_err_payload_void, |
| 297 | .anyframe_type, | |
| 298 | .bitnot, | |
| 291 | 299 | => UnOp, |
| 292 | 300 | |
| 293 | 301 | .add, |
| ... | ... | @@ -318,6 +326,8 @@ pub const Inst = struct { |
| 318 | 326 | .bitcast, |
| 319 | 327 | .coerce_result_ptr, |
| 320 | 328 | .xor, |
| 329 | .error_union_type, | |
| 330 | .merge_error_sets, | |
| 321 | 331 | => BinOp, |
| 322 | 332 | |
| 323 | 333 | .arg => Arg, |
| ... | ... | @@ -440,6 +450,10 @@ pub const Inst = struct { |
| 440 | 450 | .ptr_type, |
| 441 | 451 | .ensure_err_payload_void, |
| 442 | 452 | .enum_literal, |
| 453 | .merge_error_sets, | |
| 454 | .anyframe_type, | |
| 455 | .error_union_type, | |
| 456 | .bitnot, | |
| 443 | 457 | => false, |
| 444 | 458 | |
| 445 | 459 | .@"break", |
src-self-hosted/zir_sema.zig+29-1| ... | ... | @@ -97,7 +97,7 @@ pub fn analyzeInst(mod: *Module, scope: *Scope, old_inst: *zir.Inst) InnerError! |
| 97 | 97 | .array_cat => return analyzeInstArrayCat(mod, scope, old_inst.castTag(.array_cat).?), |
| 98 | 98 | .array_mul => return analyzeInstArrayMul(mod, scope, old_inst.castTag(.array_mul).?), |
| 99 | 99 | .bitand => return analyzeInstBitwise(mod, scope, old_inst.castTag(.bitand).?), |
| 100 | .bitnot => return analyzeInstBitwise(mod, scope, old_inst.castTag(.bitnot).?), | |
| 100 | .bitnot => return analyzeInstBitNot(mod, scope, old_inst.castTag(.bitnot).?), | |
| 101 | 101 | .bitor => return analyzeInstBitwise(mod, scope, old_inst.castTag(.bitor).?), |
| 102 | 102 | .xor => return analyzeInstBitwise(mod, scope, old_inst.castTag(.xor).?), |
| 103 | 103 | .shl => return analyzeInstShl(mod, scope, old_inst.castTag(.shl).?), |
| ... | ... | @@ -123,6 +123,9 @@ pub fn analyzeInst(mod: *Module, scope: *Scope, old_inst: *zir.Inst) InnerError! |
| 123 | 123 | .array_type => return analyzeInstArrayType(mod, scope, old_inst.castTag(.array_type).?), |
| 124 | 124 | .array_type_sentinel => return analyzeInstArrayTypeSentinel(mod, scope, old_inst.castTag(.array_type_sentinel).?), |
| 125 | 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).?), | |
| 126 | 129 | } |
| 127 | 130 | } |
| 128 | 131 | |
| ... | ... | @@ -717,6 +720,27 @@ fn analyzeInstArrayTypeSentinel(mod: *Module, scope: *Scope, array: *zir.Inst.Ar |
| 717 | 720 | return mod.constType(scope, array.base.src, try mod.arrayType(scope, len.val.toUnsignedInt(), sentinel.val, elem_type)); |
| 718 | 721 | } |
| 719 | 722 | |
| 723 | fn analyzeInstErrorUnionType(mod: *Module, scope: *Scope, inst: *zir.Inst.BinOp) InnerError!*Inst { | |
| 724 | const error_union = try resolveType(mod, scope, inst.positionals.lhs); | |
| 725 | const payload = try resolveType(mod, scope, inst.positionals.rhs); | |
| 726 | ||
| 727 | if (error_union.zigTypeTag() != .ErrorSet) { | |
| 728 | return mod.fail(scope, inst.base.src, "expected error set type, found {}", .{error_union.elemType()}); | |
| 729 | } | |
| 730 | ||
| 731 | return mod.constType(scope, inst.base.src, try mod.errorUnionType(scope, error_union, payload)); | |
| 732 | } | |
| 733 | ||
| 734 | fn analyzeInstAnyframeType(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp) InnerError!*Inst { | |
| 735 | const return_type = try resolveType(mod, scope, inst.positionals.operand); | |
| 736 | ||
| 737 | return mod.constType(scope, inst.base.src, try mod.anyframeType(scope, return_type)); | |
| 738 | } | |
| 739 | ||
| 740 | fn analyzeInstMergeErrorSets(mod: *Module, scope: *Scope, inst: *zir.Inst.BinOp) InnerError!*Inst { | |
| 741 | return mod.fail(scope, inst.base.src, "TODO implement merge_error_sets", .{}); | |
| 742 | } | |
| 743 | ||
| 720 | 744 | fn analyzeInstEnumLiteral(mod: *Module, scope: *Scope, inst: *zir.Inst.EnumLiteral) InnerError!*Inst { |
| 721 | 745 | const payload = try scope.arena().create(Value.Payload.Bytes); |
| 722 | 746 | payload.* = .{ |
| ... | ... | @@ -984,6 +1008,10 @@ fn analyzeInstBitwise(mod: *Module, scope: *Scope, inst: *zir.Inst.BinOp) InnerE |
| 984 | 1008 | return mod.fail(scope, inst.base.src, "TODO implement analyzeInstBitwise", .{}); |
| 985 | 1009 | } |
| 986 | 1010 | |
| 1011 | fn analyzeInstBitNot(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp) InnerError!*Inst { | |
| 1012 | return mod.fail(scope, inst.base.src, "TODO implement analyzeInstBitNot", .{}); | |
| 1013 | } | |
| 1014 | ||
| 987 | 1015 | fn analyzeInstArrayCat(mod: *Module, scope: *Scope, inst: *zir.Inst.BinOp) InnerError!*Inst { |
| 988 | 1016 | return mod.fail(scope, inst.base.src, "TODO implement analyzeInstArrayCat", .{}); |
| 989 | 1017 | } |