Commit 7c15c9428e
Changed files (5)
src-self-hosted
src-self-hosted/astgen.zig
@@ -128,6 +128,8 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node) InnerEr
.Break => return rlWrap(mod, scope, rl, try breakExpr(mod, scope, node.castTag(.Break).?)),
.PtrType => return rlWrap(mod, scope, rl, try ptrType(mod, scope, node.castTag(.PtrType).?)),
.GroupedExpression => return expr(mod, scope, rl, node.castTag(.GroupedExpression).?.expr),
+ .ArrayType => return rlWrap(mod, scope, rl, try arrayType(mod, scope, node.castTag(.ArrayType).?)),
+ .ArrayTypeSentinel => return rlWrap(mod, scope, rl, try arrayTypeSentinel(mod, scope, node.castTag(.ArrayTypeSentinel).?)),
.Defer => return mod.failNode(scope, node, "TODO implement astgen.expr for .Defer", .{}),
.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
.NegationWrap => return mod.failNode(scope, node, "TODO implement astgen.expr for .NegationWrap", .{}),
.Resume => return mod.failNode(scope, node, "TODO implement astgen.expr for .Resume", .{}),
.Try => return mod.failNode(scope, node, "TODO implement astgen.expr for .Try", .{}),
- .ArrayType => return mod.failNode(scope, node, "TODO implement astgen.expr for .ArrayType", .{}),
- .ArrayTypeSentinel => return mod.failNode(scope, node, "TODO implement astgen.expr for .ArrayTypeSentinel", .{}),
.SliceType => return mod.failNode(scope, node, "TODO implement astgen.expr for .SliceType", .{}),
.Slice => return mod.failNode(scope, node, "TODO implement astgen.expr for .Slice", .{}),
.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
return addZIRInst(mod, scope, src, zir.Inst.PtrType, .{ .child_type = child_type }, kw_args);
}
+fn arrayType(mod: *Module, scope: *Scope, node: *ast.Node.ArrayType) !*zir.Inst {
+ const tree = scope.tree();
+ const src = tree.token_locs[node.op_token].start;
+ const meta_type = try addZIRInstConst(mod, scope, src, .{
+ .ty = Type.initTag(.type),
+ .val = Value.initTag(.type_type),
+ });
+ const usize_type = try addZIRInstConst(mod, scope, src, .{
+ .ty = Type.initTag(.type),
+ .val = Value.initTag(.usize_type),
+ });
+
+ const len = try expr(mod, scope, .{ .ty = usize_type }, node.len_expr);
+ const child_type = try expr(mod, scope, .{ .ty = meta_type }, node.rhs);
+
+ return addZIRBinOp(mod, scope, src, .array_type, len, child_type);
+}
+
+fn arrayTypeSentinel(mod: *Module, scope: *Scope, node: *ast.Node.ArrayTypeSentinel) !*zir.Inst {
+ const tree = scope.tree();
+ const src = tree.token_locs[node.op_token].start;
+ const meta_type = try addZIRInstConst(mod, scope, src, .{
+ .ty = Type.initTag(.type),
+ .val = Value.initTag(.type_type),
+ });
+ const usize_type = try addZIRInstConst(mod, scope, src, .{
+ .ty = Type.initTag(.type),
+ .val = Value.initTag(.usize_type),
+ });
+
+ const len = try expr(mod, scope, .{ .ty = usize_type }, node.len_expr);
+ const sentinel_uncasted = try expr(mod, scope, .none, node.sentinel);
+ const elem_type = try expr(mod, scope, .{ .ty = meta_type }, node.rhs);
+ const sentinel = try addZIRBinOp(mod, scope, src, .as, elem_type, sentinel_uncasted);
+
+ return addZIRInst(mod, scope, src, zir.Inst.ArrayTypeSentinel, .{
+ .len = len,
+ .sentinel = sentinel,
+ .elem_type = elem_type,
+ }, .{});
+}
+
fn unwrapOptional(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.SimpleSuffixOp) InnerError!*zir.Inst {
const tree = scope.tree();
const src = tree.token_locs[node.rtoken].start;
src-self-hosted/Module.zig
@@ -2902,7 +2902,7 @@ pub fn floatSub(self: *Module, scope: *Scope, float_type: Type, src: usize, lhs:
return Value.initPayload(val_payload);
}
-pub fn singlePtrType(self: *Module, scope: *Scope, src: usize, mutable: bool, elem_ty: Type) error{OutOfMemory}!Type {
+pub fn singlePtrType(self: *Module, scope: *Scope, src: usize, mutable: bool, elem_ty: Type) Allocator.Error!Type {
const type_payload = try scope.arena().create(Type.Payload.Pointer);
type_payload.* = .{
.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
return Type.initPayload(&type_payload.base);
}
+pub fn optionalType(self: *Module, scope: *Scope, child_type: Type) Allocator.Error!Type {
+ return Type.initPayload(switch (child_type.tag()) {
+ .single_const_pointer => blk: {
+ const payload = try scope.arena().create(Type.Payload.Pointer);
+ payload.* = .{
+ .base = .{ .tag = .optional_single_const_pointer },
+ .pointee_type = child_type.elemType(),
+ };
+ break :blk &payload.base;
+ },
+ .single_mut_pointer => blk: {
+ const payload = try scope.arena().create(Type.Payload.Pointer);
+ payload.* = .{
+ .base = .{ .tag = .optional_single_mut_pointer },
+ .pointee_type = child_type.elemType(),
+ };
+ break :blk &payload.base;
+ },
+ else => blk: {
+ const payload = try scope.arena().create(Type.Payload.Optional);
+ payload.* = .{
+ .child_type = child_type,
+ };
+ break :blk &payload.base;
+ },
+ });
+}
+
+pub fn arrayType(self: *Module, scope: *Scope, len: u64, sentinel: ?Value, elem_type: Type) Allocator.Error!Type {
+ if (elem_type.eql(Type.initTag(.u8))) {
+ if (sentinel) |some| {
+ if (some.eql(Value.initTag(.zero))) {
+ const payload = try scope.arena().create(Type.Payload.Array_u8_Sentinel0);
+ payload.* = .{
+ .len = len,
+ };
+ return Type.initPayload(&payload.base);
+ }
+ } else {
+ const payload = try scope.arena().create(Type.Payload.Array_u8);
+ payload.* = .{
+ .len = len,
+ };
+ return Type.initPayload(&payload.base);
+ }
+ }
+
+ if (sentinel) |some| {
+ const payload = try scope.arena().create(Type.Payload.ArraySentinel);
+ payload.* = .{
+ .len = len,
+ .sentinel = some,
+ .elem_type = elem_type,
+ };
+ return Type.initPayload(&payload.base);
+ }
+
+ const payload = try scope.arena().create(Type.Payload.Array);
+ payload.* = .{
+ .len = len,
+ .elem_type = elem_type,
+ };
+ return Type.initPayload(&payload.base);
+}
+
pub fn dumpInst(self: *Module, scope: *Scope, inst: *Inst) void {
const zir_module = scope.namespace();
const source = zir_module.getSource(self) catch @panic("dumpInst failed to get source");
src-self-hosted/type.zig
@@ -65,7 +65,7 @@ pub const Type = extern union {
.fn_ccc_void_no_args => return .Fn,
.function => return .Fn,
- .array, .array_u8_sentinel_0 => return .Array,
+ .array, .array_u8_sentinel_0, .array_u8, .array_sentinel => return .Array,
.single_const_pointer => return .Pointer,
.single_mut_pointer => return .Pointer,
.single_const_pointer_to_comptime_int => return .Pointer,
@@ -330,6 +330,7 @@ pub const Type = extern union {
=> unreachable,
.array_u8_sentinel_0 => return self.copyPayloadShallow(allocator, Payload.Array_u8_Sentinel0),
+ .array_u8 => return self.copyPayloadShallow(allocator, Payload.Array_u8),
.array => {
const payload = @fieldParentPtr(Payload.Array, "base", self.ptr_otherwise);
const new_payload = try allocator.create(Payload.Array);
@@ -340,6 +341,17 @@ pub const Type = extern union {
};
return Type{ .ptr_otherwise = &new_payload.base };
},
+ .array_sentinel => {
+ const payload = @fieldParentPtr(Payload.ArraySentinel, "base", self.ptr_otherwise);
+ const new_payload = try allocator.create(Payload.ArraySentinel);
+ new_payload.* = .{
+ .base = payload.base,
+ .len = payload.len,
+ .sentinel = try payload.sentinel.copy(allocator),
+ .elem_type = try payload.elem_type.copy(allocator),
+ };
+ return Type{ .ptr_otherwise = &new_payload.base };
+ },
.int_signed => return self.copyPayloadShallow(allocator, Payload.IntSigned),
.int_unsigned => return self.copyPayloadShallow(allocator, Payload.IntUnsigned),
.function => {
@@ -445,6 +457,10 @@ pub const Type = extern union {
try payload.return_type.format("", .{}, out_stream);
},
+ .array_u8 => {
+ const payload = @fieldParentPtr(Payload.Array_u8, "base", ty.ptr_otherwise);
+ return out_stream.print("[{}]u8", .{payload.len});
+ },
.array_u8_sentinel_0 => {
const payload = @fieldParentPtr(Payload.Array_u8_Sentinel0, "base", ty.ptr_otherwise);
return out_stream.print("[{}:0]u8", .{payload.len});
@@ -455,6 +471,12 @@ pub const Type = extern union {
ty = payload.elem_type;
continue;
},
+ .array_sentinel => {
+ const payload = @fieldParentPtr(Payload.ArraySentinel, "base", ty.ptr_otherwise);
+ try out_stream.print("[{}:{}]", .{ payload.len, payload.sentinel });
+ ty = payload.elem_type;
+ continue;
+ },
.single_const_pointer => {
const payload = @fieldParentPtr(Payload.Pointer, "base", ty.ptr_otherwise);
try out_stream.writeAll("*const ");
@@ -588,6 +610,8 @@ pub const Type = extern union {
=> true,
// TODO lazy types
.array => self.elemType().hasCodeGenBits() and self.arrayLen() != 0,
+ .array_u8 => self.arrayLen() != 0,
+ .array_sentinel => self.elemType().hasCodeGenBits(),
.single_const_pointer => self.elemType().hasCodeGenBits(),
.single_mut_pointer => self.elemType().hasCodeGenBits(),
.int_signed => self.cast(Payload.IntSigned).?.bits == 0,
@@ -616,6 +640,7 @@ pub const Type = extern union {
.i8,
.bool,
.array_u8_sentinel_0,
+ .array_u8,
=> return 1,
.fn_noreturn_no_args, // represents machine code; not a pointer
@@ -659,7 +684,7 @@ pub const Type = extern union {
.anyerror => return 2, // TODO revisit this when we have the concept of the error tag type
- .array => return self.cast(Payload.Array).?.elem_type.abiAlignment(target),
+ .array, .array_sentinel => return self.elemType().abiAlignment(target),
.int_signed, .int_unsigned => {
const bits: u16 = if (self.cast(Payload.IntSigned)) |pl|
@@ -717,12 +742,18 @@ pub const Type = extern union {
.bool,
=> return 1,
- .array_u8_sentinel_0 => @fieldParentPtr(Payload.Array_u8_Sentinel0, "base", self.ptr_otherwise).len,
+ .array_u8 => @fieldParentPtr(Payload.Array_u8_Sentinel0, "base", self.ptr_otherwise).len,
+ .array_u8_sentinel_0 => @fieldParentPtr(Payload.Array_u8_Sentinel0, "base", self.ptr_otherwise).len + 1,
.array => {
const payload = @fieldParentPtr(Payload.Array, "base", self.ptr_otherwise);
const elem_size = std.math.max(payload.elem_type.abiAlignment(target), payload.elem_type.abiSize(target));
return payload.len * elem_size;
},
+ .array_sentinel => {
+ const payload = @fieldParentPtr(Payload.ArraySentinel, "base", self.ptr_otherwise);
+ const elem_size = std.math.max(payload.elem_type.abiAlignment(target), payload.elem_type.abiSize(target));
+ return (payload.len + 1) * elem_size;
+ },
.i16, .u16 => return 2,
.i32, .u32 => return 4,
.i64, .u64 => return 8,
@@ -818,6 +849,8 @@ pub const Type = extern union {
.@"null",
.@"undefined",
.array,
+ .array_sentinel,
+ .array_u8,
.array_u8_sentinel_0,
.const_slice_u8,
.fn_noreturn_no_args,
@@ -875,6 +908,8 @@ pub const Type = extern union {
.@"null",
.@"undefined",
.array,
+ .array_sentinel,
+ .array_u8,
.array_u8_sentinel_0,
.single_const_pointer,
.single_mut_pointer,
@@ -931,6 +966,8 @@ pub const Type = extern union {
.@"null",
.@"undefined",
.array,
+ .array_sentinel,
+ .array_u8,
.array_u8_sentinel_0,
.fn_noreturn_no_args,
.fn_void_no_args,
@@ -988,6 +1025,8 @@ pub const Type = extern union {
.@"null",
.@"undefined",
.array,
+ .array_sentinel,
+ .array_u8,
.array_u8_sentinel_0,
.fn_noreturn_no_args,
.fn_void_no_args,
@@ -1072,9 +1111,10 @@ pub const Type = extern union {
=> unreachable,
.array => self.cast(Payload.Array).?.elem_type,
+ .array_sentinel => self.cast(Payload.ArraySentinel).?.elem_type,
.single_const_pointer => self.castPointer().?.pointee_type,
.single_mut_pointer => self.castPointer().?.pointee_type,
- .array_u8_sentinel_0, .const_slice_u8 => Type.initTag(.u8),
+ .array_u8, .array_u8_sentinel_0, .const_slice_u8 => Type.initTag(.u8),
.single_const_pointer_to_comptime_int => Type.initTag(.comptime_int),
};
}
@@ -1176,6 +1216,8 @@ pub const Type = extern union {
=> unreachable,
.array => self.cast(Payload.Array).?.len,
+ .array_sentinel => self.cast(Payload.ArraySentinel).?.len,
+ .array_u8 => self.cast(Payload.Array_u8).?.len,
.array_u8_sentinel_0 => self.cast(Payload.Array_u8_Sentinel0).?.len,
};
}
@@ -1232,7 +1274,8 @@ pub const Type = extern union {
.optional_single_const_pointer,
=> unreachable,
- .array => return null,
+ .array, .array_u8 => return null,
+ .array_sentinel => return self.cast(Payload.ArraySentinel).?.sentinel,
.array_u8_sentinel_0 => return Value.initTag(.zero),
};
}
@@ -1266,10 +1309,12 @@ pub const Type = extern union {
.fn_ccc_void_no_args,
.function,
.array,
+ .array_sentinel,
+ .array_u8,
+ .array_u8_sentinel_0,
.single_const_pointer,
.single_mut_pointer,
.single_const_pointer_to_comptime_int,
- .array_u8_sentinel_0,
.const_slice_u8,
.int_unsigned,
.u8,
@@ -1324,10 +1369,12 @@ pub const Type = extern union {
.fn_ccc_void_no_args,
.function,
.array,
+ .array_sentinel,
+ .array_u8,
+ .array_u8_sentinel_0,
.single_const_pointer,
.single_mut_pointer,
.single_const_pointer_to_comptime_int,
- .array_u8_sentinel_0,
.const_slice_u8,
.int_signed,
.i8,
@@ -1382,10 +1429,12 @@ pub const Type = extern union {
.fn_ccc_void_no_args,
.function,
.array,
+ .array_sentinel,
+ .array_u8,
+ .array_u8_sentinel_0,
.single_const_pointer,
.single_mut_pointer,
.single_const_pointer_to_comptime_int,
- .array_u8_sentinel_0,
.const_slice_u8,
.optional,
.optional_single_mut_pointer,
@@ -1438,10 +1487,12 @@ pub const Type = extern union {
.fn_ccc_void_no_args,
.function,
.array,
+ .array_sentinel,
+ .array_u8,
+ .array_u8_sentinel_0,
.single_const_pointer,
.single_mut_pointer,
.single_const_pointer_to_comptime_int,
- .array_u8_sentinel_0,
.const_slice_u8,
.int_unsigned,
.int_signed,
@@ -1523,10 +1574,12 @@ pub const Type = extern union {
.@"null",
.@"undefined",
.array,
+ .array_sentinel,
+ .array_u8,
+ .array_u8_sentinel_0,
.single_const_pointer,
.single_mut_pointer,
.single_const_pointer_to_comptime_int,
- .array_u8_sentinel_0,
.const_slice_u8,
.u8,
.i8,
@@ -1584,10 +1637,12 @@ pub const Type = extern union {
.@"null",
.@"undefined",
.array,
+ .array_sentinel,
+ .array_u8,
+ .array_u8_sentinel_0,
.single_const_pointer,
.single_mut_pointer,
.single_const_pointer_to_comptime_int,
- .array_u8_sentinel_0,
.const_slice_u8,
.u8,
.i8,
@@ -1644,10 +1699,12 @@ pub const Type = extern union {
.@"null",
.@"undefined",
.array,
+ .array_sentinel,
+ .array_u8,
+ .array_u8_sentinel_0,
.single_const_pointer,
.single_mut_pointer,
.single_const_pointer_to_comptime_int,
- .array_u8_sentinel_0,
.const_slice_u8,
.u8,
.i8,
@@ -1704,10 +1761,12 @@ pub const Type = extern union {
.@"null",
.@"undefined",
.array,
+ .array_sentinel,
+ .array_u8,
+ .array_u8_sentinel_0,
.single_const_pointer,
.single_mut_pointer,
.single_const_pointer_to_comptime_int,
- .array_u8_sentinel_0,
.const_slice_u8,
.u8,
.i8,
@@ -1761,10 +1820,12 @@ pub const Type = extern union {
.@"null",
.@"undefined",
.array,
+ .array_sentinel,
+ .array_u8,
+ .array_u8_sentinel_0,
.single_const_pointer,
.single_mut_pointer,
.single_const_pointer_to_comptime_int,
- .array_u8_sentinel_0,
.const_slice_u8,
.u8,
.i8,
@@ -1818,10 +1879,12 @@ pub const Type = extern union {
.@"null",
.@"undefined",
.array,
+ .array_sentinel,
+ .array_u8,
+ .array_u8_sentinel_0,
.single_const_pointer,
.single_mut_pointer,
.single_const_pointer_to_comptime_int,
- .array_u8_sentinel_0,
.const_slice_u8,
.u8,
.i8,
@@ -1895,10 +1958,12 @@ pub const Type = extern union {
.fn_ccc_void_no_args,
.function,
.array,
+ .array_sentinel,
+ .array_u8,
+ .array_u8_sentinel_0,
.single_const_pointer,
.single_mut_pointer,
.single_const_pointer_to_comptime_int,
- .array_u8_sentinel_0,
.const_slice_u8,
.optional,
.optional_single_mut_pointer,
@@ -1944,6 +2009,7 @@ pub const Type = extern union {
.fn_ccc_void_no_args,
.function,
.single_const_pointer_to_comptime_int,
+ .array_sentinel,
.array_u8_sentinel_0,
.const_slice_u8,
.c_void,
@@ -1971,11 +2037,10 @@ pub const Type = extern union {
return null;
}
},
- .array => {
- const array = ty.cast(Payload.Array).?;
- if (array.len == 0)
+ .array, .array_u8 => {
+ if (ty.arrayLen() == 0)
return Value.initTag(.empty_array);
- ty = array.elem_type;
+ ty = ty.elemType();
continue;
},
.single_const_pointer, .single_mut_pointer => {
@@ -2022,7 +2087,6 @@ pub const Type = extern union {
.fn_ccc_void_no_args,
.function,
.single_const_pointer_to_comptime_int,
- .array_u8_sentinel_0,
.const_slice_u8,
.c_void,
.void,
@@ -2032,6 +2096,9 @@ pub const Type = extern union {
.int_unsigned,
.int_signed,
.array,
+ .array_sentinel,
+ .array_u8,
+ .array_u8_sentinel_0,
.single_const_pointer,
.single_mut_pointer,
.optional,
@@ -2090,8 +2157,10 @@ pub const Type = extern union {
const_slice_u8, // See last_no_payload_tag below.
// After this, the tag requires a payload.
+ array_u8,
array_u8_sentinel_0,
array,
+ array_sentinel,
single_const_pointer,
single_mut_pointer,
int_signed,
@@ -2114,11 +2183,25 @@ pub const Type = extern union {
len: u64,
};
+ pub const Array_u8 = struct {
+ base: Payload = Payload{ .tag = .array_u8 },
+
+ len: u64,
+ };
+
pub const Array = struct {
base: Payload = Payload{ .tag = .array },
+ len: u64,
elem_type: Type,
+ };
+
+ pub const ArraySentinel = struct {
+ base: Payload = Payload{ .tag = .array_sentinel },
+
len: u64,
+ sentinel: Value,
+ elem_type: Type,
};
pub const Pointer = struct {
src-self-hosted/zir.zig
@@ -47,6 +47,10 @@ pub const Inst = struct {
array_cat,
/// Array multiplication `a ** b`
array_mul,
+ /// Create an array type
+ array_type,
+ /// Create an array type with sentinel
+ array_type_sentinel,
/// Function parameter value. These must be first in a function's main block,
/// in respective order with the parameters.
arg,
@@ -268,6 +272,7 @@ pub const Inst = struct {
.addwrap,
.array_cat,
.array_mul,
+ .array_type,
.bitand,
.bitor,
.div,
@@ -294,6 +299,7 @@ pub const Inst = struct {
=> BinOp,
.arg => Arg,
+ .array_type_sentinel => ArrayTypeSentinel,
.block => Block,
.@"break" => Break,
.breakvoid => BreakVoid,
@@ -333,6 +339,8 @@ pub const Inst = struct {
.alloc_inferred,
.array_cat,
.array_mul,
+ .array_type,
+ .array_type_sentinel,
.arg,
.as,
.@"asm",
@@ -849,6 +857,18 @@ pub const Inst = struct {
sentinel: ?*Inst = null,
},
};
+
+ pub const ArrayTypeSentinel = struct {
+ pub const base_tag = Tag.array_type_sentinel;
+ base: Inst,
+
+ positionals: struct {
+ len: *Inst,
+ sentinel: *Inst,
+ elem_type: *Inst,
+ },
+ kw_args: struct {},
+ };
};
pub const ErrorMsg = struct {
src-self-hosted/zir_sema.zig
@@ -113,6 +113,8 @@ pub fn analyzeInst(mod: *Module, scope: *Scope, old_inst: *zir.Inst) InnerError!
.unwrap_err_safe => return analyzeInstUnwrapErr(mod, scope, old_inst.castTag(.unwrap_err_safe).?, true),
.unwrap_err_unsafe => return analyzeInstUnwrapErr(mod, scope, old_inst.castTag(.unwrap_err_unsafe).?, false),
.ensure_err_payload_void => return analyzeInstEnsureErrPayloadVoid(mod, scope, old_inst.castTag(.ensure_err_payload_void).?),
+ .array_type => return analyzeInstArrayType(mod, scope, old_inst.castTag(.array_type).?),
+ .array_type_sentinel => return analyzeInstArrayTypeSentinel(mod, scope, old_inst.castTag(.array_type_sentinel).?),
}
}
@@ -676,31 +678,24 @@ fn analyzeInstIntType(mod: *Module, scope: *Scope, inttype: *zir.Inst.IntType) I
fn analyzeInstOptionalType(mod: *Module, scope: *Scope, optional: *zir.Inst.UnOp) InnerError!*Inst {
const child_type = try resolveType(mod, scope, optional.positionals.operand);
- return mod.constType(scope, optional.base.src, Type.initPayload(switch (child_type.tag()) {
- .single_const_pointer => blk: {
- const payload = try scope.arena().create(Type.Payload.Pointer);
- payload.* = .{
- .base = .{ .tag = .optional_single_const_pointer },
- .pointee_type = child_type.elemType(),
- };
- break :blk &payload.base;
- },
- .single_mut_pointer => blk: {
- const payload = try scope.arena().create(Type.Payload.Pointer);
- payload.* = .{
- .base = .{ .tag = .optional_single_mut_pointer },
- .pointee_type = child_type.elemType(),
- };
- break :blk &payload.base;
- },
- else => blk: {
- const payload = try scope.arena().create(Type.Payload.Optional);
- payload.* = .{
- .child_type = child_type,
- };
- break :blk &payload.base;
- },
- }));
+ return mod.constType(scope, optional.base.src, try mod.optionalType(scope, child_type));
+}
+
+fn analyzeInstArrayType(mod: *Module, scope: *Scope, array: *zir.Inst.BinOp) InnerError!*Inst {
+ // TODO these should be lazily evaluated
+ const len = try resolveInstConst(mod, scope, array.positionals.lhs);
+ const elem_type = try resolveType(mod, scope, array.positionals.rhs);
+
+ return mod.constType(scope, array.base.src, try mod.arrayType(scope, len.val.toUnsignedInt(), null, elem_type));
+}
+
+fn analyzeInstArrayTypeSentinel(mod: *Module, scope: *Scope, array: *zir.Inst.ArrayTypeSentinel) InnerError!*Inst {
+ // TODO these should be lazily evaluated
+ const len = try resolveInstConst(mod, scope, array.positionals.len);
+ const sentinel = try resolveInstConst(mod, scope, array.positionals.sentinel);
+ const elem_type = try resolveType(mod, scope, array.positionals.elem_type);
+
+ return mod.constType(scope, array.base.src, try mod.arrayType(scope, len.val.toUnsignedInt(), sentinel.val, elem_type));
}
fn analyzeInstUnwrapOptional(mod: *Module, scope: *Scope, unwrap: *zir.Inst.UnOp, safety_check: bool) InnerError!*Inst {