Commit 16d7db59ed
Changed files (6)
src-self-hosted
src-self-hosted/astgen.zig
@@ -267,11 +267,12 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node) InnerEr
.MultilineStringLiteral => return rlWrap(mod, scope, rl, try multilineStrLiteral(mod, scope, node.castTag(.MultilineStringLiteral).?)),
.CharLiteral => return rlWrap(mod, scope, rl, try charLiteral(mod, scope, node.castTag(.CharLiteral).?)),
.SliceType => return rlWrap(mod, scope, rl, try sliceType(mod, scope, node.castTag(.SliceType).?)),
+ .ErrorUnion => return rlWrap(mod, scope, rl, try typeInixOp(mod, scope, node.castTag(.ErrorUnion).?, .error_union_type)),
+ .MergeErrorSets => return rlWrap(mod, scope, rl, try typeInixOp(mod, scope, node.castTag(.MergeErrorSets).?, .merge_error_sets)),
+ .AnyFrameType => return rlWrap(mod, scope, rl, try anyFrameType(mod, scope, node.castTag(.AnyFrameType).?)),
.Defer => return mod.failNode(scope, node, "TODO implement astgen.expr for .Defer", .{}),
.Catch => return mod.failNode(scope, node, "TODO implement astgen.expr for .Catch", .{}),
- .ErrorUnion => return mod.failNode(scope, node, "TODO implement astgen.expr for .ErrorUnion", .{}),
- .MergeErrorSets => return mod.failNode(scope, node, "TODO implement astgen.expr for .MergeErrorSets", .{}),
.Range => return mod.failNode(scope, node, "TODO implement astgen.expr for .Range", .{}),
.OrElse => return mod.failNode(scope, node, "TODO implement astgen.expr for .OrElse", .{}),
.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
.AnyType => return mod.failNode(scope, node, "TODO implement astgen.expr for .AnyType", .{}),
.ErrorType => return mod.failNode(scope, node, "TODO implement astgen.expr for .ErrorType", .{}),
.FnProto => return mod.failNode(scope, node, "TODO implement astgen.expr for .FnProto", .{}),
- .AnyFrameType => return mod.failNode(scope, node, "TODO implement astgen.expr for .AnyFrameType", .{}),
.ErrorSetDecl => return mod.failNode(scope, node, "TODO implement astgen.expr for .ErrorSetDecl", .{}),
.ContainerDecl => return mod.failNode(scope, node, "TODO implement astgen.expr for .ContainerDecl", .{}),
.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
const tree = scope.tree();
const src = tree.token_locs[node.op_token].start;
- const lhs = addZIRInstConst(mod, scope, src, .{
+ const lhs = try addZIRInstConst(mod, scope, src, .{
.ty = Type.initTag(.comptime_int),
.val = Value.initTag(.zero),
});
const rhs = try expr(mod, scope, .none, node.rhs);
- const result = try addZIRBinOp(mod, scope, src, op_inst_tag, lhs, rhs);
- return rlWrap(mod, scope, rl, result);
+ return addZIRBinOp(mod, scope, src, op_inst_tag, lhs, rhs);
}
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
}, .{});
}
+fn anyFrameType(mod: *Module, scope: *Scope, node: *ast.Node.AnyFrameType) InnerError!*zir.Inst {
+ const tree = scope.tree();
+ const src = tree.token_locs[node.anyframe_token].start;
+ if (node.result) |some| {
+ const meta_type = try addZIRInstConst(mod, scope, src, .{
+ .ty = Type.initTag(.type),
+ .val = Value.initTag(.type_type),
+ });
+ const return_type = try expr(mod, scope, .{ .ty = meta_type}, some.return_type);
+ return addZIRUnOp(mod, scope, src, .anyframe_type, return_type);
+ } else {
+ return addZIRInstConst(mod, scope, src, .{
+ .ty = Type.initTag(.type),
+ .val = Value.initTag(.anyframe_type),
+ });
+ }
+}
+
+fn typeInixOp(mod: *Module, scope: *Scope, node: *ast.Node.SimpleInfixOp, op_inst_tag: zir.Inst.Tag) InnerError!*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 error_set = try expr(mod, scope, .{ .ty = meta_type }, node.lhs);
+ const payload = try expr(mod, scope, .{ .ty = meta_type }, node.rhs);
+ return addZIRBinOp(mod, scope, src, op_inst_tag, error_set, payload);
+}
+
fn enumLiteral(mod: *Module, scope: *Scope, node: *ast.Node.EnumLiteral) !*zir.Inst {
const tree = scope.tree();
const src = tree.token_locs[node.name].start;
src-self-hosted/Module.zig
@@ -3309,6 +3309,28 @@ pub fn arrayType(self: *Module, scope: *Scope, len: u64, sentinel: ?Value, elem_
return Type.initPayload(&payload.base);
}
+pub fn errorUnionType(self: *Module, scope: *Scope, error_set: Type, payload: Type) Allocator.Error!Type {
+ assert(error_set.zigTypeTag() == .ErrorSet);
+ if (error_set.eql(Type.initTag(.anyerror)) and payload.eql(Type.initTag(.void))) {
+ return Type.initTag(.anyerror_void_error_union);
+ }
+
+ const result = try scope.arena().create(Type.Payload.ErrorUnion);
+ result.* = .{
+ .error_set = error_set,
+ .payload = payload,
+ };
+ return Type.initPayload(&result.base);
+}
+
+pub fn anyframeType(self: *Module, scope: *Scope, return_type: Type) Allocator.Error!Type {
+ const result = try scope.arena().create(Type.Payload.AnyFrame);
+ result.* = .{
+ .return_type = return_type,
+ };
+ return Type.initPayload(&result.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
@@ -84,6 +84,10 @@ pub const Type = extern union {
.optional_single_mut_pointer,
=> return .Optional,
.enum_literal => return .EnumLiteral,
+
+ .anyerror_void_error_union, .error_union => return .ErrorUnion,
+
+ .anyframe_T, .@"anyframe" => return .AnyFrame,
}
}
@@ -151,6 +155,9 @@ pub const Type = extern union {
.ComptimeInt => return true,
.Undefined => return true,
.Null => return true,
+ .AnyFrame => {
+ return a.elemType().eql(b.elemType());
+ },
.Pointer => {
// Hot path for common case:
if (a.castPointer()) |a_payload| {
@@ -225,7 +232,6 @@ pub const Type = extern union {
.BoundFn,
.Opaque,
.Frame,
- .AnyFrame,
.Vector,
=> std.debug.panic("TODO implement Type equality comparison of {} and {}", .{ a, b }),
}
@@ -343,6 +349,8 @@ pub const Type = extern union {
.single_const_pointer_to_comptime_int,
.const_slice_u8,
.enum_literal,
+ .anyerror_void_error_union,
+ .@"anyframe",
=> unreachable,
.array_u8_sentinel_0 => return self.copyPayloadShallow(allocator, Payload.Array_u8_Sentinel0),
@@ -397,6 +405,7 @@ pub const Type = extern union {
.optional_single_mut_pointer,
.optional_single_const_pointer,
=> return self.copyPayloadSingleField(allocator, Payload.PointerSimple, "pointee_type"),
+ .anyframe_T => return self.copyPayloadSingleField(allocator, Payload.AnyFrame, "return_type"),
.pointer => {
const payload = @fieldParentPtr(Payload.Pointer, "base", self.ptr_otherwise);
@@ -416,6 +425,17 @@ pub const Type = extern union {
};
return Type{ .ptr_otherwise = &new_payload.base };
},
+ .error_union => {
+ const payload = @fieldParentPtr(Payload.ErrorUnion, "base", self.ptr_otherwise);
+ const new_payload = try allocator.create(Payload.ErrorUnion);
+ new_payload.* = .{
+ .base = payload.base,
+
+ .error_set = try payload.error_set.copy(allocator),
+ .payload = try payload.payload.copy(allocator),
+ };
+ return Type{ .ptr_otherwise = &new_payload.base };
+ },
}
}
@@ -482,6 +502,8 @@ pub const Type = extern union {
.@"null" => return out_stream.writeAll("@TypeOf(null)"),
.@"undefined" => return out_stream.writeAll("@TypeOf(undefined)"),
+ .@"anyframe" => return out_stream.writeAll("anyframe"),
+ .anyerror_void_error_union => return out_stream.writeAll("anyerror!void"),
.const_slice_u8 => return out_stream.writeAll("[]const u8"),
.fn_noreturn_no_args => return out_stream.writeAll("fn() noreturn"),
.fn_void_no_args => return out_stream.writeAll("fn() void"),
@@ -500,6 +522,12 @@ pub const Type = extern union {
continue;
},
+ .anyframe_T => {
+ const payload = @fieldParentPtr(Payload.AnyFrame, "base", ty.ptr_otherwise);
+ try out_stream.print("anyframe->", .{});
+ ty = payload.return_type;
+ continue;
+ },
.array_u8 => {
const payload = @fieldParentPtr(Payload.Array_u8, "base", ty.ptr_otherwise);
return out_stream.print("[{}]u8", .{payload.len});
@@ -622,6 +650,13 @@ pub const Type = extern union {
ty = payload.pointee_type;
continue;
},
+ .error_union => {
+ const payload = @fieldParentPtr(Payload.ErrorUnion, "base", ty.ptr_otherwise);
+ try payload.error_set.format("", .{}, out_stream);
+ try out_stream.writeAll("!");
+ ty = payload.payload;
+ continue;
+ },
}
unreachable;
}
@@ -715,6 +750,9 @@ pub const Type = extern union {
.optional,
.optional_single_mut_pointer,
.optional_single_const_pointer,
+ .@"anyframe",
+ .anyframe_T,
+ .anyerror_void_error_union,
=> true,
// TODO lazy types
.array => self.elemType().hasCodeGenBits() and self.arrayLen() != 0,
@@ -723,6 +761,11 @@ pub const Type = extern union {
.int_signed => self.cast(Payload.IntSigned).?.bits == 0,
.int_unsigned => self.cast(Payload.IntUnsigned).?.bits == 0,
+ .error_union => {
+ const payload = self.cast(Payload.ErrorUnion).?;
+ return payload.error_set.hasCodeGenBits() or payload.payload.hasCodeGenBits();
+ },
+
.c_void,
.void,
.type,
@@ -779,6 +822,8 @@ pub const Type = extern union {
.mut_slice,
.optional_single_const_pointer,
.optional_single_mut_pointer,
+ .@"anyframe",
+ .anyframe_T,
=> return @divExact(target.cpu.arch.ptrBitWidth(), 8),
.pointer => {
@@ -803,7 +848,7 @@ pub const Type = extern union {
.f128 => return 16,
.c_longdouble => return 16,
- .anyerror => return 2, // TODO revisit this when we have the concept of the error tag type
+ .anyerror_void_error_union, .anyerror => return 2, // TODO revisit this when we have the concept of the error tag type
.array, .array_sentinel => return self.elemType().abiAlignment(target),
@@ -829,6 +874,16 @@ pub const Type = extern union {
return child_type.abiAlignment(target);
},
+ .error_union => {
+ const payload = self.cast(Payload.ErrorUnion).?;
+ if (!payload.error_set.hasCodeGenBits()) {
+ return payload.payload.abiAlignment(target);
+ } else if (!payload.payload.hasCodeGenBits()) {
+ return payload.error_set.abiAlignment(target);
+ }
+ @panic("TODO abiAlignment error union");
+ },
+
.c_void,
.void,
.type,
@@ -882,12 +937,15 @@ pub const Type = extern union {
.i32, .u32 => return 4,
.i64, .u64 => return 8,
- .isize, .usize => return @divExact(target.cpu.arch.ptrBitWidth(), 8),
+ .@"anyframe", .anyframe_T, .isize, .usize => return @divExact(target.cpu.arch.ptrBitWidth(), 8),
.const_slice,
.mut_slice,
- .const_slice_u8,
- => return @divExact(target.cpu.arch.ptrBitWidth(), 8) * 2,
+ => {
+ if (self.elemType().hasCodeGenBits()) return @divExact(target.cpu.arch.ptrBitWidth(), 8) * 2;
+ return @divExact(target.cpu.arch.ptrBitWidth(), 8);
+ },
+ .const_slice_u8 => return @divExact(target.cpu.arch.ptrBitWidth(), 8) * 2,
.optional_single_const_pointer,
.optional_single_mut_pointer,
@@ -923,7 +981,7 @@ pub const Type = extern union {
.f128 => return 16,
.c_longdouble => return 16,
- .anyerror => return 2, // TODO revisit this when we have the concept of the error tag type
+ .anyerror_void_error_union, .anyerror => return 2, // TODO revisit this when we have the concept of the error tag type
.int_signed, .int_unsigned => {
const bits: u16 = if (self.cast(Payload.IntSigned)) |pl|
@@ -950,6 +1008,18 @@ pub const Type = extern union {
// to the child type's ABI alignment.
return child_type.abiAlignment(target) + child_type.abiSize(target);
},
+
+ .error_union => {
+ const payload = self.cast(Payload.ErrorUnion).?;
+ if (!payload.error_set.hasCodeGenBits() and !payload.payload.hasCodeGenBits()) {
+ return 0;
+ } else if (!payload.error_set.hasCodeGenBits()) {
+ return payload.payload.abiSize(target);
+ } else if (!payload.payload.hasCodeGenBits()) {
+ return payload.error_set.abiSize(target);
+ }
+ @panic("TODO abiSize error union");
+ },
};
}
@@ -1010,6 +1080,10 @@ pub const Type = extern union {
.c_mut_pointer,
.const_slice,
.mut_slice,
+ .error_union,
+ .@"anyframe",
+ .anyframe_T,
+ .anyerror_void_error_union,
=> false,
.single_const_pointer,
@@ -1078,6 +1152,10 @@ pub const Type = extern union {
.optional_single_mut_pointer,
.optional_single_const_pointer,
.enum_literal,
+ .error_union,
+ .@"anyframe",
+ .anyframe_T,
+ .anyerror_void_error_union,
=> false,
.const_slice,
@@ -1143,6 +1221,10 @@ pub const Type = extern union {
.optional_single_const_pointer,
.enum_literal,
.mut_slice,
+ .error_union,
+ .@"anyframe",
+ .anyframe_T,
+ .anyerror_void_error_union,
=> false,
.single_const_pointer,
@@ -1217,6 +1299,10 @@ pub const Type = extern union {
.optional_single_mut_pointer,
.optional_single_const_pointer,
.enum_literal,
+ .error_union,
+ .@"anyframe",
+ .anyframe_T,
+ .anyerror_void_error_union,
=> false,
.pointer => {
@@ -1328,6 +1414,10 @@ pub const Type = extern union {
.optional_single_const_pointer,
.optional_single_mut_pointer,
.enum_literal,
+ .error_union,
+ .@"anyframe",
+ .anyframe_T,
+ .anyerror_void_error_union,
=> unreachable,
.array => self.cast(Payload.Array).?.elem_type,
@@ -1449,6 +1539,10 @@ pub const Type = extern union {
.optional_single_mut_pointer,
.optional_single_const_pointer,
.enum_literal,
+ .error_union,
+ .@"anyframe",
+ .anyframe_T,
+ .anyerror_void_error_union,
=> unreachable,
.array => self.cast(Payload.Array).?.len,
@@ -1516,6 +1610,10 @@ pub const Type = extern union {
.optional_single_mut_pointer,
.optional_single_const_pointer,
.enum_literal,
+ .error_union,
+ .@"anyframe",
+ .anyframe_T,
+ .anyerror_void_error_union,
=> unreachable,
.array, .array_u8 => return null,
@@ -1581,6 +1679,10 @@ pub const Type = extern union {
.optional_single_mut_pointer,
.optional_single_const_pointer,
.enum_literal,
+ .error_union,
+ .@"anyframe",
+ .anyframe_T,
+ .anyerror_void_error_union,
=> false,
.int_signed,
@@ -1649,6 +1751,10 @@ pub const Type = extern union {
.optional_single_mut_pointer,
.optional_single_const_pointer,
.enum_literal,
+ .error_union,
+ .@"anyframe",
+ .anyframe_T,
+ .anyerror_void_error_union,
=> false,
.int_unsigned,
@@ -1707,6 +1813,10 @@ pub const Type = extern union {
.optional_single_mut_pointer,
.optional_single_const_pointer,
.enum_literal,
+ .error_union,
+ .@"anyframe",
+ .anyframe_T,
+ .anyerror_void_error_union,
=> unreachable,
.int_unsigned => .{ .signed = false, .bits = self.cast(Payload.IntUnsigned).?.bits },
@@ -1783,6 +1893,10 @@ pub const Type = extern union {
.optional_single_mut_pointer,
.optional_single_const_pointer,
.enum_literal,
+ .error_union,
+ .@"anyframe",
+ .anyframe_T,
+ .anyerror_void_error_union,
=> false,
.usize,
@@ -1888,6 +2002,10 @@ pub const Type = extern union {
.optional_single_mut_pointer,
.optional_single_const_pointer,
.enum_literal,
+ .error_union,
+ .@"anyframe",
+ .anyframe_T,
+ .anyerror_void_error_union,
=> unreachable,
};
}
@@ -1959,6 +2077,10 @@ pub const Type = extern union {
.optional_single_mut_pointer,
.optional_single_const_pointer,
.enum_literal,
+ .error_union,
+ .@"anyframe",
+ .anyframe_T,
+ .anyerror_void_error_union,
=> unreachable,
}
}
@@ -2029,6 +2151,10 @@ pub const Type = extern union {
.optional_single_mut_pointer,
.optional_single_const_pointer,
.enum_literal,
+ .error_union,
+ .@"anyframe",
+ .anyframe_T,
+ .anyerror_void_error_union,
=> unreachable,
}
}
@@ -2099,6 +2225,10 @@ pub const Type = extern union {
.optional_single_mut_pointer,
.optional_single_const_pointer,
.enum_literal,
+ .error_union,
+ .@"anyframe",
+ .anyframe_T,
+ .anyerror_void_error_union,
=> unreachable,
};
}
@@ -2166,6 +2296,10 @@ pub const Type = extern union {
.optional_single_mut_pointer,
.optional_single_const_pointer,
.enum_literal,
+ .error_union,
+ .@"anyframe",
+ .anyframe_T,
+ .anyerror_void_error_union,
=> unreachable,
};
}
@@ -2233,6 +2367,10 @@ pub const Type = extern union {
.optional_single_mut_pointer,
.optional_single_const_pointer,
.enum_literal,
+ .error_union,
+ .@"anyframe",
+ .anyframe_T,
+ .anyerror_void_error_union,
=> unreachable,
};
}
@@ -2300,6 +2438,10 @@ pub const Type = extern union {
.optional_single_mut_pointer,
.optional_single_const_pointer,
.enum_literal,
+ .error_union,
+ .@"anyframe",
+ .anyframe_T,
+ .anyerror_void_error_union,
=> false,
};
}
@@ -2351,6 +2493,10 @@ pub const Type = extern union {
.optional_single_mut_pointer,
.optional_single_const_pointer,
.enum_literal,
+ .anyerror_void_error_union,
+ .anyframe_T,
+ .@"anyframe",
+ .error_union,
=> return null,
.void => return Value.initTag(.void_value),
@@ -2454,6 +2600,10 @@ pub const Type = extern union {
.optional_single_mut_pointer,
.optional_single_const_pointer,
.enum_literal,
+ .error_union,
+ .@"anyframe",
+ .anyframe_T,
+ .anyerror_void_error_union,
=> return false,
.c_const_pointer,
@@ -2511,6 +2661,8 @@ pub const Type = extern union {
fn_naked_noreturn_no_args,
fn_ccc_void_no_args,
single_const_pointer_to_comptime_int,
+ anyerror_void_error_union,
+ @"anyframe",
const_slice_u8, // See last_no_payload_tag below.
// After this, the tag requires a payload.
@@ -2533,6 +2685,8 @@ pub const Type = extern union {
optional,
optional_single_mut_pointer,
optional_single_const_pointer,
+ error_union,
+ anyframe_T,
pub const last_no_payload_tag = Tag.const_slice_u8;
pub const no_payload_count = @enumToInt(last_no_payload_tag) + 1;
@@ -2614,6 +2768,19 @@ pub const Type = extern union {
@"volatile": bool,
size: std.builtin.TypeInfo.Pointer.Size,
};
+
+ pub const ErrorUnion = struct {
+ base: Payload = .{ .tag = .error_union },
+
+ error_set: Type,
+ payload: Type,
+ };
+
+ pub const AnyFrame = struct {
+ base: Payload = .{ .tag = .anyframe_T },
+
+ return_type: Type,
+ };
};
};
src-self-hosted/value.zig
@@ -61,6 +61,7 @@ pub const Value = extern union {
single_const_pointer_to_comptime_int_type,
const_slice_u8_type,
enum_literal_type,
+ anyframe_type,
undef,
zero,
@@ -168,6 +169,7 @@ pub const Value = extern union {
.single_const_pointer_to_comptime_int_type,
.const_slice_u8_type,
.enum_literal_type,
+ .anyframe_type,
.undef,
.zero,
.void_value,
@@ -300,6 +302,7 @@ pub const Value = extern union {
.single_const_pointer_to_comptime_int_type => return out_stream.writeAll("*const comptime_int"),
.const_slice_u8_type => return out_stream.writeAll("[]const u8"),
.enum_literal_type => return out_stream.writeAll("@TypeOf(.EnumLiteral)"),
+ .anyframe_type => return out_stream.writeAll("anyframe"),
.null_value => return out_stream.writeAll("null"),
.undef => return out_stream.writeAll("undefined"),
@@ -408,6 +411,7 @@ pub const Value = extern union {
.single_const_pointer_to_comptime_int_type => Type.initTag(.single_const_pointer_to_comptime_int),
.const_slice_u8_type => Type.initTag(.const_slice_u8),
.enum_literal_type => Type.initTag(.enum_literal),
+ .anyframe_type => Type.initTag(.@"anyframe"),
.undef,
.zero,
@@ -482,6 +486,7 @@ pub const Value = extern union {
.single_const_pointer_to_comptime_int_type,
.const_slice_u8_type,
.enum_literal_type,
+ .anyframe_type,
.null_value,
.function,
.variable,
@@ -560,6 +565,7 @@ pub const Value = extern union {
.single_const_pointer_to_comptime_int_type,
.const_slice_u8_type,
.enum_literal_type,
+ .anyframe_type,
.null_value,
.function,
.variable,
@@ -638,6 +644,7 @@ pub const Value = extern union {
.single_const_pointer_to_comptime_int_type,
.const_slice_u8_type,
.enum_literal_type,
+ .anyframe_type,
.null_value,
.function,
.variable,
@@ -742,6 +749,7 @@ pub const Value = extern union {
.single_const_pointer_to_comptime_int_type,
.const_slice_u8_type,
.enum_literal_type,
+ .anyframe_type,
.null_value,
.function,
.variable,
@@ -825,6 +833,7 @@ pub const Value = extern union {
.single_const_pointer_to_comptime_int_type,
.const_slice_u8_type,
.enum_literal_type,
+ .anyframe_type,
.null_value,
.function,
.variable,
@@ -988,6 +997,7 @@ pub const Value = extern union {
.single_const_pointer_to_comptime_int_type,
.const_slice_u8_type,
.enum_literal_type,
+ .anyframe_type,
.bool_true,
.bool_false,
.null_value,
@@ -1063,6 +1073,7 @@ pub const Value = extern union {
.single_const_pointer_to_comptime_int_type,
.const_slice_u8_type,
.enum_literal_type,
+ .anyframe_type,
.null_value,
.function,
.variable,
@@ -1197,6 +1208,7 @@ pub const Value = extern union {
.single_const_pointer_to_comptime_int_type,
.const_slice_u8_type,
.enum_literal_type,
+ .anyframe_type,
.zero,
.bool_true,
.bool_false,
@@ -1276,6 +1288,7 @@ pub const Value = extern union {
.single_const_pointer_to_comptime_int_type,
.const_slice_u8_type,
.enum_literal_type,
+ .anyframe_type,
.zero,
.bool_true,
.bool_false,
@@ -1372,6 +1385,7 @@ pub const Value = extern union {
.single_const_pointer_to_comptime_int_type,
.const_slice_u8_type,
.enum_literal_type,
+ .anyframe_type,
.zero,
.empty_array,
.bool_true,
src-self-hosted/zir.zig
@@ -43,6 +43,8 @@ pub const Inst = struct {
alloc,
/// Same as `alloc` except the type is inferred.
alloc_inferred,
+ /// Create an `anyframe->T`.
+ anyframe_type,
/// Array concatenation. `a ++ b`
array_cat,
/// Array multiplication `a ** b`
@@ -135,6 +137,8 @@ pub const Inst = struct {
ensure_result_used,
/// Emits a compile error if an error is ignored.
ensure_result_non_error,
+ /// Create a `E!T` type.
+ error_union_type,
/// Export the provided Decl as the provided name in the compilation's output object file.
@"export",
/// Given a pointer to a struct or object that contains virtual fields, returns a pointer
@@ -162,6 +166,8 @@ pub const Inst = struct {
/// A labeled block of code that loops forever. At the end of the body it is implied
/// to repeat; no explicit "repeat" instruction terminates loop bodies.
loop,
+ /// Merge two error sets into one, `E1 || E2`.
+ merge_error_sets,
/// Ambiguously remainder division or modulus. If the computation would possibly have
/// a different value depending on whether the operation is remainder division or modulus,
/// a compile error is emitted. Otherwise the computation is performed.
@@ -288,6 +294,8 @@ pub const Inst = struct {
.unwrap_err_safe,
.unwrap_err_unsafe,
.ensure_err_payload_void,
+ .anyframe_type,
+ .bitnot,
=> UnOp,
.add,
@@ -318,6 +326,8 @@ pub const Inst = struct {
.bitcast,
.coerce_result_ptr,
.xor,
+ .error_union_type,
+ .merge_error_sets,
=> BinOp,
.arg => Arg,
@@ -440,6 +450,10 @@ pub const Inst = struct {
.ptr_type,
.ensure_err_payload_void,
.enum_literal,
+ .merge_error_sets,
+ .anyframe_type,
+ .error_union_type,
+ .bitnot,
=> false,
.@"break",
src-self-hosted/zir_sema.zig
@@ -97,7 +97,7 @@ pub fn analyzeInst(mod: *Module, scope: *Scope, old_inst: *zir.Inst) InnerError!
.array_cat => return analyzeInstArrayCat(mod, scope, old_inst.castTag(.array_cat).?),
.array_mul => return analyzeInstArrayMul(mod, scope, old_inst.castTag(.array_mul).?),
.bitand => return analyzeInstBitwise(mod, scope, old_inst.castTag(.bitand).?),
- .bitnot => return analyzeInstBitwise(mod, scope, old_inst.castTag(.bitnot).?),
+ .bitnot => return analyzeInstBitNot(mod, scope, old_inst.castTag(.bitnot).?),
.bitor => return analyzeInstBitwise(mod, scope, old_inst.castTag(.bitor).?),
.xor => return analyzeInstBitwise(mod, scope, old_inst.castTag(.xor).?),
.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!
.array_type => return analyzeInstArrayType(mod, scope, old_inst.castTag(.array_type).?),
.array_type_sentinel => return analyzeInstArrayTypeSentinel(mod, scope, old_inst.castTag(.array_type_sentinel).?),
.enum_literal => return analyzeInstEnumLiteral(mod, scope, old_inst.castTag(.enum_literal).?),
+ .merge_error_sets => return analyzeInstMergeErrorSets(mod, scope, old_inst.castTag(.merge_error_sets).?),
+ .error_union_type => return analyzeInstErrorUnionType(mod, scope, old_inst.castTag(.error_union_type).?),
+ .anyframe_type => return analyzeInstAnyframeType(mod, scope, old_inst.castTag(.anyframe_type).?),
}
}
@@ -717,6 +720,27 @@ fn analyzeInstArrayTypeSentinel(mod: *Module, scope: *Scope, array: *zir.Inst.Ar
return mod.constType(scope, array.base.src, try mod.arrayType(scope, len.val.toUnsignedInt(), sentinel.val, elem_type));
}
+fn analyzeInstErrorUnionType(mod: *Module, scope: *Scope, inst: *zir.Inst.BinOp) InnerError!*Inst {
+ const error_union = try resolveType(mod, scope, inst.positionals.lhs);
+ const payload = try resolveType(mod, scope, inst.positionals.rhs);
+
+ if (error_union.zigTypeTag() != .ErrorSet) {
+ return mod.fail(scope, inst.base.src, "expected error set type, found {}", .{error_union.elemType()});
+ }
+
+ return mod.constType(scope, inst.base.src, try mod.errorUnionType(scope, error_union, payload));
+}
+
+fn analyzeInstAnyframeType(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp) InnerError!*Inst {
+ const return_type = try resolveType(mod, scope, inst.positionals.operand);
+
+ return mod.constType(scope, inst.base.src, try mod.anyframeType(scope, return_type));
+}
+
+fn analyzeInstMergeErrorSets(mod: *Module, scope: *Scope, inst: *zir.Inst.BinOp) InnerError!*Inst {
+ return mod.fail(scope, inst.base.src, "TODO implement merge_error_sets", .{});
+}
+
fn analyzeInstEnumLiteral(mod: *Module, scope: *Scope, inst: *zir.Inst.EnumLiteral) InnerError!*Inst {
const payload = try scope.arena().create(Value.Payload.Bytes);
payload.* = .{
@@ -984,6 +1008,10 @@ fn analyzeInstBitwise(mod: *Module, scope: *Scope, inst: *zir.Inst.BinOp) InnerE
return mod.fail(scope, inst.base.src, "TODO implement analyzeInstBitwise", .{});
}
+fn analyzeInstBitNot(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp) InnerError!*Inst {
+ return mod.fail(scope, inst.base.src, "TODO implement analyzeInstBitNot", .{});
+}
+
fn analyzeInstArrayCat(mod: *Module, scope: *Scope, inst: *zir.Inst.BinOp) InnerError!*Inst {
return mod.fail(scope, inst.base.src, "TODO implement analyzeInstArrayCat", .{});
}