stage2: anyframe and error union types

This commit is contained in:
Vexu 2020-08-22 16:30:57 +03:00 committed by Andrew Kelley
parent d62c12e077
commit 16d7db59ed
6 changed files with 287 additions and 13 deletions

View File

@ -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");

View File

@ -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;

View File

@ -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,
};
};
};

View File

@ -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,

View File

@ -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",

View File

@ -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", .{});
}