authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-08-18 12:24:23+03:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-08-18 12:36:00+03:00
log7c15c9428e9df26c8699f034704796b03cf839b9
treebb9f04e3e50acfa09cbf6eb56612e7223499488c
parent3eb8f7be1018cef3043bfb56a0e2c3ff323e91d5
signature Commit is signed but in an unrecognized format.

stage2: array types


5 files changed, 254 insertions(+), 49 deletions(-)

src-self-hosted/Module.zig+66-1
...@@ -2902,7 +2902,7 @@ pub fn floatSub(self: *Module, scope: *Scope, float_type: Type, src: usize, lhs:...@@ -2902,7 +2902,7 @@ pub fn floatSub(self: *Module, scope: *Scope, float_type: Type, src: usize, lhs:
2902 return Value.initPayload(val_payload);2902 return Value.initPayload(val_payload);
2903}2903}
29042904
2905pub fn singlePtrType(self: *Module, scope: *Scope, src: usize, mutable: bool, elem_ty: Type) error{OutOfMemory}!Type {2905pub fn singlePtrType(self: *Module, scope: *Scope, src: usize, mutable: bool, elem_ty: Type) Allocator.Error!Type {
2906 const type_payload = try scope.arena().create(Type.Payload.Pointer);2906 const type_payload = try scope.arena().create(Type.Payload.Pointer);
2907 type_payload.* = .{2907 type_payload.* = .{
2908 .base = .{ .tag = if (mutable) .single_mut_pointer else .single_const_pointer },2908 .base = .{ .tag = if (mutable) .single_mut_pointer else .single_const_pointer },
...@@ -2911,6 +2911,71 @@ pub fn singlePtrType(self: *Module, scope: *Scope, src: usize, mutable: bool, el...@@ -2911,6 +2911,71 @@ pub fn singlePtrType(self: *Module, scope: *Scope, src: usize, mutable: bool, el
2911 return Type.initPayload(&type_payload.base);2911 return Type.initPayload(&type_payload.base);
2912}2912}
29132913
2914pub fn optionalType(self: *Module, scope: *Scope, child_type: Type) Allocator.Error!Type {
2915 return Type.initPayload(switch (child_type.tag()) {
2916 .single_const_pointer => blk: {
2917 const payload = try scope.arena().create(Type.Payload.Pointer);
2918 payload.* = .{
2919 .base = .{ .tag = .optional_single_const_pointer },
2920 .pointee_type = child_type.elemType(),
2921 };
2922 break :blk &payload.base;
2923 },
2924 .single_mut_pointer => blk: {
2925 const payload = try scope.arena().create(Type.Payload.Pointer);
2926 payload.* = .{
2927 .base = .{ .tag = .optional_single_mut_pointer },
2928 .pointee_type = child_type.elemType(),
2929 };
2930 break :blk &payload.base;
2931 },
2932 else => blk: {
2933 const payload = try scope.arena().create(Type.Payload.Optional);
2934 payload.* = .{
2935 .child_type = child_type,
2936 };
2937 break :blk &payload.base;
2938 },
2939 });
2940}
2941
2942pub fn arrayType(self: *Module, scope: *Scope, len: u64, sentinel: ?Value, elem_type: Type) Allocator.Error!Type {
2943 if (elem_type.eql(Type.initTag(.u8))) {
2944 if (sentinel) |some| {
2945 if (some.eql(Value.initTag(.zero))) {
2946 const payload = try scope.arena().create(Type.Payload.Array_u8_Sentinel0);
2947 payload.* = .{
2948 .len = len,
2949 };
2950 return Type.initPayload(&payload.base);
2951 }
2952 } else {
2953 const payload = try scope.arena().create(Type.Payload.Array_u8);
2954 payload.* = .{
2955 .len = len,
2956 };
2957 return Type.initPayload(&payload.base);
2958 }
2959 }
2960
2961 if (sentinel) |some| {
2962 const payload = try scope.arena().create(Type.Payload.ArraySentinel);
2963 payload.* = .{
2964 .len = len,
2965 .sentinel = some,
2966 .elem_type = elem_type,
2967 };
2968 return Type.initPayload(&payload.base);
2969 }
2970
2971 const payload = try scope.arena().create(Type.Payload.Array);
2972 payload.* = .{
2973 .len = len,
2974 .elem_type = elem_type,
2975 };
2976 return Type.initPayload(&payload.base);
2977}
2978
2914pub fn dumpInst(self: *Module, scope: *Scope, inst: *Inst) void {2979pub fn dumpInst(self: *Module, scope: *Scope, inst: *Inst) void {
2915 const zir_module = scope.namespace();2980 const zir_module = scope.namespace();
2916 const source = zir_module.getSource(self) catch @panic("dumpInst failed to get source");2981 const source = zir_module.getSource(self) catch @panic("dumpInst failed to get source");
src-self-hosted/astgen.zig+44-2
...@@ -128,6 +128,8 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node) InnerEr...@@ -128,6 +128,8 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node) InnerEr
128 .Break => return rlWrap(mod, scope, rl, try breakExpr(mod, scope, node.castTag(.Break).?)),128 .Break => return rlWrap(mod, scope, rl, try breakExpr(mod, scope, node.castTag(.Break).?)),
129 .PtrType => return rlWrap(mod, scope, rl, try ptrType(mod, scope, node.castTag(.PtrType).?)),129 .PtrType => return rlWrap(mod, scope, rl, try ptrType(mod, scope, node.castTag(.PtrType).?)),
130 .GroupedExpression => return expr(mod, scope, rl, node.castTag(.GroupedExpression).?.expr),130 .GroupedExpression => return expr(mod, scope, rl, node.castTag(.GroupedExpression).?.expr),
131 .ArrayType => return rlWrap(mod, scope, rl, try arrayType(mod, scope, node.castTag(.ArrayType).?)),
132 .ArrayTypeSentinel => return rlWrap(mod, scope, rl, try arrayTypeSentinel(mod, scope, node.castTag(.ArrayTypeSentinel).?)),
131133
132 .Defer => return mod.failNode(scope, node, "TODO implement astgen.expr for .Defer", .{}),134 .Defer => return mod.failNode(scope, node, "TODO implement astgen.expr for .Defer", .{}),
133 .Catch => return mod.failNode(scope, node, "TODO implement astgen.expr for .Catch", .{}),135 .Catch => return mod.failNode(scope, node, "TODO implement astgen.expr for .Catch", .{}),
...@@ -141,8 +143,6 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node) InnerEr...@@ -141,8 +143,6 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node) InnerEr
141 .NegationWrap => return mod.failNode(scope, node, "TODO implement astgen.expr for .NegationWrap", .{}),143 .NegationWrap => return mod.failNode(scope, node, "TODO implement astgen.expr for .NegationWrap", .{}),
142 .Resume => return mod.failNode(scope, node, "TODO implement astgen.expr for .Resume", .{}),144 .Resume => return mod.failNode(scope, node, "TODO implement astgen.expr for .Resume", .{}),
143 .Try => return mod.failNode(scope, node, "TODO implement astgen.expr for .Try", .{}),145 .Try => return mod.failNode(scope, node, "TODO implement astgen.expr for .Try", .{}),
144 .ArrayType => return mod.failNode(scope, node, "TODO implement astgen.expr for .ArrayType", .{}),
145 .ArrayTypeSentinel => return mod.failNode(scope, node, "TODO implement astgen.expr for .ArrayTypeSentinel", .{}),
146 .SliceType => return mod.failNode(scope, node, "TODO implement astgen.expr for .SliceType", .{}),146 .SliceType => return mod.failNode(scope, node, "TODO implement astgen.expr for .SliceType", .{}),
147 .Slice => return mod.failNode(scope, node, "TODO implement astgen.expr for .Slice", .{}),147 .Slice => return mod.failNode(scope, node, "TODO implement astgen.expr for .Slice", .{}),
148 .ArrayAccess => return mod.failNode(scope, node, "TODO implement astgen.expr for .ArrayAccess", .{}),148 .ArrayAccess => return mod.failNode(scope, node, "TODO implement astgen.expr for .ArrayAccess", .{}),
...@@ -485,6 +485,48 @@ fn ptrType(mod: *Module, scope: *Scope, node: *ast.Node.PtrType) InnerError!*zir...@@ -485,6 +485,48 @@ fn ptrType(mod: *Module, scope: *Scope, node: *ast.Node.PtrType) InnerError!*zir
485 return addZIRInst(mod, scope, src, zir.Inst.PtrType, .{ .child_type = child_type }, kw_args);485 return addZIRInst(mod, scope, src, zir.Inst.PtrType, .{ .child_type = child_type }, kw_args);
486}486}
487487
488fn arrayType(mod: *Module, scope: *Scope, node: *ast.Node.ArrayType) !*zir.Inst {
489 const tree = scope.tree();
490 const src = tree.token_locs[node.op_token].start;
491 const meta_type = try addZIRInstConst(mod, scope, src, .{
492 .ty = Type.initTag(.type),
493 .val = Value.initTag(.type_type),
494 });
495 const usize_type = try addZIRInstConst(mod, scope, src, .{
496 .ty = Type.initTag(.type),
497 .val = Value.initTag(.usize_type),
498 });
499
500 const len = try expr(mod, scope, .{ .ty = usize_type }, node.len_expr);
501 const child_type = try expr(mod, scope, .{ .ty = meta_type }, node.rhs);
502
503 return addZIRBinOp(mod, scope, src, .array_type, len, child_type);
504}
505
506fn arrayTypeSentinel(mod: *Module, scope: *Scope, node: *ast.Node.ArrayTypeSentinel) !*zir.Inst {
507 const tree = scope.tree();
508 const src = tree.token_locs[node.op_token].start;
509 const meta_type = try addZIRInstConst(mod, scope, src, .{
510 .ty = Type.initTag(.type),
511 .val = Value.initTag(.type_type),
512 });
513 const usize_type = try addZIRInstConst(mod, scope, src, .{
514 .ty = Type.initTag(.type),
515 .val = Value.initTag(.usize_type),
516 });
517
518 const len = try expr(mod, scope, .{ .ty = usize_type }, node.len_expr);
519 const sentinel_uncasted = try expr(mod, scope, .none, node.sentinel);
520 const elem_type = try expr(mod, scope, .{ .ty = meta_type }, node.rhs);
521 const sentinel = try addZIRBinOp(mod, scope, src, .as, elem_type, sentinel_uncasted);
522
523 return addZIRInst(mod, scope, src, zir.Inst.ArrayTypeSentinel, .{
524 .len = len,
525 .sentinel = sentinel,
526 .elem_type = elem_type,
527 }, .{});
528}
529
488fn unwrapOptional(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.SimpleSuffixOp) InnerError!*zir.Inst {530fn unwrapOptional(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.SimpleSuffixOp) InnerError!*zir.Inst {
489 const tree = scope.tree();531 const tree = scope.tree();
490 const src = tree.token_locs[node.rtoken].start;532 const src = tree.token_locs[node.rtoken].start;
src-self-hosted/type.zig+104-21
...@@ -65,7 +65,7 @@ pub const Type = extern union {...@@ -65,7 +65,7 @@ pub const Type = extern union {
65 .fn_ccc_void_no_args => return .Fn,65 .fn_ccc_void_no_args => return .Fn,
66 .function => return .Fn,66 .function => return .Fn,
6767
68 .array, .array_u8_sentinel_0 => return .Array,68 .array, .array_u8_sentinel_0, .array_u8, .array_sentinel => return .Array,
69 .single_const_pointer => return .Pointer,69 .single_const_pointer => return .Pointer,
70 .single_mut_pointer => return .Pointer,70 .single_mut_pointer => return .Pointer,
71 .single_const_pointer_to_comptime_int => return .Pointer,71 .single_const_pointer_to_comptime_int => return .Pointer,
...@@ -330,6 +330,7 @@ pub const Type = extern union {...@@ -330,6 +330,7 @@ pub const Type = extern union {
330 => unreachable,330 => unreachable,
331331
332 .array_u8_sentinel_0 => return self.copyPayloadShallow(allocator, Payload.Array_u8_Sentinel0),332 .array_u8_sentinel_0 => return self.copyPayloadShallow(allocator, Payload.Array_u8_Sentinel0),
333 .array_u8 => return self.copyPayloadShallow(allocator, Payload.Array_u8),
333 .array => {334 .array => {
334 const payload = @fieldParentPtr(Payload.Array, "base", self.ptr_otherwise);335 const payload = @fieldParentPtr(Payload.Array, "base", self.ptr_otherwise);
335 const new_payload = try allocator.create(Payload.Array);336 const new_payload = try allocator.create(Payload.Array);
...@@ -340,6 +341,17 @@ pub const Type = extern union {...@@ -340,6 +341,17 @@ pub const Type = extern union {
340 };341 };
341 return Type{ .ptr_otherwise = &new_payload.base };342 return Type{ .ptr_otherwise = &new_payload.base };
342 },343 },
344 .array_sentinel => {
345 const payload = @fieldParentPtr(Payload.ArraySentinel, "base", self.ptr_otherwise);
346 const new_payload = try allocator.create(Payload.ArraySentinel);
347 new_payload.* = .{
348 .base = payload.base,
349 .len = payload.len,
350 .sentinel = try payload.sentinel.copy(allocator),
351 .elem_type = try payload.elem_type.copy(allocator),
352 };
353 return Type{ .ptr_otherwise = &new_payload.base };
354 },
343 .int_signed => return self.copyPayloadShallow(allocator, Payload.IntSigned),355 .int_signed => return self.copyPayloadShallow(allocator, Payload.IntSigned),
344 .int_unsigned => return self.copyPayloadShallow(allocator, Payload.IntUnsigned),356 .int_unsigned => return self.copyPayloadShallow(allocator, Payload.IntUnsigned),
345 .function => {357 .function => {
...@@ -445,6 +457,10 @@ pub const Type = extern union {...@@ -445,6 +457,10 @@ pub const Type = extern union {
445 try payload.return_type.format("", .{}, out_stream);457 try payload.return_type.format("", .{}, out_stream);
446 },458 },
447459
460 .array_u8 => {
461 const payload = @fieldParentPtr(Payload.Array_u8, "base", ty.ptr_otherwise);
462 return out_stream.print("[{}]u8", .{payload.len});
463 },
448 .array_u8_sentinel_0 => {464 .array_u8_sentinel_0 => {
449 const payload = @fieldParentPtr(Payload.Array_u8_Sentinel0, "base", ty.ptr_otherwise);465 const payload = @fieldParentPtr(Payload.Array_u8_Sentinel0, "base", ty.ptr_otherwise);
450 return out_stream.print("[{}:0]u8", .{payload.len});466 return out_stream.print("[{}:0]u8", .{payload.len});
...@@ -455,6 +471,12 @@ pub const Type = extern union {...@@ -455,6 +471,12 @@ pub const Type = extern union {
455 ty = payload.elem_type;471 ty = payload.elem_type;
456 continue;472 continue;
457 },473 },
474 .array_sentinel => {
475 const payload = @fieldParentPtr(Payload.ArraySentinel, "base", ty.ptr_otherwise);
476 try out_stream.print("[{}:{}]", .{ payload.len, payload.sentinel });
477 ty = payload.elem_type;
478 continue;
479 },
458 .single_const_pointer => {480 .single_const_pointer => {
459 const payload = @fieldParentPtr(Payload.Pointer, "base", ty.ptr_otherwise);481 const payload = @fieldParentPtr(Payload.Pointer, "base", ty.ptr_otherwise);
460 try out_stream.writeAll("*const ");482 try out_stream.writeAll("*const ");
...@@ -588,6 +610,8 @@ pub const Type = extern union {...@@ -588,6 +610,8 @@ pub const Type = extern union {
588 => true,610 => true,
589 // TODO lazy types611 // TODO lazy types
590 .array => self.elemType().hasCodeGenBits() and self.arrayLen() != 0,612 .array => self.elemType().hasCodeGenBits() and self.arrayLen() != 0,
613 .array_u8 => self.arrayLen() != 0,
614 .array_sentinel => self.elemType().hasCodeGenBits(),
591 .single_const_pointer => self.elemType().hasCodeGenBits(),615 .single_const_pointer => self.elemType().hasCodeGenBits(),
592 .single_mut_pointer => self.elemType().hasCodeGenBits(),616 .single_mut_pointer => self.elemType().hasCodeGenBits(),
593 .int_signed => self.cast(Payload.IntSigned).?.bits == 0,617 .int_signed => self.cast(Payload.IntSigned).?.bits == 0,
...@@ -616,6 +640,7 @@ pub const Type = extern union {...@@ -616,6 +640,7 @@ pub const Type = extern union {
616 .i8,640 .i8,
617 .bool,641 .bool,
618 .array_u8_sentinel_0,642 .array_u8_sentinel_0,
643 .array_u8,
619 => return 1,644 => return 1,
620645
621 .fn_noreturn_no_args, // represents machine code; not a pointer646 .fn_noreturn_no_args, // represents machine code; not a pointer
...@@ -659,7 +684,7 @@ pub const Type = extern union {...@@ -659,7 +684,7 @@ pub const Type = extern union {
659684
660 .anyerror => return 2, // TODO revisit this when we have the concept of the error tag type685 .anyerror => return 2, // TODO revisit this when we have the concept of the error tag type
661686
662 .array => return self.cast(Payload.Array).?.elem_type.abiAlignment(target),687 .array, .array_sentinel => return self.elemType().abiAlignment(target),
663688
664 .int_signed, .int_unsigned => {689 .int_signed, .int_unsigned => {
665 const bits: u16 = if (self.cast(Payload.IntSigned)) |pl|690 const bits: u16 = if (self.cast(Payload.IntSigned)) |pl|
...@@ -717,12 +742,18 @@ pub const Type = extern union {...@@ -717,12 +742,18 @@ pub const Type = extern union {
717 .bool,742 .bool,
718 => return 1,743 => return 1,
719744
720 .array_u8_sentinel_0 => @fieldParentPtr(Payload.Array_u8_Sentinel0, "base", self.ptr_otherwise).len,745 .array_u8 => @fieldParentPtr(Payload.Array_u8_Sentinel0, "base", self.ptr_otherwise).len,
746 .array_u8_sentinel_0 => @fieldParentPtr(Payload.Array_u8_Sentinel0, "base", self.ptr_otherwise).len + 1,
721 .array => {747 .array => {
722 const payload = @fieldParentPtr(Payload.Array, "base", self.ptr_otherwise);748 const payload = @fieldParentPtr(Payload.Array, "base", self.ptr_otherwise);
723 const elem_size = std.math.max(payload.elem_type.abiAlignment(target), payload.elem_type.abiSize(target));749 const elem_size = std.math.max(payload.elem_type.abiAlignment(target), payload.elem_type.abiSize(target));
724 return payload.len * elem_size;750 return payload.len * elem_size;
725 },751 },
752 .array_sentinel => {
753 const payload = @fieldParentPtr(Payload.ArraySentinel, "base", self.ptr_otherwise);
754 const elem_size = std.math.max(payload.elem_type.abiAlignment(target), payload.elem_type.abiSize(target));
755 return (payload.len + 1) * elem_size;
756 },
726 .i16, .u16 => return 2,757 .i16, .u16 => return 2,
727 .i32, .u32 => return 4,758 .i32, .u32 => return 4,
728 .i64, .u64 => return 8,759 .i64, .u64 => return 8,
...@@ -818,6 +849,8 @@ pub const Type = extern union {...@@ -818,6 +849,8 @@ pub const Type = extern union {
818 .@"null",849 .@"null",
819 .@"undefined",850 .@"undefined",
820 .array,851 .array,
852 .array_sentinel,
853 .array_u8,
821 .array_u8_sentinel_0,854 .array_u8_sentinel_0,
822 .const_slice_u8,855 .const_slice_u8,
823 .fn_noreturn_no_args,856 .fn_noreturn_no_args,
...@@ -875,6 +908,8 @@ pub const Type = extern union {...@@ -875,6 +908,8 @@ pub const Type = extern union {
875 .@"null",908 .@"null",
876 .@"undefined",909 .@"undefined",
877 .array,910 .array,
911 .array_sentinel,
912 .array_u8,
878 .array_u8_sentinel_0,913 .array_u8_sentinel_0,
879 .single_const_pointer,914 .single_const_pointer,
880 .single_mut_pointer,915 .single_mut_pointer,
...@@ -931,6 +966,8 @@ pub const Type = extern union {...@@ -931,6 +966,8 @@ pub const Type = extern union {
931 .@"null",966 .@"null",
932 .@"undefined",967 .@"undefined",
933 .array,968 .array,
969 .array_sentinel,
970 .array_u8,
934 .array_u8_sentinel_0,971 .array_u8_sentinel_0,
935 .fn_noreturn_no_args,972 .fn_noreturn_no_args,
936 .fn_void_no_args,973 .fn_void_no_args,
...@@ -988,6 +1025,8 @@ pub const Type = extern union {...@@ -988,6 +1025,8 @@ pub const Type = extern union {
988 .@"null",1025 .@"null",
989 .@"undefined",1026 .@"undefined",
990 .array,1027 .array,
1028 .array_sentinel,
1029 .array_u8,
991 .array_u8_sentinel_0,1030 .array_u8_sentinel_0,
992 .fn_noreturn_no_args,1031 .fn_noreturn_no_args,
993 .fn_void_no_args,1032 .fn_void_no_args,
...@@ -1072,9 +1111,10 @@ pub const Type = extern union {...@@ -1072,9 +1111,10 @@ pub const Type = extern union {
1072 => unreachable,1111 => unreachable,
10731112
1074 .array => self.cast(Payload.Array).?.elem_type,1113 .array => self.cast(Payload.Array).?.elem_type,
1114 .array_sentinel => self.cast(Payload.ArraySentinel).?.elem_type,
1075 .single_const_pointer => self.castPointer().?.pointee_type,1115 .single_const_pointer => self.castPointer().?.pointee_type,
1076 .single_mut_pointer => self.castPointer().?.pointee_type,1116 .single_mut_pointer => self.castPointer().?.pointee_type,
1077 .array_u8_sentinel_0, .const_slice_u8 => Type.initTag(.u8),1117 .array_u8, .array_u8_sentinel_0, .const_slice_u8 => Type.initTag(.u8),
1078 .single_const_pointer_to_comptime_int => Type.initTag(.comptime_int),1118 .single_const_pointer_to_comptime_int => Type.initTag(.comptime_int),
1079 };1119 };
1080 }1120 }
...@@ -1176,6 +1216,8 @@ pub const Type = extern union {...@@ -1176,6 +1216,8 @@ pub const Type = extern union {
1176 => unreachable,1216 => unreachable,
11771217
1178 .array => self.cast(Payload.Array).?.len,1218 .array => self.cast(Payload.Array).?.len,
1219 .array_sentinel => self.cast(Payload.ArraySentinel).?.len,
1220 .array_u8 => self.cast(Payload.Array_u8).?.len,
1179 .array_u8_sentinel_0 => self.cast(Payload.Array_u8_Sentinel0).?.len,1221 .array_u8_sentinel_0 => self.cast(Payload.Array_u8_Sentinel0).?.len,
1180 };1222 };
1181 }1223 }
...@@ -1232,7 +1274,8 @@ pub const Type = extern union {...@@ -1232,7 +1274,8 @@ pub const Type = extern union {
1232 .optional_single_const_pointer,1274 .optional_single_const_pointer,
1233 => unreachable,1275 => unreachable,
12341276
1235 .array => return null,1277 .array, .array_u8 => return null,
1278 .array_sentinel => return self.cast(Payload.ArraySentinel).?.sentinel,
1236 .array_u8_sentinel_0 => return Value.initTag(.zero),1279 .array_u8_sentinel_0 => return Value.initTag(.zero),
1237 };1280 };
1238 }1281 }
...@@ -1266,10 +1309,12 @@ pub const Type = extern union {...@@ -1266,10 +1309,12 @@ pub const Type = extern union {
1266 .fn_ccc_void_no_args,1309 .fn_ccc_void_no_args,
1267 .function,1310 .function,
1268 .array,1311 .array,
1312 .array_sentinel,
1313 .array_u8,
1314 .array_u8_sentinel_0,
1269 .single_const_pointer,1315 .single_const_pointer,
1270 .single_mut_pointer,1316 .single_mut_pointer,
1271 .single_const_pointer_to_comptime_int,1317 .single_const_pointer_to_comptime_int,
1272 .array_u8_sentinel_0,
1273 .const_slice_u8,1318 .const_slice_u8,
1274 .int_unsigned,1319 .int_unsigned,
1275 .u8,1320 .u8,
...@@ -1324,10 +1369,12 @@ pub const Type = extern union {...@@ -1324,10 +1369,12 @@ pub const Type = extern union {
1324 .fn_ccc_void_no_args,1369 .fn_ccc_void_no_args,
1325 .function,1370 .function,
1326 .array,1371 .array,
1372 .array_sentinel,
1373 .array_u8,
1374 .array_u8_sentinel_0,
1327 .single_const_pointer,1375 .single_const_pointer,
1328 .single_mut_pointer,1376 .single_mut_pointer,
1329 .single_const_pointer_to_comptime_int,1377 .single_const_pointer_to_comptime_int,
1330 .array_u8_sentinel_0,
1331 .const_slice_u8,1378 .const_slice_u8,
1332 .int_signed,1379 .int_signed,
1333 .i8,1380 .i8,
...@@ -1382,10 +1429,12 @@ pub const Type = extern union {...@@ -1382,10 +1429,12 @@ pub const Type = extern union {
1382 .fn_ccc_void_no_args,1429 .fn_ccc_void_no_args,
1383 .function,1430 .function,
1384 .array,1431 .array,
1432 .array_sentinel,
1433 .array_u8,
1434 .array_u8_sentinel_0,
1385 .single_const_pointer,1435 .single_const_pointer,
1386 .single_mut_pointer,1436 .single_mut_pointer,
1387 .single_const_pointer_to_comptime_int,1437 .single_const_pointer_to_comptime_int,
1388 .array_u8_sentinel_0,
1389 .const_slice_u8,1438 .const_slice_u8,
1390 .optional,1439 .optional,
1391 .optional_single_mut_pointer,1440 .optional_single_mut_pointer,
...@@ -1438,10 +1487,12 @@ pub const Type = extern union {...@@ -1438,10 +1487,12 @@ pub const Type = extern union {
1438 .fn_ccc_void_no_args,1487 .fn_ccc_void_no_args,
1439 .function,1488 .function,
1440 .array,1489 .array,
1490 .array_sentinel,
1491 .array_u8,
1492 .array_u8_sentinel_0,
1441 .single_const_pointer,1493 .single_const_pointer,
1442 .single_mut_pointer,1494 .single_mut_pointer,
1443 .single_const_pointer_to_comptime_int,1495 .single_const_pointer_to_comptime_int,
1444 .array_u8_sentinel_0,
1445 .const_slice_u8,1496 .const_slice_u8,
1446 .int_unsigned,1497 .int_unsigned,
1447 .int_signed,1498 .int_signed,
...@@ -1523,10 +1574,12 @@ pub const Type = extern union {...@@ -1523,10 +1574,12 @@ pub const Type = extern union {
1523 .@"null",1574 .@"null",
1524 .@"undefined",1575 .@"undefined",
1525 .array,1576 .array,
1577 .array_sentinel,
1578 .array_u8,
1579 .array_u8_sentinel_0,
1526 .single_const_pointer,1580 .single_const_pointer,
1527 .single_mut_pointer,1581 .single_mut_pointer,
1528 .single_const_pointer_to_comptime_int,1582 .single_const_pointer_to_comptime_int,
1529 .array_u8_sentinel_0,
1530 .const_slice_u8,1583 .const_slice_u8,
1531 .u8,1584 .u8,
1532 .i8,1585 .i8,
...@@ -1584,10 +1637,12 @@ pub const Type = extern union {...@@ -1584,10 +1637,12 @@ pub const Type = extern union {
1584 .@"null",1637 .@"null",
1585 .@"undefined",1638 .@"undefined",
1586 .array,1639 .array,
1640 .array_sentinel,
1641 .array_u8,
1642 .array_u8_sentinel_0,
1587 .single_const_pointer,1643 .single_const_pointer,
1588 .single_mut_pointer,1644 .single_mut_pointer,
1589 .single_const_pointer_to_comptime_int,1645 .single_const_pointer_to_comptime_int,
1590 .array_u8_sentinel_0,
1591 .const_slice_u8,1646 .const_slice_u8,
1592 .u8,1647 .u8,
1593 .i8,1648 .i8,
...@@ -1644,10 +1699,12 @@ pub const Type = extern union {...@@ -1644,10 +1699,12 @@ pub const Type = extern union {
1644 .@"null",1699 .@"null",
1645 .@"undefined",1700 .@"undefined",
1646 .array,1701 .array,
1702 .array_sentinel,
1703 .array_u8,
1704 .array_u8_sentinel_0,
1647 .single_const_pointer,1705 .single_const_pointer,
1648 .single_mut_pointer,1706 .single_mut_pointer,
1649 .single_const_pointer_to_comptime_int,1707 .single_const_pointer_to_comptime_int,
1650 .array_u8_sentinel_0,
1651 .const_slice_u8,1708 .const_slice_u8,
1652 .u8,1709 .u8,
1653 .i8,1710 .i8,
...@@ -1704,10 +1761,12 @@ pub const Type = extern union {...@@ -1704,10 +1761,12 @@ pub const Type = extern union {
1704 .@"null",1761 .@"null",
1705 .@"undefined",1762 .@"undefined",
1706 .array,1763 .array,
1764 .array_sentinel,
1765 .array_u8,
1766 .array_u8_sentinel_0,
1707 .single_const_pointer,1767 .single_const_pointer,
1708 .single_mut_pointer,1768 .single_mut_pointer,
1709 .single_const_pointer_to_comptime_int,1769 .single_const_pointer_to_comptime_int,
1710 .array_u8_sentinel_0,
1711 .const_slice_u8,1770 .const_slice_u8,
1712 .u8,1771 .u8,
1713 .i8,1772 .i8,
...@@ -1761,10 +1820,12 @@ pub const Type = extern union {...@@ -1761,10 +1820,12 @@ pub const Type = extern union {
1761 .@"null",1820 .@"null",
1762 .@"undefined",1821 .@"undefined",
1763 .array,1822 .array,
1823 .array_sentinel,
1824 .array_u8,
1825 .array_u8_sentinel_0,
1764 .single_const_pointer,1826 .single_const_pointer,
1765 .single_mut_pointer,1827 .single_mut_pointer,
1766 .single_const_pointer_to_comptime_int,1828 .single_const_pointer_to_comptime_int,
1767 .array_u8_sentinel_0,
1768 .const_slice_u8,1829 .const_slice_u8,
1769 .u8,1830 .u8,
1770 .i8,1831 .i8,
...@@ -1818,10 +1879,12 @@ pub const Type = extern union {...@@ -1818,10 +1879,12 @@ pub const Type = extern union {
1818 .@"null",1879 .@"null",
1819 .@"undefined",1880 .@"undefined",
1820 .array,1881 .array,
1882 .array_sentinel,
1883 .array_u8,
1884 .array_u8_sentinel_0,
1821 .single_const_pointer,1885 .single_const_pointer,
1822 .single_mut_pointer,1886 .single_mut_pointer,
1823 .single_const_pointer_to_comptime_int,1887 .single_const_pointer_to_comptime_int,
1824 .array_u8_sentinel_0,
1825 .const_slice_u8,1888 .const_slice_u8,
1826 .u8,1889 .u8,
1827 .i8,1890 .i8,
...@@ -1895,10 +1958,12 @@ pub const Type = extern union {...@@ -1895,10 +1958,12 @@ pub const Type = extern union {
1895 .fn_ccc_void_no_args,1958 .fn_ccc_void_no_args,
1896 .function,1959 .function,
1897 .array,1960 .array,
1961 .array_sentinel,
1962 .array_u8,
1963 .array_u8_sentinel_0,
1898 .single_const_pointer,1964 .single_const_pointer,
1899 .single_mut_pointer,1965 .single_mut_pointer,
1900 .single_const_pointer_to_comptime_int,1966 .single_const_pointer_to_comptime_int,
1901 .array_u8_sentinel_0,
1902 .const_slice_u8,1967 .const_slice_u8,
1903 .optional,1968 .optional,
1904 .optional_single_mut_pointer,1969 .optional_single_mut_pointer,
...@@ -1944,6 +2009,7 @@ pub const Type = extern union {...@@ -1944,6 +2009,7 @@ pub const Type = extern union {
1944 .fn_ccc_void_no_args,2009 .fn_ccc_void_no_args,
1945 .function,2010 .function,
1946 .single_const_pointer_to_comptime_int,2011 .single_const_pointer_to_comptime_int,
2012 .array_sentinel,
1947 .array_u8_sentinel_0,2013 .array_u8_sentinel_0,
1948 .const_slice_u8,2014 .const_slice_u8,
1949 .c_void,2015 .c_void,
...@@ -1971,11 +2037,10 @@ pub const Type = extern union {...@@ -1971,11 +2037,10 @@ pub const Type = extern union {
1971 return null;2037 return null;
1972 }2038 }
1973 },2039 },
1974 .array => {2040 .array, .array_u8 => {
1975 const array = ty.cast(Payload.Array).?;2041 if (ty.arrayLen() == 0)
1976 if (array.len == 0)
1977 return Value.initTag(.empty_array);2042 return Value.initTag(.empty_array);
1978 ty = array.elem_type;2043 ty = ty.elemType();
1979 continue;2044 continue;
1980 },2045 },
1981 .single_const_pointer, .single_mut_pointer => {2046 .single_const_pointer, .single_mut_pointer => {
...@@ -2022,7 +2087,6 @@ pub const Type = extern union {...@@ -2022,7 +2087,6 @@ pub const Type = extern union {
2022 .fn_ccc_void_no_args,2087 .fn_ccc_void_no_args,
2023 .function,2088 .function,
2024 .single_const_pointer_to_comptime_int,2089 .single_const_pointer_to_comptime_int,
2025 .array_u8_sentinel_0,
2026 .const_slice_u8,2090 .const_slice_u8,
2027 .c_void,2091 .c_void,
2028 .void,2092 .void,
...@@ -2032,6 +2096,9 @@ pub const Type = extern union {...@@ -2032,6 +2096,9 @@ pub const Type = extern union {
2032 .int_unsigned,2096 .int_unsigned,
2033 .int_signed,2097 .int_signed,
2034 .array,2098 .array,
2099 .array_sentinel,
2100 .array_u8,
2101 .array_u8_sentinel_0,
2035 .single_const_pointer,2102 .single_const_pointer,
2036 .single_mut_pointer,2103 .single_mut_pointer,
2037 .optional,2104 .optional,
...@@ -2090,8 +2157,10 @@ pub const Type = extern union {...@@ -2090,8 +2157,10 @@ pub const Type = extern union {
2090 const_slice_u8, // See last_no_payload_tag below.2157 const_slice_u8, // See last_no_payload_tag below.
2091 // After this, the tag requires a payload.2158 // After this, the tag requires a payload.
20922159
2160 array_u8,
2093 array_u8_sentinel_0,2161 array_u8_sentinel_0,
2094 array,2162 array,
2163 array_sentinel,
2095 single_const_pointer,2164 single_const_pointer,
2096 single_mut_pointer,2165 single_mut_pointer,
2097 int_signed,2166 int_signed,
...@@ -2114,11 +2183,25 @@ pub const Type = extern union {...@@ -2114,11 +2183,25 @@ pub const Type = extern union {
2114 len: u64,2183 len: u64,
2115 };2184 };
21162185
2186 pub const Array_u8 = struct {
2187 base: Payload = Payload{ .tag = .array_u8 },
2188
2189 len: u64,
2190 };
2191
2117 pub const Array = struct {2192 pub const Array = struct {
2118 base: Payload = Payload{ .tag = .array },2193 base: Payload = Payload{ .tag = .array },
21192194
2195 len: u64,
2120 elem_type: Type,2196 elem_type: Type,
2197 };
2198
2199 pub const ArraySentinel = struct {
2200 base: Payload = Payload{ .tag = .array_sentinel },
2201
2121 len: u64,2202 len: u64,
2203 sentinel: Value,
2204 elem_type: Type,
2122 };2205 };
21232206
2124 pub const Pointer = struct {2207 pub const Pointer = struct {
src-self-hosted/zir.zig+20
...@@ -47,6 +47,10 @@ pub const Inst = struct {...@@ -47,6 +47,10 @@ pub const Inst = struct {
47 array_cat,47 array_cat,
48 /// Array multiplication `a ** b`48 /// Array multiplication `a ** b`
49 array_mul,49 array_mul,
50 /// Create an array type
51 array_type,
52 /// Create an array type with sentinel
53 array_type_sentinel,
50 /// Function parameter value. These must be first in a function's main block,54 /// Function parameter value. These must be first in a function's main block,
51 /// in respective order with the parameters.55 /// in respective order with the parameters.
52 arg,56 arg,
...@@ -268,6 +272,7 @@ pub const Inst = struct {...@@ -268,6 +272,7 @@ pub const Inst = struct {
268 .addwrap,272 .addwrap,
269 .array_cat,273 .array_cat,
270 .array_mul,274 .array_mul,
275 .array_type,
271 .bitand,276 .bitand,
272 .bitor,277 .bitor,
273 .div,278 .div,
...@@ -294,6 +299,7 @@ pub const Inst = struct {...@@ -294,6 +299,7 @@ pub const Inst = struct {
294 => BinOp,299 => BinOp,
295300
296 .arg => Arg,301 .arg => Arg,
302 .array_type_sentinel => ArrayTypeSentinel,
297 .block => Block,303 .block => Block,
298 .@"break" => Break,304 .@"break" => Break,
299 .breakvoid => BreakVoid,305 .breakvoid => BreakVoid,
...@@ -333,6 +339,8 @@ pub const Inst = struct {...@@ -333,6 +339,8 @@ pub const Inst = struct {
333 .alloc_inferred,339 .alloc_inferred,
334 .array_cat,340 .array_cat,
335 .array_mul,341 .array_mul,
342 .array_type,
343 .array_type_sentinel,
336 .arg,344 .arg,
337 .as,345 .as,
338 .@"asm",346 .@"asm",
...@@ -849,6 +857,18 @@ pub const Inst = struct {...@@ -849,6 +857,18 @@ pub const Inst = struct {
849 sentinel: ?*Inst = null,857 sentinel: ?*Inst = null,
850 },858 },
851 };859 };
860
861 pub const ArrayTypeSentinel = struct {
862 pub const base_tag = Tag.array_type_sentinel;
863 base: Inst,
864
865 positionals: struct {
866 len: *Inst,
867 sentinel: *Inst,
868 elem_type: *Inst,
869 },
870 kw_args: struct {},
871 };
852};872};
853873
854pub const ErrorMsg = struct {874pub const ErrorMsg = struct {
src-self-hosted/zir_sema.zig+20-25
...@@ -113,6 +113,8 @@ pub fn analyzeInst(mod: *Module, scope: *Scope, old_inst: *zir.Inst) InnerError!...@@ -113,6 +113,8 @@ pub fn analyzeInst(mod: *Module, scope: *Scope, old_inst: *zir.Inst) InnerError!
113 .unwrap_err_safe => return analyzeInstUnwrapErr(mod, scope, old_inst.castTag(.unwrap_err_safe).?, true),113 .unwrap_err_safe => return analyzeInstUnwrapErr(mod, scope, old_inst.castTag(.unwrap_err_safe).?, true),
114 .unwrap_err_unsafe => return analyzeInstUnwrapErr(mod, scope, old_inst.castTag(.unwrap_err_unsafe).?, false),114 .unwrap_err_unsafe => return analyzeInstUnwrapErr(mod, scope, old_inst.castTag(.unwrap_err_unsafe).?, false),
115 .ensure_err_payload_void => return analyzeInstEnsureErrPayloadVoid(mod, scope, old_inst.castTag(.ensure_err_payload_void).?),115 .ensure_err_payload_void => return analyzeInstEnsureErrPayloadVoid(mod, scope, old_inst.castTag(.ensure_err_payload_void).?),
116 .array_type => return analyzeInstArrayType(mod, scope, old_inst.castTag(.array_type).?),
117 .array_type_sentinel => return analyzeInstArrayTypeSentinel(mod, scope, old_inst.castTag(.array_type_sentinel).?),
116 }118 }
117}119}
118120
...@@ -676,31 +678,24 @@ fn analyzeInstIntType(mod: *Module, scope: *Scope, inttype: *zir.Inst.IntType) I...@@ -676,31 +678,24 @@ fn analyzeInstIntType(mod: *Module, scope: *Scope, inttype: *zir.Inst.IntType) I
676fn analyzeInstOptionalType(mod: *Module, scope: *Scope, optional: *zir.Inst.UnOp) InnerError!*Inst {678fn analyzeInstOptionalType(mod: *Module, scope: *Scope, optional: *zir.Inst.UnOp) InnerError!*Inst {
677 const child_type = try resolveType(mod, scope, optional.positionals.operand);679 const child_type = try resolveType(mod, scope, optional.positionals.operand);
678680
679 return mod.constType(scope, optional.base.src, Type.initPayload(switch (child_type.tag()) {681 return mod.constType(scope, optional.base.src, try mod.optionalType(scope, child_type));
680 .single_const_pointer => blk: {682}
681 const payload = try scope.arena().create(Type.Payload.Pointer);683
682 payload.* = .{684fn analyzeInstArrayType(mod: *Module, scope: *Scope, array: *zir.Inst.BinOp) InnerError!*Inst {
683 .base = .{ .tag = .optional_single_const_pointer },685 // TODO these should be lazily evaluated
684 .pointee_type = child_type.elemType(),686 const len = try resolveInstConst(mod, scope, array.positionals.lhs);
685 };687 const elem_type = try resolveType(mod, scope, array.positionals.rhs);
686 break :blk &payload.base;688
687 },689 return mod.constType(scope, array.base.src, try mod.arrayType(scope, len.val.toUnsignedInt(), null, elem_type));
688 .single_mut_pointer => blk: {690}
689 const payload = try scope.arena().create(Type.Payload.Pointer);691
690 payload.* = .{692fn analyzeInstArrayTypeSentinel(mod: *Module, scope: *Scope, array: *zir.Inst.ArrayTypeSentinel) InnerError!*Inst {
691 .base = .{ .tag = .optional_single_mut_pointer },693 // TODO these should be lazily evaluated
692 .pointee_type = child_type.elemType(),694 const len = try resolveInstConst(mod, scope, array.positionals.len);
693 };695 const sentinel = try resolveInstConst(mod, scope, array.positionals.sentinel);
694 break :blk &payload.base;696 const elem_type = try resolveType(mod, scope, array.positionals.elem_type);
695 },697
696 else => blk: {698 return mod.constType(scope, array.base.src, try mod.arrayType(scope, len.val.toUnsignedInt(), sentinel.val, elem_type));
697 const payload = try scope.arena().create(Type.Payload.Optional);
698 payload.* = .{
699 .child_type = child_type,
700 };
701 break :blk &payload.base;
702 },
703 }));
704}699}
705700
706fn analyzeInstUnwrapOptional(mod: *Module, scope: *Scope, unwrap: *zir.Inst.UnOp, safety_check: bool) InnerError!*Inst {701fn analyzeInstUnwrapOptional(mod: *Module, scope: *Scope, unwrap: *zir.Inst.UnOp, safety_check: bool) InnerError!*Inst {