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
signaturelock-open 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:
29022902 return Value.initPayload(val_payload);
29032903}
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 {
29062906 const type_payload = try scope.arena().create(Type.Payload.Pointer);
29072907 type_payload.* = .{
29082908 .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
29112911 return Type.initPayload(&type_payload.base);
29122912}
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
29142979pub fn dumpInst(self: *Module, scope: *Scope, inst: *Inst) void {
29152980 const zir_module = scope.namespace();
29162981 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
128128 .Break => return rlWrap(mod, scope, rl, try breakExpr(mod, scope, node.castTag(.Break).?)),
129129 .PtrType => return rlWrap(mod, scope, rl, try ptrType(mod, scope, node.castTag(.PtrType).?)),
130130 .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
132134 .Defer => return mod.failNode(scope, node, "TODO implement astgen.expr for .Defer", .{}),
133135 .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
141143 .NegationWrap => return mod.failNode(scope, node, "TODO implement astgen.expr for .NegationWrap", .{}),
142144 .Resume => return mod.failNode(scope, node, "TODO implement astgen.expr for .Resume", .{}),
143145 .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", .{}),
146146 .SliceType => return mod.failNode(scope, node, "TODO implement astgen.expr for .SliceType", .{}),
147147 .Slice => return mod.failNode(scope, node, "TODO implement astgen.expr for .Slice", .{}),
148148 .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
485485 return addZIRInst(mod, scope, src, zir.Inst.PtrType, .{ .child_type = child_type }, kw_args);
486486}
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
488530fn unwrapOptional(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.SimpleSuffixOp) InnerError!*zir.Inst {
489531 const tree = scope.tree();
490532 const src = tree.token_locs[node.rtoken].start;
src-self-hosted/type.zig+104-21
......@@ -65,7 +65,7 @@ pub const Type = extern union {
6565 .fn_ccc_void_no_args => return .Fn,
6666 .function => return .Fn,
6767
68 .array, .array_u8_sentinel_0 => return .Array,
68 .array, .array_u8_sentinel_0, .array_u8, .array_sentinel => return .Array,
6969 .single_const_pointer => return .Pointer,
7070 .single_mut_pointer => return .Pointer,
7171 .single_const_pointer_to_comptime_int => return .Pointer,
......@@ -330,6 +330,7 @@ pub const Type = extern union {
330330 => unreachable,
331331
332332 .array_u8_sentinel_0 => return self.copyPayloadShallow(allocator, Payload.Array_u8_Sentinel0),
333 .array_u8 => return self.copyPayloadShallow(allocator, Payload.Array_u8),
333334 .array => {
334335 const payload = @fieldParentPtr(Payload.Array, "base", self.ptr_otherwise);
335336 const new_payload = try allocator.create(Payload.Array);
......@@ -340,6 +341,17 @@ pub const Type = extern union {
340341 };
341342 return Type{ .ptr_otherwise = &new_payload.base };
342343 },
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 },
343355 .int_signed => return self.copyPayloadShallow(allocator, Payload.IntSigned),
344356 .int_unsigned => return self.copyPayloadShallow(allocator, Payload.IntUnsigned),
345357 .function => {
......@@ -445,6 +457,10 @@ pub const Type = extern union {
445457 try payload.return_type.format("", .{}, out_stream);
446458 },
447459
460 .array_u8 => {
461 const payload = @fieldParentPtr(Payload.Array_u8, "base", ty.ptr_otherwise);
462 return out_stream.print("[{}]u8", .{payload.len});
463 },
448464 .array_u8_sentinel_0 => {
449465 const payload = @fieldParentPtr(Payload.Array_u8_Sentinel0, "base", ty.ptr_otherwise);
450466 return out_stream.print("[{}:0]u8", .{payload.len});
......@@ -455,6 +471,12 @@ pub const Type = extern union {
455471 ty = payload.elem_type;
456472 continue;
457473 },
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 },
458480 .single_const_pointer => {
459481 const payload = @fieldParentPtr(Payload.Pointer, "base", ty.ptr_otherwise);
460482 try out_stream.writeAll("*const ");
......@@ -588,6 +610,8 @@ pub const Type = extern union {
588610 => true,
589611 // TODO lazy types
590612 .array => self.elemType().hasCodeGenBits() and self.arrayLen() != 0,
613 .array_u8 => self.arrayLen() != 0,
614 .array_sentinel => self.elemType().hasCodeGenBits(),
591615 .single_const_pointer => self.elemType().hasCodeGenBits(),
592616 .single_mut_pointer => self.elemType().hasCodeGenBits(),
593617 .int_signed => self.cast(Payload.IntSigned).?.bits == 0,
......@@ -616,6 +640,7 @@ pub const Type = extern union {
616640 .i8,
617641 .bool,
618642 .array_u8_sentinel_0,
643 .array_u8,
619644 => return 1,
620645
621646 .fn_noreturn_no_args, // represents machine code; not a pointer
......@@ -659,7 +684,7 @@ pub const Type = extern union {
659684
660685 .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
664689 .int_signed, .int_unsigned => {
665690 const bits: u16 = if (self.cast(Payload.IntSigned)) |pl|
......@@ -717,12 +742,18 @@ pub const Type = extern union {
717742 .bool,
718743 => 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,
721747 .array => {
722748 const payload = @fieldParentPtr(Payload.Array, "base", self.ptr_otherwise);
723749 const elem_size = std.math.max(payload.elem_type.abiAlignment(target), payload.elem_type.abiSize(target));
724750 return payload.len * elem_size;
725751 },
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 },
726757 .i16, .u16 => return 2,
727758 .i32, .u32 => return 4,
728759 .i64, .u64 => return 8,
......@@ -818,6 +849,8 @@ pub const Type = extern union {
818849 .@"null",
819850 .@"undefined",
820851 .array,
852 .array_sentinel,
853 .array_u8,
821854 .array_u8_sentinel_0,
822855 .const_slice_u8,
823856 .fn_noreturn_no_args,
......@@ -875,6 +908,8 @@ pub const Type = extern union {
875908 .@"null",
876909 .@"undefined",
877910 .array,
911 .array_sentinel,
912 .array_u8,
878913 .array_u8_sentinel_0,
879914 .single_const_pointer,
880915 .single_mut_pointer,
......@@ -931,6 +966,8 @@ pub const Type = extern union {
931966 .@"null",
932967 .@"undefined",
933968 .array,
969 .array_sentinel,
970 .array_u8,
934971 .array_u8_sentinel_0,
935972 .fn_noreturn_no_args,
936973 .fn_void_no_args,
......@@ -988,6 +1025,8 @@ pub const Type = extern union {
9881025 .@"null",
9891026 .@"undefined",
9901027 .array,
1028 .array_sentinel,
1029 .array_u8,
9911030 .array_u8_sentinel_0,
9921031 .fn_noreturn_no_args,
9931032 .fn_void_no_args,
......@@ -1072,9 +1111,10 @@ pub const Type = extern union {
10721111 => unreachable,
10731112
10741113 .array => self.cast(Payload.Array).?.elem_type,
1114 .array_sentinel => self.cast(Payload.ArraySentinel).?.elem_type,
10751115 .single_const_pointer => self.castPointer().?.pointee_type,
10761116 .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),
10781118 .single_const_pointer_to_comptime_int => Type.initTag(.comptime_int),
10791119 };
10801120 }
......@@ -1176,6 +1216,8 @@ pub const Type = extern union {
11761216 => unreachable,
11771217
11781218 .array => self.cast(Payload.Array).?.len,
1219 .array_sentinel => self.cast(Payload.ArraySentinel).?.len,
1220 .array_u8 => self.cast(Payload.Array_u8).?.len,
11791221 .array_u8_sentinel_0 => self.cast(Payload.Array_u8_Sentinel0).?.len,
11801222 };
11811223 }
......@@ -1232,7 +1274,8 @@ pub const Type = extern union {
12321274 .optional_single_const_pointer,
12331275 => unreachable,
12341276
1235 .array => return null,
1277 .array, .array_u8 => return null,
1278 .array_sentinel => return self.cast(Payload.ArraySentinel).?.sentinel,
12361279 .array_u8_sentinel_0 => return Value.initTag(.zero),
12371280 };
12381281 }
......@@ -1266,10 +1309,12 @@ pub const Type = extern union {
12661309 .fn_ccc_void_no_args,
12671310 .function,
12681311 .array,
1312 .array_sentinel,
1313 .array_u8,
1314 .array_u8_sentinel_0,
12691315 .single_const_pointer,
12701316 .single_mut_pointer,
12711317 .single_const_pointer_to_comptime_int,
1272 .array_u8_sentinel_0,
12731318 .const_slice_u8,
12741319 .int_unsigned,
12751320 .u8,
......@@ -1324,10 +1369,12 @@ pub const Type = extern union {
13241369 .fn_ccc_void_no_args,
13251370 .function,
13261371 .array,
1372 .array_sentinel,
1373 .array_u8,
1374 .array_u8_sentinel_0,
13271375 .single_const_pointer,
13281376 .single_mut_pointer,
13291377 .single_const_pointer_to_comptime_int,
1330 .array_u8_sentinel_0,
13311378 .const_slice_u8,
13321379 .int_signed,
13331380 .i8,
......@@ -1382,10 +1429,12 @@ pub const Type = extern union {
13821429 .fn_ccc_void_no_args,
13831430 .function,
13841431 .array,
1432 .array_sentinel,
1433 .array_u8,
1434 .array_u8_sentinel_0,
13851435 .single_const_pointer,
13861436 .single_mut_pointer,
13871437 .single_const_pointer_to_comptime_int,
1388 .array_u8_sentinel_0,
13891438 .const_slice_u8,
13901439 .optional,
13911440 .optional_single_mut_pointer,
......@@ -1438,10 +1487,12 @@ pub const Type = extern union {
14381487 .fn_ccc_void_no_args,
14391488 .function,
14401489 .array,
1490 .array_sentinel,
1491 .array_u8,
1492 .array_u8_sentinel_0,
14411493 .single_const_pointer,
14421494 .single_mut_pointer,
14431495 .single_const_pointer_to_comptime_int,
1444 .array_u8_sentinel_0,
14451496 .const_slice_u8,
14461497 .int_unsigned,
14471498 .int_signed,
......@@ -1523,10 +1574,12 @@ pub const Type = extern union {
15231574 .@"null",
15241575 .@"undefined",
15251576 .array,
1577 .array_sentinel,
1578 .array_u8,
1579 .array_u8_sentinel_0,
15261580 .single_const_pointer,
15271581 .single_mut_pointer,
15281582 .single_const_pointer_to_comptime_int,
1529 .array_u8_sentinel_0,
15301583 .const_slice_u8,
15311584 .u8,
15321585 .i8,
......@@ -1584,10 +1637,12 @@ pub const Type = extern union {
15841637 .@"null",
15851638 .@"undefined",
15861639 .array,
1640 .array_sentinel,
1641 .array_u8,
1642 .array_u8_sentinel_0,
15871643 .single_const_pointer,
15881644 .single_mut_pointer,
15891645 .single_const_pointer_to_comptime_int,
1590 .array_u8_sentinel_0,
15911646 .const_slice_u8,
15921647 .u8,
15931648 .i8,
......@@ -1644,10 +1699,12 @@ pub const Type = extern union {
16441699 .@"null",
16451700 .@"undefined",
16461701 .array,
1702 .array_sentinel,
1703 .array_u8,
1704 .array_u8_sentinel_0,
16471705 .single_const_pointer,
16481706 .single_mut_pointer,
16491707 .single_const_pointer_to_comptime_int,
1650 .array_u8_sentinel_0,
16511708 .const_slice_u8,
16521709 .u8,
16531710 .i8,
......@@ -1704,10 +1761,12 @@ pub const Type = extern union {
17041761 .@"null",
17051762 .@"undefined",
17061763 .array,
1764 .array_sentinel,
1765 .array_u8,
1766 .array_u8_sentinel_0,
17071767 .single_const_pointer,
17081768 .single_mut_pointer,
17091769 .single_const_pointer_to_comptime_int,
1710 .array_u8_sentinel_0,
17111770 .const_slice_u8,
17121771 .u8,
17131772 .i8,
......@@ -1761,10 +1820,12 @@ pub const Type = extern union {
17611820 .@"null",
17621821 .@"undefined",
17631822 .array,
1823 .array_sentinel,
1824 .array_u8,
1825 .array_u8_sentinel_0,
17641826 .single_const_pointer,
17651827 .single_mut_pointer,
17661828 .single_const_pointer_to_comptime_int,
1767 .array_u8_sentinel_0,
17681829 .const_slice_u8,
17691830 .u8,
17701831 .i8,
......@@ -1818,10 +1879,12 @@ pub const Type = extern union {
18181879 .@"null",
18191880 .@"undefined",
18201881 .array,
1882 .array_sentinel,
1883 .array_u8,
1884 .array_u8_sentinel_0,
18211885 .single_const_pointer,
18221886 .single_mut_pointer,
18231887 .single_const_pointer_to_comptime_int,
1824 .array_u8_sentinel_0,
18251888 .const_slice_u8,
18261889 .u8,
18271890 .i8,
......@@ -1895,10 +1958,12 @@ pub const Type = extern union {
18951958 .fn_ccc_void_no_args,
18961959 .function,
18971960 .array,
1961 .array_sentinel,
1962 .array_u8,
1963 .array_u8_sentinel_0,
18981964 .single_const_pointer,
18991965 .single_mut_pointer,
19001966 .single_const_pointer_to_comptime_int,
1901 .array_u8_sentinel_0,
19021967 .const_slice_u8,
19031968 .optional,
19041969 .optional_single_mut_pointer,
......@@ -1944,6 +2009,7 @@ pub const Type = extern union {
19442009 .fn_ccc_void_no_args,
19452010 .function,
19462011 .single_const_pointer_to_comptime_int,
2012 .array_sentinel,
19472013 .array_u8_sentinel_0,
19482014 .const_slice_u8,
19492015 .c_void,
......@@ -1971,11 +2037,10 @@ pub const Type = extern union {
19712037 return null;
19722038 }
19732039 },
1974 .array => {
1975 const array = ty.cast(Payload.Array).?;
1976 if (array.len == 0)
2040 .array, .array_u8 => {
2041 if (ty.arrayLen() == 0)
19772042 return Value.initTag(.empty_array);
1978 ty = array.elem_type;
2043 ty = ty.elemType();
19792044 continue;
19802045 },
19812046 .single_const_pointer, .single_mut_pointer => {
......@@ -2022,7 +2087,6 @@ pub const Type = extern union {
20222087 .fn_ccc_void_no_args,
20232088 .function,
20242089 .single_const_pointer_to_comptime_int,
2025 .array_u8_sentinel_0,
20262090 .const_slice_u8,
20272091 .c_void,
20282092 .void,
......@@ -2032,6 +2096,9 @@ pub const Type = extern union {
20322096 .int_unsigned,
20332097 .int_signed,
20342098 .array,
2099 .array_sentinel,
2100 .array_u8,
2101 .array_u8_sentinel_0,
20352102 .single_const_pointer,
20362103 .single_mut_pointer,
20372104 .optional,
......@@ -2090,8 +2157,10 @@ pub const Type = extern union {
20902157 const_slice_u8, // See last_no_payload_tag below.
20912158 // After this, the tag requires a payload.
20922159
2160 array_u8,
20932161 array_u8_sentinel_0,
20942162 array,
2163 array_sentinel,
20952164 single_const_pointer,
20962165 single_mut_pointer,
20972166 int_signed,
......@@ -2114,11 +2183,25 @@ pub const Type = extern union {
21142183 len: u64,
21152184 };
21162185
2186 pub const Array_u8 = struct {
2187 base: Payload = Payload{ .tag = .array_u8 },
2188
2189 len: u64,
2190 };
2191
21172192 pub const Array = struct {
21182193 base: Payload = Payload{ .tag = .array },
21192194
2195 len: u64,
21202196 elem_type: Type,
2197 };
2198
2199 pub const ArraySentinel = struct {
2200 base: Payload = Payload{ .tag = .array_sentinel },
2201
21212202 len: u64,
2203 sentinel: Value,
2204 elem_type: Type,
21222205 };
21232206
21242207 pub const Pointer = struct {
src-self-hosted/zir.zig+20
......@@ -47,6 +47,10 @@ pub const Inst = struct {
4747 array_cat,
4848 /// Array multiplication `a ** b`
4949 array_mul,
50 /// Create an array type
51 array_type,
52 /// Create an array type with sentinel
53 array_type_sentinel,
5054 /// Function parameter value. These must be first in a function's main block,
5155 /// in respective order with the parameters.
5256 arg,
......@@ -268,6 +272,7 @@ pub const Inst = struct {
268272 .addwrap,
269273 .array_cat,
270274 .array_mul,
275 .array_type,
271276 .bitand,
272277 .bitor,
273278 .div,
......@@ -294,6 +299,7 @@ pub const Inst = struct {
294299 => BinOp,
295300
296301 .arg => Arg,
302 .array_type_sentinel => ArrayTypeSentinel,
297303 .block => Block,
298304 .@"break" => Break,
299305 .breakvoid => BreakVoid,
......@@ -333,6 +339,8 @@ pub const Inst = struct {
333339 .alloc_inferred,
334340 .array_cat,
335341 .array_mul,
342 .array_type,
343 .array_type_sentinel,
336344 .arg,
337345 .as,
338346 .@"asm",
......@@ -849,6 +857,18 @@ pub const Inst = struct {
849857 sentinel: ?*Inst = null,
850858 },
851859 };
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 };
852872};
853873
854874pub 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!
113113 .unwrap_err_safe => return analyzeInstUnwrapErr(mod, scope, old_inst.castTag(.unwrap_err_safe).?, true),
114114 .unwrap_err_unsafe => return analyzeInstUnwrapErr(mod, scope, old_inst.castTag(.unwrap_err_unsafe).?, false),
115115 .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).?),
116118 }
117119}
118120
......@@ -676,31 +678,24 @@ fn analyzeInstIntType(mod: *Module, scope: *Scope, inttype: *zir.Inst.IntType) I
676678fn analyzeInstOptionalType(mod: *Module, scope: *Scope, optional: *zir.Inst.UnOp) InnerError!*Inst {
677679 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()) {
680 .single_const_pointer => blk: {
681 const payload = try scope.arena().create(Type.Payload.Pointer);
682 payload.* = .{
683 .base = .{ .tag = .optional_single_const_pointer },
684 .pointee_type = child_type.elemType(),
685 };
686 break :blk &payload.base;
687 },
688 .single_mut_pointer => blk: {
689 const payload = try scope.arena().create(Type.Payload.Pointer);
690 payload.* = .{
691 .base = .{ .tag = .optional_single_mut_pointer },
692 .pointee_type = child_type.elemType(),
693 };
694 break :blk &payload.base;
695 },
696 else => blk: {
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 }));
681 return mod.constType(scope, optional.base.src, try mod.optionalType(scope, child_type));
682}
683
684fn analyzeInstArrayType(mod: *Module, scope: *Scope, array: *zir.Inst.BinOp) InnerError!*Inst {
685 // TODO these should be lazily evaluated
686 const len = try resolveInstConst(mod, scope, array.positionals.lhs);
687 const elem_type = try resolveType(mod, scope, array.positionals.rhs);
688
689 return mod.constType(scope, array.base.src, try mod.arrayType(scope, len.val.toUnsignedInt(), null, elem_type));
690}
691
692fn analyzeInstArrayTypeSentinel(mod: *Module, scope: *Scope, array: *zir.Inst.ArrayTypeSentinel) InnerError!*Inst {
693 // TODO these should be lazily evaluated
694 const len = try resolveInstConst(mod, scope, array.positionals.len);
695 const sentinel = try resolveInstConst(mod, scope, array.positionals.sentinel);
696 const elem_type = try resolveType(mod, scope, array.positionals.elem_type);
697
698 return mod.constType(scope, array.base.src, try mod.arrayType(scope, len.val.toUnsignedInt(), sentinel.val, elem_type));
704699}
705700
706701fn analyzeInstUnwrapOptional(mod: *Module, scope: *Scope, unwrap: *zir.Inst.UnOp, safety_check: bool) InnerError!*Inst {