mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-06 13:54:21 +00:00
compiler: replace @Type with individual type-creating builtins
The new builtins are:
* `@EnumLiteral`
* `@Int`
* `@Fn`
* `@Pointer`
* `@Tuple`
* `@Enum`
* `@Union`
* `@Struct`
Their usage is documented in the language reference.
There is no `@Array` because arrays can be created like this:
if (sentinel) |s| [n:s]T else [n]T
There is also no `@Float`. Instead, `std.meta.Float` can serve this use
case if necessary.
There is no `@ErrorSet` and intentionally no way to achieve this.
Likewise, there is intentionally no way to reify tuples with comptime
fields, or function types with comptime parameters. These decisions
simplify the Zig language specification, and moreover make Zig code more
readable by discouraging overly complex metaprogramming.
Co-authored-by: Ali Cheraghi <alichraghi@proton.me>
Resolves: #10710
This commit is contained in:
parent
3f2cf1c002
commit
c5383173a0
16 changed files with 2076 additions and 1471 deletions
|
|
@ -638,7 +638,7 @@
|
|||
{#syntax#}i7{#endsyntax#} refers to a signed 7-bit integer. The maximum allowed bit-width of an
|
||||
integer type is {#syntax#}65535{#endsyntax#}.
|
||||
</p>
|
||||
{#see_also|Integers|Floats|void|Errors|@Type#}
|
||||
{#see_also|Integers|Floats|void|Errors|@Int#}
|
||||
{#header_close#}
|
||||
{#header_open|Primitive Values#}
|
||||
<div class="table-wrapper">
|
||||
|
|
@ -3723,9 +3723,9 @@ void do_a_thing(struct Foo *foo) {
|
|||
<td>{#syntax#}x{#endsyntax#} is a {#syntax#}@FieldType(T, "a"){#endsyntax#}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">{#syntax#}@Type(x){#endsyntax#}</th>
|
||||
<th scope="row">{#syntax#}@Int(x, y){#endsyntax#}</th>
|
||||
<td>-</td>
|
||||
<td>{#syntax#}x{#endsyntax#} is a {#syntax#}std.builtin.Type{#endsyntax#}</td>
|
||||
<td>{#syntax#}x{#endsyntax#} is a {#syntax#}std.builtin.Signedness{#endsyntax#}, {#syntax#}y{#endsyntax#} is a {#syntax#}u16{#endsyntax#}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">{#syntax#}@typeInfo(x){#endsyntax#}</th>
|
||||
|
|
@ -3839,9 +3839,9 @@ void do_a_thing(struct Foo *foo) {
|
|||
<td>{#syntax#}x{#endsyntax#} has no result location (typed initializers do not propagate result locations)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">{#syntax#}@Type(x){#endsyntax#}</th>
|
||||
<td>{#syntax#}ptr{#endsyntax#}</td>
|
||||
<td>{#syntax#}x{#endsyntax#} has no result location</td>
|
||||
<th scope="row">{#syntax#}@Int(x, y){#endsyntax#}</th>
|
||||
<td>-</td>
|
||||
<td>{#syntax#}x{#endsyntax#} and {#syntax#}y{#endsyntax#} do not have result locations</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">{#syntax#}@typeInfo(x){#endsyntax#}</th>
|
||||
|
|
@ -5755,41 +5755,75 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val
|
|||
</p>
|
||||
{#header_close#}
|
||||
|
||||
{#header_open|@Type#}
|
||||
<pre>{#syntax#}@Type(comptime info: std.builtin.Type) type{#endsyntax#}</pre>
|
||||
<p>
|
||||
This function is the inverse of {#link|@typeInfo#}. It reifies type information
|
||||
into a {#syntax#}type{#endsyntax#}.
|
||||
</p>
|
||||
<p>
|
||||
It is available for the following types:
|
||||
</p>
|
||||
<ul>
|
||||
<li>{#syntax#}type{#endsyntax#}</li>
|
||||
<li>{#syntax#}noreturn{#endsyntax#}</li>
|
||||
<li>{#syntax#}void{#endsyntax#}</li>
|
||||
<li>{#syntax#}bool{#endsyntax#}</li>
|
||||
<li>{#link|Integers#} - The maximum bit count for an integer type is {#syntax#}65535{#endsyntax#}.</li>
|
||||
<li>{#link|Floats#}</li>
|
||||
<li>{#link|Pointers#}</li>
|
||||
<li>{#syntax#}comptime_int{#endsyntax#}</li>
|
||||
<li>{#syntax#}comptime_float{#endsyntax#}</li>
|
||||
<li>{#syntax#}@TypeOf(undefined){#endsyntax#}</li>
|
||||
<li>{#syntax#}@TypeOf(null){#endsyntax#}</li>
|
||||
<li>{#link|Arrays#}</li>
|
||||
<li>{#link|Optionals#}</li>
|
||||
<li>{#link|Error Set Type#}</li>
|
||||
<li>{#link|Error Union Type#}</li>
|
||||
<li>{#link|Vectors#}</li>
|
||||
<li>{#link|opaque#}</li>
|
||||
<li>{#syntax#}anyframe{#endsyntax#}</li>
|
||||
<li>{#link|struct#}</li>
|
||||
<li>{#link|enum#}</li>
|
||||
<li>{#link|Enum Literals#}</li>
|
||||
<li>{#link|union#}</li>
|
||||
<li>{#link|Functions#}</li>
|
||||
</ul>
|
||||
{#header_open|@EnumLiteral#}
|
||||
<pre>{#syntax#}@EnumLiteral() type{#endsyntax#}</pre>
|
||||
<p>Returns the comptime-only "enum literal" type. This is the type of uncoerced {#link|Enum Literals#}. Values of this type can coerce to any {#link|enum#} with a matching field.</p>
|
||||
{#header_close#}
|
||||
|
||||
{#header_open|@Int#}
|
||||
<pre>{#syntax#}@Int(comptime signedness: std.builtin.Signedness, comptime bits: u16) type{#endsyntax#}</pre>
|
||||
<p>Returns an integer type with the given signedness and bit width.</p>
|
||||
<p>For instance, {#syntax#}@Int(.unsigned, 18){#endsyntax#} returns the type {#syntax#}u18{#endsyntax#}.</p>
|
||||
{#header_close#}
|
||||
|
||||
{#header_open|@Tuple#}
|
||||
<pre>{#syntax#}@Tuple(comptime field_types: []const type) type{#endsyntax#}</pre>
|
||||
<p>Returns a {#link|tuple|Tuples#} type with the given field types.</p>
|
||||
{#header_close#}
|
||||
|
||||
{#header_open|@Pointer#}
|
||||
<pre>{#syntax#}@Pointer(
|
||||
comptime size: std.builtin.Type.Pointer.Size,
|
||||
comptime attrs: std.builtin.Type.Pointer.Attributes,
|
||||
comptime Element: type,
|
||||
comptime sentinel: ?Element,
|
||||
) type{#endsyntax#}</pre>
|
||||
<p>Returns a {#link|pointer|Pointers#} type with the properties specified by the arguments.</p>
|
||||
{#header_close#}
|
||||
|
||||
{#header_open|@Fn#}
|
||||
<pre>{#syntax#}@Fn(
|
||||
comptime param_types: []const type,
|
||||
comptime param_attrs: *const [param_types.len]std.builtin.Type.Fn.Param.Attributes,
|
||||
comptime ReturnType: type,
|
||||
comptime attrs: std.builtin.Type.Fn.Attributes,
|
||||
) type{#endsyntax#}</pre>
|
||||
<p>Returns a {#link|function|Functions#} type with the properties specified by the arguments.</p>
|
||||
{#header_close#}
|
||||
|
||||
{#header_open|@Struct#}
|
||||
<pre>{#syntax#}@Struct(
|
||||
comptime layout: std.builtin.Type.ContainerLayout,
|
||||
comptime BackingInt: ?type,
|
||||
comptime field_names: []const []const u8,
|
||||
comptime field_types: *const [field_names.len]type,
|
||||
comptime field_attrs: *const [field_names.len]std.builtin.Type.StructField.Attributes,
|
||||
) type{#endsyntax#}</pre>
|
||||
<p>Returns a {#link|struct#} type with the properties specified by the arguments.</p>
|
||||
{#header_close#}
|
||||
|
||||
{#header_open|@Union#}
|
||||
<pre>{#syntax#}@Union(
|
||||
comptime layout: std.builtin.Type.ContainerLayout,
|
||||
/// Either the integer tag type, or the integer backing type, depending on `layout`.
|
||||
comptime ArgType: ?type,
|
||||
comptime field_names: []const []const u8,
|
||||
comptime field_types: *const [field_names.len]type,
|
||||
comptime field_attrs: *const [field_names.len]std.builtin.Type.UnionField.Attributes,
|
||||
) type{#endsyntax#}</pre>
|
||||
<p>Returns a {#link|union#} type with the properties specified by the arguments.</p>
|
||||
{#header_close#}
|
||||
|
||||
{#header_open|@Enum#}
|
||||
<pre>{#syntax#}@Enum(
|
||||
comptime TagInt: type,
|
||||
comptime mode: std.builtin.Type.Enum.Mode,
|
||||
comptime field_names: []const []const u8,
|
||||
comptime field_values: *const [field_names.len]TagInt,
|
||||
) type{#endsyntax#}</pre>
|
||||
<p>Returns an {#link|enum#} type with the properties specified by the arguments.</p>
|
||||
{#header_close#}
|
||||
|
||||
{#header_open|@typeInfo#}
|
||||
<pre>{#syntax#}@typeInfo(comptime T: type) std.builtin.Type{#endsyntax#}</pre>
|
||||
<p>
|
||||
|
|
|
|||
|
|
@ -548,19 +548,19 @@ pub const TypeId = std.meta.Tag(Type);
|
|||
/// This data structure is used by the Zig language code generation and
|
||||
/// therefore must be kept in sync with the compiler implementation.
|
||||
pub const Type = union(enum) {
|
||||
type: void,
|
||||
void: void,
|
||||
bool: void,
|
||||
noreturn: void,
|
||||
type,
|
||||
void,
|
||||
bool,
|
||||
noreturn,
|
||||
int: Int,
|
||||
float: Float,
|
||||
pointer: Pointer,
|
||||
array: Array,
|
||||
@"struct": Struct,
|
||||
comptime_float: void,
|
||||
comptime_int: void,
|
||||
undefined: void,
|
||||
null: void,
|
||||
comptime_float,
|
||||
comptime_int,
|
||||
undefined,
|
||||
null,
|
||||
optional: Optional,
|
||||
error_union: ErrorUnion,
|
||||
error_set: ErrorSet,
|
||||
|
|
@ -571,7 +571,7 @@ pub const Type = union(enum) {
|
|||
frame: Frame,
|
||||
@"anyframe": AnyFrame,
|
||||
vector: Vector,
|
||||
enum_literal: void,
|
||||
enum_literal,
|
||||
|
||||
/// This data structure is used by the Zig language code generation and
|
||||
/// therefore must be kept in sync with the compiler implementation.
|
||||
|
|
@ -619,6 +619,16 @@ pub const Type = union(enum) {
|
|||
slice,
|
||||
c,
|
||||
};
|
||||
|
||||
/// This data structure is used by the Zig language code generation and
|
||||
/// therefore must be kept in sync with the compiler implementation.
|
||||
pub const Attributes = struct {
|
||||
@"const": bool = false,
|
||||
@"volatile": bool = false,
|
||||
@"allowzero": bool = false,
|
||||
@"addrspace": ?AddressSpace = null,
|
||||
@"align": ?usize = null,
|
||||
};
|
||||
};
|
||||
|
||||
/// This data structure is used by the Zig language code generation and
|
||||
|
|
@ -668,6 +678,14 @@ pub const Type = union(enum) {
|
|||
const dp: *const sf.type = @ptrCast(@alignCast(sf.default_value_ptr orelse return null));
|
||||
return dp.*;
|
||||
}
|
||||
|
||||
/// This data structure is used by the Zig language code generation and
|
||||
/// therefore must be kept in sync with the compiler implementation.
|
||||
pub const Attributes = struct {
|
||||
@"comptime": bool = false,
|
||||
@"align": ?usize = null,
|
||||
default_value_ptr: ?*const anyopaque = null,
|
||||
};
|
||||
};
|
||||
|
||||
/// This data structure is used by the Zig language code generation and
|
||||
|
|
@ -718,6 +736,10 @@ pub const Type = union(enum) {
|
|||
fields: []const EnumField,
|
||||
decls: []const Declaration,
|
||||
is_exhaustive: bool,
|
||||
|
||||
/// This data structure is used by the Zig language code generation and
|
||||
/// therefore must be kept in sync with the compiler implementation.
|
||||
pub const Mode = enum { exhaustive, nonexhaustive };
|
||||
};
|
||||
|
||||
/// This data structure is used by the Zig language code generation and
|
||||
|
|
@ -726,6 +748,12 @@ pub const Type = union(enum) {
|
|||
name: [:0]const u8,
|
||||
type: type,
|
||||
alignment: comptime_int,
|
||||
|
||||
/// This data structure is used by the Zig language code generation and
|
||||
/// therefore must be kept in sync with the compiler implementation.
|
||||
pub const Attributes = struct {
|
||||
@"align": ?usize = null,
|
||||
};
|
||||
};
|
||||
|
||||
/// This data structure is used by the Zig language code generation and
|
||||
|
|
@ -753,6 +781,19 @@ pub const Type = union(enum) {
|
|||
is_generic: bool,
|
||||
is_noalias: bool,
|
||||
type: ?type,
|
||||
|
||||
/// This data structure is used by the Zig language code generation and
|
||||
/// therefore must be kept in sync with the compiler implementation.
|
||||
pub const Attributes = struct {
|
||||
@"noalias": bool = false,
|
||||
};
|
||||
};
|
||||
|
||||
/// This data structure is used by the Zig language code generation and
|
||||
/// therefore must be kept in sync with the compiler implementation.
|
||||
pub const Attributes = struct {
|
||||
@"callconv": CallingConvention = .auto,
|
||||
varargs: bool = false,
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -773,7 +773,6 @@ pub const EnvVar = enum {
|
|||
pub const SimpleComptimeReason = enum(u32) {
|
||||
// Evaluating at comptime because a builtin operand must be comptime-known.
|
||||
// These messages all mention a specific builtin.
|
||||
operand_Type,
|
||||
operand_setEvalBranchQuota,
|
||||
operand_setFloatMode,
|
||||
operand_branchHint,
|
||||
|
|
@ -809,25 +808,34 @@ pub const SimpleComptimeReason = enum(u32) {
|
|||
// Evaluating at comptime because types must be comptime-known.
|
||||
// Reasons other than `.type` are just more specific messages.
|
||||
type,
|
||||
int_signedness,
|
||||
int_bit_width,
|
||||
array_sentinel,
|
||||
array_length,
|
||||
pointer_size,
|
||||
pointer_attrs,
|
||||
pointer_sentinel,
|
||||
slice_sentinel,
|
||||
array_length,
|
||||
vector_length,
|
||||
error_set_contents,
|
||||
struct_fields,
|
||||
enum_fields,
|
||||
union_fields,
|
||||
function_ret_ty,
|
||||
function_parameters,
|
||||
fn_ret_ty,
|
||||
fn_param_types,
|
||||
fn_param_attrs,
|
||||
fn_attrs,
|
||||
struct_layout,
|
||||
struct_field_names,
|
||||
struct_field_types,
|
||||
struct_field_attrs,
|
||||
union_layout,
|
||||
union_field_names,
|
||||
union_field_types,
|
||||
union_field_attrs,
|
||||
tuple_field_types,
|
||||
enum_field_names,
|
||||
enum_field_values,
|
||||
|
||||
// Evaluating at comptime because decl/field name must be comptime-known.
|
||||
decl_name,
|
||||
field_name,
|
||||
struct_field_name,
|
||||
enum_field_name,
|
||||
union_field_name,
|
||||
tuple_field_name,
|
||||
tuple_field_index,
|
||||
|
||||
// Evaluating at comptime because it is an attribute of a global declaration.
|
||||
|
|
@ -856,7 +864,6 @@ pub const SimpleComptimeReason = enum(u32) {
|
|||
pub fn message(r: SimpleComptimeReason) []const u8 {
|
||||
return switch (r) {
|
||||
// zig fmt: off
|
||||
.operand_Type => "operand to '@Type' must be comptime-known",
|
||||
.operand_setEvalBranchQuota => "operand to '@setEvalBranchQuota' must be comptime-known",
|
||||
.operand_setFloatMode => "operand to '@setFloatMode' must be comptime-known",
|
||||
.operand_branchHint => "operand to '@branchHint' must be comptime-known",
|
||||
|
|
@ -888,24 +895,33 @@ pub const SimpleComptimeReason = enum(u32) {
|
|||
.clobber => "clobber must be comptime-known",
|
||||
|
||||
.type => "types must be comptime-known",
|
||||
.int_signedness => "integer signedness must be comptime-known",
|
||||
.int_bit_width => "integer bit width must be comptime-known",
|
||||
.array_sentinel => "array sentinel value must be comptime-known",
|
||||
.array_length => "array length must be comptime-known",
|
||||
.pointer_size => "pointer size must be comptime-known",
|
||||
.pointer_attrs => "pointer attributes must be comptime-known",
|
||||
.pointer_sentinel => "pointer sentinel value must be comptime-known",
|
||||
.slice_sentinel => "slice sentinel value must be comptime-known",
|
||||
.array_length => "array length must be comptime-known",
|
||||
.vector_length => "vector length must be comptime-known",
|
||||
.error_set_contents => "error set contents must be comptime-known",
|
||||
.struct_fields => "struct fields must be comptime-known",
|
||||
.enum_fields => "enum fields must be comptime-known",
|
||||
.union_fields => "union fields must be comptime-known",
|
||||
.function_ret_ty => "function return type must be comptime-known",
|
||||
.function_parameters => "function parameters must be comptime-known",
|
||||
.fn_ret_ty => "function return type must be comptime-known",
|
||||
.fn_param_types => "function parameter types must be comptime-known",
|
||||
.fn_param_attrs => "function parameter attributes must be comptime-known",
|
||||
.fn_attrs => "function attributes must be comptime-known",
|
||||
.struct_layout => "struct layout must be comptime-known",
|
||||
.struct_field_names => "struct field names must be comptime-known",
|
||||
.struct_field_types => "struct field types must be comptime-known",
|
||||
.struct_field_attrs => "struct field attributes must be comptime-known",
|
||||
.union_layout => "union layout must be comptime-known",
|
||||
.union_field_names => "union field names must be comptime-known",
|
||||
.union_field_types => "union field types must be comptime-known",
|
||||
.union_field_attrs => "union field attributes must be comptime-known",
|
||||
.tuple_field_types => "tuple field types must be comptime-known",
|
||||
.enum_field_names => "enum field names must be comptime-known",
|
||||
.enum_field_values => "enum field values must be comptime-known",
|
||||
|
||||
.decl_name => "declaration name must be comptime-known",
|
||||
.field_name => "field name must be comptime-known",
|
||||
.struct_field_name => "struct field name must be comptime-known",
|
||||
.enum_field_name => "enum field name must be comptime-known",
|
||||
.union_field_name => "union field name must be comptime-known",
|
||||
.tuple_field_name => "tuple field name must be comptime-known",
|
||||
.tuple_field_index => "tuple field index must be comptime-known",
|
||||
|
||||
.container_var_init => "initializer of container-level variable must be comptime-known",
|
||||
|
|
|
|||
|
|
@ -833,7 +833,7 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE
|
|||
=> {
|
||||
var buf: [2]Ast.Node.Index = undefined;
|
||||
const params = tree.builtinCallParams(&buf, node).?;
|
||||
return builtinCall(gz, scope, ri, node, params, false);
|
||||
return builtinCall(gz, scope, ri, node, params, false, .anon);
|
||||
},
|
||||
|
||||
.call_one,
|
||||
|
|
@ -1194,14 +1194,20 @@ fn nameStratExpr(
|
|||
},
|
||||
.builtin_call_two,
|
||||
.builtin_call_two_comma,
|
||||
.builtin_call,
|
||||
.builtin_call_comma,
|
||||
=> {
|
||||
const builtin_token = tree.nodeMainToken(node);
|
||||
const builtin_name = tree.tokenSlice(builtin_token);
|
||||
if (!std.mem.eql(u8, builtin_name, "@Type")) return null;
|
||||
var buf: [2]Ast.Node.Index = undefined;
|
||||
const params = tree.builtinCallParams(&buf, node).?;
|
||||
if (params.len != 1) return null; // let `builtinCall` error
|
||||
return try builtinReify(gz, scope, ri, node, params[0], name_strat);
|
||||
const info = BuiltinFn.list.get(builtin_name) orelse return null;
|
||||
switch (info.tag) {
|
||||
.Enum, .Struct, .Union => {
|
||||
var buf: [2]Ast.Node.Index = undefined;
|
||||
const params = tree.builtinCallParams(&buf, node).?;
|
||||
return try builtinCall(gz, scope, ri, node, params, false, name_strat);
|
||||
},
|
||||
else => return null,
|
||||
}
|
||||
},
|
||||
else => return null,
|
||||
}
|
||||
|
|
@ -1406,7 +1412,7 @@ fn fnProtoExprInner(
|
|||
.none;
|
||||
|
||||
const ret_ty_node = fn_proto.ast.return_type.unwrap().?;
|
||||
const ret_ty = try comptimeExpr(&block_scope, scope, coerced_type_ri, ret_ty_node, .function_ret_ty);
|
||||
const ret_ty = try comptimeExpr(&block_scope, scope, coerced_type_ri, ret_ty_node, .fn_ret_ty);
|
||||
|
||||
const result = try block_scope.addFunc(.{
|
||||
.src_node = fn_proto.ast.proto_node,
|
||||
|
|
@ -2629,7 +2635,7 @@ fn blockExprStmts(gz: *GenZir, parent_scope: *Scope, statements: []const Ast.Nod
|
|||
const params = tree.builtinCallParams(&buf, inner_node).?;
|
||||
|
||||
try emitDbgNode(gz, inner_node);
|
||||
const result = try builtinCall(gz, scope, .{ .rl = .none }, inner_node, params, allow_branch_hint);
|
||||
const result = try builtinCall(gz, scope, .{ .rl = .none }, inner_node, params, allow_branch_hint, .anon);
|
||||
noreturn_src_node = try addEnsureResult(gz, result, inner_node);
|
||||
},
|
||||
|
||||
|
|
@ -2707,6 +2713,7 @@ fn addEnsureResult(gz: *GenZir, maybe_unused_result: Zir.Inst.Ref, statement: As
|
|||
.elem_type,
|
||||
.indexable_ptr_elem_type,
|
||||
.splat_op_result_ty,
|
||||
.reify_int,
|
||||
.vector_type,
|
||||
.indexable_ptr_len,
|
||||
.anyframe_type,
|
||||
|
|
@ -8942,7 +8949,7 @@ fn unionInit(
|
|||
params: []const Ast.Node.Index,
|
||||
) InnerError!Zir.Inst.Ref {
|
||||
const union_type = try typeExpr(gz, scope, params[0]);
|
||||
const field_name = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = .slice_const_u8_type } }, params[1], .union_field_name);
|
||||
const field_name = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = .slice_const_u8_type } }, params[1], .union_field_names);
|
||||
const field_type = try gz.addPlNode(.field_type_ref, node, Zir.Inst.FieldTypeRef{
|
||||
.container_type = union_type,
|
||||
.field_name = field_name,
|
||||
|
|
@ -9210,6 +9217,7 @@ fn builtinCall(
|
|||
node: Ast.Node.Index,
|
||||
params: []const Ast.Node.Index,
|
||||
allow_branch_hint: bool,
|
||||
reify_name_strat: Zir.Inst.NameStrategy,
|
||||
) InnerError!Zir.Inst.Ref {
|
||||
const astgen = gz.astgen;
|
||||
const tree = astgen.tree;
|
||||
|
|
@ -9443,9 +9451,140 @@ fn builtinCall(
|
|||
return rvalue(gz, ri, try gz.addNodeExtended(.in_comptime, node), node);
|
||||
},
|
||||
|
||||
.Type => {
|
||||
return builtinReify(gz, scope, ri, node, params[0], .anon);
|
||||
.EnumLiteral => return rvalue(gz, ri, .enum_literal_type, node),
|
||||
.Int => {
|
||||
const signedness_ty = try gz.addBuiltinValue(node, .signedness);
|
||||
const result = try gz.addPlNode(.reify_int, node, Zir.Inst.Bin{
|
||||
.lhs = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = signedness_ty } }, params[0], .int_signedness),
|
||||
.rhs = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = .u16_type } }, params[1], .int_bit_width),
|
||||
});
|
||||
return rvalue(gz, ri, result, node);
|
||||
},
|
||||
.Tuple => {
|
||||
const result = try gz.addExtendedPayload(.reify_tuple, Zir.Inst.UnNode{
|
||||
.node = gz.nodeIndexToRelative(node),
|
||||
.operand = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = .slice_const_type_type } }, params[0], .tuple_field_types),
|
||||
});
|
||||
return rvalue(gz, ri, result, node);
|
||||
},
|
||||
.Pointer => {
|
||||
const ptr_size_ty = try gz.addBuiltinValue(node, .pointer_size);
|
||||
const ptr_attrs_ty = try gz.addBuiltinValue(node, .pointer_attributes);
|
||||
const size = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = ptr_size_ty } }, params[0], .pointer_size);
|
||||
const attrs = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = ptr_attrs_ty } }, params[1], .pointer_attrs);
|
||||
const elem_ty = try typeExpr(gz, scope, params[2]);
|
||||
const sentinel_ty = try gz.addExtendedPayload(.reify_pointer_sentinel_ty, Zir.Inst.UnNode{
|
||||
.node = gz.nodeIndexToRelative(params[2]),
|
||||
.operand = elem_ty,
|
||||
});
|
||||
const sentinel = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = sentinel_ty } }, params[3], .pointer_sentinel);
|
||||
const result = try gz.addExtendedPayload(.reify_pointer, Zir.Inst.ReifyPointer{
|
||||
.node = gz.nodeIndexToRelative(node),
|
||||
.size = size,
|
||||
.attrs = attrs,
|
||||
.elem_ty = elem_ty,
|
||||
.sentinel = sentinel,
|
||||
});
|
||||
return rvalue(gz, ri, result, node);
|
||||
},
|
||||
.Fn => {
|
||||
const fn_attrs_ty = try gz.addBuiltinValue(node, .fn_attributes);
|
||||
const param_types = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = .slice_const_type_type } }, params[0], .fn_param_types);
|
||||
const param_attrs_ty = try gz.addExtendedPayloadSmall(
|
||||
.reify_slice_arg_ty,
|
||||
@intFromEnum(Zir.Inst.ReifySliceArgInfo.type_to_fn_param_attrs),
|
||||
Zir.Inst.UnNode{ .node = gz.nodeIndexToRelative(params[0]), .operand = param_types },
|
||||
);
|
||||
const param_attrs = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = param_attrs_ty } }, params[1], .fn_param_attrs);
|
||||
const ret_ty = try comptimeExpr(gz, scope, coerced_type_ri, params[2], .fn_ret_ty);
|
||||
const fn_attrs = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = fn_attrs_ty } }, params[3], .fn_attrs);
|
||||
const result = try gz.addExtendedPayload(.reify_fn, Zir.Inst.ReifyFn{
|
||||
.node = gz.nodeIndexToRelative(node),
|
||||
.param_types = param_types,
|
||||
.param_attrs = param_attrs,
|
||||
.ret_ty = ret_ty,
|
||||
.fn_attrs = fn_attrs,
|
||||
});
|
||||
return rvalue(gz, ri, result, node);
|
||||
},
|
||||
.Struct => {
|
||||
const container_layout_ty = try gz.addBuiltinValue(node, .container_layout);
|
||||
const layout = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = container_layout_ty } }, params[0], .struct_layout);
|
||||
const backing_ty = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = .optional_type_type } }, params[1], .type);
|
||||
const field_names = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = .slice_const_slice_const_u8_type } }, params[2], .struct_field_names);
|
||||
const field_types_ty = try gz.addExtendedPayloadSmall(
|
||||
.reify_slice_arg_ty,
|
||||
@intFromEnum(Zir.Inst.ReifySliceArgInfo.string_to_struct_field_type),
|
||||
Zir.Inst.UnNode{ .node = gz.nodeIndexToRelative(params[2]), .operand = field_names },
|
||||
);
|
||||
const field_attrs_ty = try gz.addExtendedPayloadSmall(
|
||||
.reify_slice_arg_ty,
|
||||
@intFromEnum(Zir.Inst.ReifySliceArgInfo.string_to_struct_field_attrs),
|
||||
Zir.Inst.UnNode{ .node = gz.nodeIndexToRelative(params[2]), .operand = field_names },
|
||||
);
|
||||
const field_types = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = field_types_ty } }, params[3], .struct_field_types);
|
||||
const field_attrs = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = field_attrs_ty } }, params[4], .struct_field_attrs);
|
||||
const result = try gz.addExtendedPayloadSmall(.reify_struct, @intFromEnum(reify_name_strat), Zir.Inst.ReifyStruct{
|
||||
.src_line = gz.astgen.source_line,
|
||||
.node = node,
|
||||
.layout = layout,
|
||||
.backing_ty = backing_ty,
|
||||
.field_names = field_names,
|
||||
.field_types = field_types,
|
||||
.field_attrs = field_attrs,
|
||||
});
|
||||
return rvalue(gz, ri, result, node);
|
||||
},
|
||||
.Union => {
|
||||
const container_layout_ty = try gz.addBuiltinValue(node, .container_layout);
|
||||
const layout = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = container_layout_ty } }, params[0], .union_layout);
|
||||
const arg_ty = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = .optional_type_type } }, params[1], .type);
|
||||
const field_names = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = .slice_const_slice_const_u8_type } }, params[2], .union_field_names);
|
||||
const field_types_ty = try gz.addExtendedPayloadSmall(
|
||||
.reify_slice_arg_ty,
|
||||
@intFromEnum(Zir.Inst.ReifySliceArgInfo.string_to_union_field_type),
|
||||
Zir.Inst.UnNode{ .node = gz.nodeIndexToRelative(params[2]), .operand = field_names },
|
||||
);
|
||||
const field_attrs_ty = try gz.addExtendedPayloadSmall(
|
||||
.reify_slice_arg_ty,
|
||||
@intFromEnum(Zir.Inst.ReifySliceArgInfo.string_to_union_field_attrs),
|
||||
Zir.Inst.UnNode{ .node = gz.nodeIndexToRelative(params[2]), .operand = field_names },
|
||||
);
|
||||
const field_types = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = field_types_ty } }, params[3], .union_field_types);
|
||||
const field_attrs = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = field_attrs_ty } }, params[4], .union_field_attrs);
|
||||
const result = try gz.addExtendedPayloadSmall(.reify_union, @intFromEnum(reify_name_strat), Zir.Inst.ReifyUnion{
|
||||
.src_line = gz.astgen.source_line,
|
||||
.node = node,
|
||||
.layout = layout,
|
||||
.arg_ty = arg_ty,
|
||||
.field_names = field_names,
|
||||
.field_types = field_types,
|
||||
.field_attrs = field_attrs,
|
||||
});
|
||||
return rvalue(gz, ri, result, node);
|
||||
},
|
||||
.Enum => {
|
||||
const enum_mode_ty = try gz.addBuiltinValue(node, .enum_mode);
|
||||
const tag_ty = try typeExpr(gz, scope, params[0]);
|
||||
const mode = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = enum_mode_ty } }, params[1], .type);
|
||||
const field_names = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = .slice_const_slice_const_u8_type } }, params[2], .enum_field_names);
|
||||
const field_values_ty = try gz.addExtendedPayload(.reify_enum_value_slice_ty, Zir.Inst.BinNode{
|
||||
.node = gz.nodeIndexToRelative(node),
|
||||
.lhs = tag_ty,
|
||||
.rhs = field_names,
|
||||
});
|
||||
const field_values = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = field_values_ty } }, params[3], .enum_field_values);
|
||||
const result = try gz.addExtendedPayloadSmall(.reify_enum, @intFromEnum(reify_name_strat), Zir.Inst.ReifyEnum{
|
||||
.src_line = gz.astgen.source_line,
|
||||
.node = node,
|
||||
.tag_ty = tag_ty,
|
||||
.mode = mode,
|
||||
.field_names = field_names,
|
||||
.field_values = field_values,
|
||||
});
|
||||
return rvalue(gz, ri, result, node);
|
||||
},
|
||||
|
||||
.panic => {
|
||||
try emitDbgNode(gz, node);
|
||||
return simpleUnOp(gz, scope, ri, node, .{ .rl = .{ .coerced_ty = .slice_const_u8_type } }, params[0], .panic);
|
||||
|
|
@ -9764,41 +9903,6 @@ fn builtinCall(
|
|||
},
|
||||
}
|
||||
}
|
||||
fn builtinReify(
|
||||
gz: *GenZir,
|
||||
scope: *Scope,
|
||||
ri: ResultInfo,
|
||||
node: Ast.Node.Index,
|
||||
arg_node: Ast.Node.Index,
|
||||
name_strat: Zir.Inst.NameStrategy,
|
||||
) InnerError!Zir.Inst.Ref {
|
||||
const astgen = gz.astgen;
|
||||
const gpa = astgen.gpa;
|
||||
|
||||
const type_info_ty = try gz.addBuiltinValue(node, .type_info);
|
||||
const operand = try expr(gz, scope, .{ .rl = .{ .coerced_ty = type_info_ty } }, arg_node);
|
||||
|
||||
try gz.instructions.ensureUnusedCapacity(gpa, 1);
|
||||
try astgen.instructions.ensureUnusedCapacity(gpa, 1);
|
||||
|
||||
const payload_index = try astgen.addExtra(Zir.Inst.Reify{
|
||||
.node = node, // Absolute node index -- see the definition of `Reify`.
|
||||
.operand = operand,
|
||||
.src_line = astgen.source_line,
|
||||
});
|
||||
const new_index: Zir.Inst.Index = @enumFromInt(astgen.instructions.len);
|
||||
astgen.instructions.appendAssumeCapacity(.{
|
||||
.tag = .extended,
|
||||
.data = .{ .extended = .{
|
||||
.opcode = .reify,
|
||||
.small = @intFromEnum(name_strat),
|
||||
.operand = payload_index,
|
||||
} },
|
||||
});
|
||||
gz.instructions.appendAssumeCapacity(new_index);
|
||||
const result = new_index.toRef();
|
||||
return rvalue(gz, ri, result, node);
|
||||
}
|
||||
|
||||
fn hasDeclOrField(
|
||||
gz: *GenZir,
|
||||
|
|
|
|||
|
|
@ -866,6 +866,7 @@ fn builtinCall(astrl: *AstRlAnnotate, block: ?*Block, ri: ResultInfo, node: Ast.
|
|||
// These builtins take no args and do not consume the result pointer.
|
||||
.src,
|
||||
.This,
|
||||
.EnumLiteral,
|
||||
.return_address,
|
||||
.error_return_trace,
|
||||
.frame,
|
||||
|
|
@ -906,7 +907,7 @@ fn builtinCall(astrl: *AstRlAnnotate, block: ?*Block, ri: ResultInfo, node: Ast.
|
|||
.embed_file,
|
||||
.error_name,
|
||||
.set_runtime_safety,
|
||||
.Type,
|
||||
.Tuple,
|
||||
.c_undef,
|
||||
.c_include,
|
||||
.wasm_memory_size,
|
||||
|
|
@ -1058,6 +1059,48 @@ fn builtinCall(astrl: *AstRlAnnotate, block: ?*Block, ri: ResultInfo, node: Ast.
|
|||
_ = try astrl.expr(args[3], block, ResultInfo.none);
|
||||
return false;
|
||||
},
|
||||
.Int => {
|
||||
_ = try astrl.expr(args[0], block, ResultInfo.type_only);
|
||||
_ = try astrl.expr(args[1], block, ResultInfo.type_only);
|
||||
return false;
|
||||
},
|
||||
.Pointer => {
|
||||
_ = try astrl.expr(args[0], block, ResultInfo.type_only);
|
||||
_ = try astrl.expr(args[1], block, ResultInfo.type_only);
|
||||
_ = try astrl.expr(args[2], block, ResultInfo.type_only);
|
||||
_ = try astrl.expr(args[3], block, ResultInfo.type_only);
|
||||
return false;
|
||||
},
|
||||
.Fn => {
|
||||
_ = try astrl.expr(args[0], block, ResultInfo.type_only);
|
||||
_ = try astrl.expr(args[1], block, ResultInfo.type_only);
|
||||
_ = try astrl.expr(args[2], block, ResultInfo.type_only);
|
||||
_ = try astrl.expr(args[3], block, ResultInfo.type_only);
|
||||
return false;
|
||||
},
|
||||
.Struct => {
|
||||
_ = try astrl.expr(args[0], block, ResultInfo.type_only);
|
||||
_ = try astrl.expr(args[1], block, ResultInfo.type_only);
|
||||
_ = try astrl.expr(args[2], block, ResultInfo.type_only);
|
||||
_ = try astrl.expr(args[3], block, ResultInfo.type_only);
|
||||
_ = try astrl.expr(args[4], block, ResultInfo.type_only);
|
||||
return false;
|
||||
},
|
||||
.Union => {
|
||||
_ = try astrl.expr(args[0], block, ResultInfo.type_only);
|
||||
_ = try astrl.expr(args[1], block, ResultInfo.type_only);
|
||||
_ = try astrl.expr(args[2], block, ResultInfo.type_only);
|
||||
_ = try astrl.expr(args[3], block, ResultInfo.type_only);
|
||||
_ = try astrl.expr(args[4], block, ResultInfo.type_only);
|
||||
return false;
|
||||
},
|
||||
.Enum => {
|
||||
_ = try astrl.expr(args[0], block, ResultInfo.type_only);
|
||||
_ = try astrl.expr(args[1], block, ResultInfo.type_only);
|
||||
_ = try astrl.expr(args[2], block, ResultInfo.type_only);
|
||||
_ = try astrl.expr(args[3], block, ResultInfo.type_only);
|
||||
return false;
|
||||
},
|
||||
.Vector => {
|
||||
_ = try astrl.expr(args[0], block, ResultInfo.type_only);
|
||||
_ = try astrl.expr(args[1], block, ResultInfo.type_only);
|
||||
|
|
|
|||
|
|
@ -110,7 +110,14 @@ pub const Tag = enum {
|
|||
This,
|
||||
trap,
|
||||
truncate,
|
||||
Type,
|
||||
EnumLiteral,
|
||||
Int,
|
||||
Tuple,
|
||||
Pointer,
|
||||
Fn,
|
||||
Struct,
|
||||
Union,
|
||||
Enum,
|
||||
type_info,
|
||||
type_name,
|
||||
TypeOf,
|
||||
|
|
@ -937,12 +944,61 @@ pub const list = list: {
|
|||
},
|
||||
},
|
||||
.{
|
||||
"@Type",
|
||||
"@EnumLiteral",
|
||||
.{
|
||||
.tag = .Type,
|
||||
.tag = .EnumLiteral,
|
||||
.param_count = 0,
|
||||
},
|
||||
},
|
||||
.{
|
||||
"@Int",
|
||||
.{
|
||||
.tag = .Int,
|
||||
.param_count = 2,
|
||||
},
|
||||
},
|
||||
.{
|
||||
"@Tuple",
|
||||
.{
|
||||
.tag = .Tuple,
|
||||
.param_count = 1,
|
||||
},
|
||||
},
|
||||
.{
|
||||
"@Pointer",
|
||||
.{
|
||||
.tag = .Pointer,
|
||||
.param_count = 4,
|
||||
},
|
||||
},
|
||||
.{
|
||||
"@Fn",
|
||||
.{
|
||||
.tag = .Fn,
|
||||
.param_count = 4,
|
||||
},
|
||||
},
|
||||
.{
|
||||
"@Struct",
|
||||
.{
|
||||
.tag = .Struct,
|
||||
.param_count = 5,
|
||||
},
|
||||
},
|
||||
.{
|
||||
"@Union",
|
||||
.{
|
||||
.tag = .Union,
|
||||
.param_count = 5,
|
||||
},
|
||||
},
|
||||
.{
|
||||
"@Enum",
|
||||
.{
|
||||
.tag = .Enum,
|
||||
.param_count = 4,
|
||||
},
|
||||
},
|
||||
.{
|
||||
"@typeInfo",
|
||||
.{
|
||||
|
|
|
|||
|
|
@ -260,6 +260,10 @@ pub const Inst = struct {
|
|||
/// `[N:S]T` syntax. Source location is the array type expression node.
|
||||
/// Uses the `pl_node` union field. Payload is `ArrayTypeSentinel`.
|
||||
array_type_sentinel,
|
||||
/// `@Int` builtin.
|
||||
/// Uses the `pl_node` union field with `Bin` payload.
|
||||
/// lhs is signedness, rhs is bit count.
|
||||
reify_int,
|
||||
/// `@Vector` builtin.
|
||||
/// Uses the `pl_node` union field with `Bin` payload.
|
||||
/// lhs is length, rhs is element type.
|
||||
|
|
@ -1112,6 +1116,7 @@ pub const Inst = struct {
|
|||
.array_mul,
|
||||
.array_type,
|
||||
.array_type_sentinel,
|
||||
.reify_int,
|
||||
.vector_type,
|
||||
.elem_type,
|
||||
.indexable_ptr_elem_type,
|
||||
|
|
@ -1409,6 +1414,7 @@ pub const Inst = struct {
|
|||
.array_mul,
|
||||
.array_type,
|
||||
.array_type_sentinel,
|
||||
.reify_int,
|
||||
.vector_type,
|
||||
.elem_type,
|
||||
.indexable_ptr_elem_type,
|
||||
|
|
@ -1644,6 +1650,7 @@ pub const Inst = struct {
|
|||
.array_mul = .pl_node,
|
||||
.array_type = .pl_node,
|
||||
.array_type_sentinel = .pl_node,
|
||||
.reify_int = .pl_node,
|
||||
.vector_type = .pl_node,
|
||||
.elem_type = .un_node,
|
||||
.indexable_ptr_elem_type = .un_node,
|
||||
|
|
@ -2035,10 +2042,43 @@ pub const Inst = struct {
|
|||
/// Implement builtin `@errorFromInt`.
|
||||
/// `operand` is payload index to `UnNode`.
|
||||
error_from_int,
|
||||
/// Implement builtin `@Type`.
|
||||
/// `operand` is payload index to `Reify`.
|
||||
/// Given a comptime-known operand of type `[]const A`, returns the type `*const [operand.len]B`.
|
||||
/// The types `A` and `B` are determined from `ReifySliceArgInfo`.
|
||||
/// This instruction is used to provide result types to arguments of `@Fn`, `@Struct`, etc.
|
||||
/// `operand` is payload index to `UnNode`.
|
||||
/// `small` is a bitcast `ReifySliceArgInfo`.
|
||||
reify_slice_arg_ty,
|
||||
/// Like `reify_slice_arg_ty` for the specific case of `[]const []const u8` to `[]const TagInt`,
|
||||
/// as needed for `@Enum`.
|
||||
/// `operand` is payload index to `BinNode`. lhs is the type `TagInt`. rhs is the `[]const []const u8` value.
|
||||
/// `small` is unused.
|
||||
reify_enum_value_slice_ty,
|
||||
/// Given a comptime-known operand of type `type`, returns the type `?operand` if possible, otherwise `?noreturn`.
|
||||
/// Used for the final arg of `@Pointer` to allow reifying pointers to opaque types.
|
||||
/// `operand` is payload index to `UnNode`.
|
||||
/// `small` is unused.
|
||||
reify_pointer_sentinel_ty,
|
||||
/// Implements builtin `@Tuple`.
|
||||
/// `operand` is payload index to `UnNode`.
|
||||
reify_tuple,
|
||||
/// Implements builtin `@Pointer`.
|
||||
/// `operand` is payload index to `ReifyPointer`.
|
||||
reify_pointer,
|
||||
/// Implements builtin `@Fn`.
|
||||
/// `operand` is payload index to `ReifyFn`.
|
||||
reify_fn,
|
||||
/// Implements builtin `@Struct`.
|
||||
/// `operand` is payload index to `ReifyStruct`.
|
||||
/// `small` contains `NameStrategy`.
|
||||
reify,
|
||||
reify_struct,
|
||||
/// Implements builtin `@Union`.
|
||||
/// `operand` is payload index to `ReifyUnion`.
|
||||
/// `small` contains `NameStrategy`.
|
||||
reify_union,
|
||||
/// Implements builtin `@Enum`.
|
||||
/// `operand` is payload index to `ReifyEnum`.
|
||||
/// `small` contains `NameStrategy`.
|
||||
reify_enum,
|
||||
/// Implements the `@cmpxchgStrong` and `@cmpxchgWeak` builtins.
|
||||
/// `small` 0=>weak 1=>strong
|
||||
/// `operand` is payload index to `Cmpxchg`.
|
||||
|
|
@ -2226,6 +2266,11 @@ pub const Inst = struct {
|
|||
manyptr_const_u8_sentinel_0_type,
|
||||
slice_const_u8_type,
|
||||
slice_const_u8_sentinel_0_type,
|
||||
manyptr_const_slice_const_u8_type,
|
||||
slice_const_slice_const_u8_type,
|
||||
optional_type_type,
|
||||
manyptr_const_type_type,
|
||||
slice_const_type_type,
|
||||
vector_8_i8_type,
|
||||
vector_16_i8_type,
|
||||
vector_32_i8_type,
|
||||
|
|
@ -3169,6 +3214,23 @@ pub const Inst = struct {
|
|||
rhs: Ref,
|
||||
};
|
||||
|
||||
pub const ReifySliceArgInfo = enum(u16) {
|
||||
/// Input element type is `type`.
|
||||
/// Output element type is `std.builtin.Type.Fn.Param.Attributes`.
|
||||
type_to_fn_param_attrs,
|
||||
/// Input element type is `[]const u8`.
|
||||
/// Output element type is `type`.
|
||||
string_to_struct_field_type,
|
||||
/// Identical to `string_to_struct_field_type` aside from emitting slightly different error messages.
|
||||
string_to_union_field_type,
|
||||
/// Input element type is `[]const u8`.
|
||||
/// Output element type is `std.builtin.Type.StructField.Attributes`.
|
||||
string_to_struct_field_attrs,
|
||||
/// Input element type is `[]const u8`.
|
||||
/// Output element type is `std.builtin.Type.UnionField.Attributes`.
|
||||
string_to_union_field_attrs,
|
||||
};
|
||||
|
||||
pub const UnNode = struct {
|
||||
node: Ast.Node.Offset,
|
||||
operand: Ref,
|
||||
|
|
@ -3179,12 +3241,55 @@ pub const Inst = struct {
|
|||
index: u32,
|
||||
};
|
||||
|
||||
pub const Reify = struct {
|
||||
pub const ReifyPointer = struct {
|
||||
node: Ast.Node.Offset,
|
||||
size: Ref,
|
||||
attrs: Ref,
|
||||
elem_ty: Ref,
|
||||
sentinel: Ref,
|
||||
};
|
||||
|
||||
pub const ReifyFn = struct {
|
||||
node: Ast.Node.Offset,
|
||||
param_types: Ref,
|
||||
param_attrs: Ref,
|
||||
ret_ty: Ref,
|
||||
fn_attrs: Ref,
|
||||
};
|
||||
|
||||
pub const ReifyStruct = struct {
|
||||
src_line: u32,
|
||||
/// This node is absolute, because `reify` instructions are tracked across updates, and
|
||||
/// this simplifies the logic for getting source locations for types.
|
||||
node: Ast.Node.Index,
|
||||
operand: Ref,
|
||||
layout: Ref,
|
||||
backing_ty: Ref,
|
||||
field_names: Ref,
|
||||
field_types: Ref,
|
||||
field_attrs: Ref,
|
||||
};
|
||||
|
||||
pub const ReifyUnion = struct {
|
||||
src_line: u32,
|
||||
/// This node is absolute, because `reify` instructions are tracked across updates, and
|
||||
/// this simplifies the logic for getting source locations for types.
|
||||
node: Ast.Node.Index,
|
||||
layout: Ref,
|
||||
arg_ty: Ref,
|
||||
field_names: Ref,
|
||||
field_types: Ref,
|
||||
field_attrs: Ref,
|
||||
};
|
||||
|
||||
pub const ReifyEnum = struct {
|
||||
src_line: u32,
|
||||
/// This node is absolute, because `reify` instructions are tracked across updates, and
|
||||
/// this simplifies the logic for getting source locations for types.
|
||||
node: Ast.Node.Index,
|
||||
tag_ty: Ref,
|
||||
mode: Ref,
|
||||
field_names: Ref,
|
||||
field_values: Ref,
|
||||
};
|
||||
|
||||
/// Trailing:
|
||||
|
|
@ -3496,14 +3601,19 @@ pub const Inst = struct {
|
|||
calling_convention,
|
||||
address_space,
|
||||
float_mode,
|
||||
signedness,
|
||||
reduce_op,
|
||||
call_modifier,
|
||||
prefetch_options,
|
||||
export_options,
|
||||
extern_options,
|
||||
type_info,
|
||||
branch_hint,
|
||||
clobbers,
|
||||
pointer_size,
|
||||
pointer_attributes,
|
||||
fn_attributes,
|
||||
container_layout,
|
||||
enum_mode,
|
||||
// Values
|
||||
calling_convention_c,
|
||||
calling_convention_inline,
|
||||
|
|
@ -4190,6 +4300,7 @@ fn findTrackableInner(
|
|||
.array_mul,
|
||||
.array_type,
|
||||
.array_type_sentinel,
|
||||
.reify_int,
|
||||
.vector_type,
|
||||
.elem_type,
|
||||
.indexable_ptr_elem_type,
|
||||
|
|
@ -4432,6 +4543,12 @@ fn findTrackableInner(
|
|||
.select,
|
||||
.int_from_error,
|
||||
.error_from_int,
|
||||
.reify_slice_arg_ty,
|
||||
.reify_enum_value_slice_ty,
|
||||
.reify_pointer_sentinel_ty,
|
||||
.reify_tuple,
|
||||
.reify_pointer,
|
||||
.reify_fn,
|
||||
.cmpxchg,
|
||||
.c_va_arg,
|
||||
.c_va_copy,
|
||||
|
|
@ -4463,7 +4580,11 @@ fn findTrackableInner(
|
|||
},
|
||||
|
||||
// Reifications and opaque declarations need tracking, but have no body.
|
||||
.reify, .opaque_decl => return contents.other.append(gpa, inst),
|
||||
.reify_enum,
|
||||
.reify_struct,
|
||||
.reify_union,
|
||||
.opaque_decl,
|
||||
=> return contents.other.append(gpa, inst),
|
||||
|
||||
// Struct declarations need tracking and have bodies.
|
||||
.struct_decl => {
|
||||
|
|
@ -5246,7 +5367,9 @@ pub fn assertTrackable(zir: Zir, inst_idx: Zir.Inst.Index) void {
|
|||
.union_decl,
|
||||
.enum_decl,
|
||||
.opaque_decl,
|
||||
.reify,
|
||||
.reify_enum,
|
||||
.reify_struct,
|
||||
.reify_union,
|
||||
=> {}, // tracked in order, as the owner instructions of explicit container types
|
||||
else => unreachable, // assertion failure; not trackable
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1062,6 +1062,11 @@ pub const Inst = struct {
|
|||
manyptr_const_u8_sentinel_0_type = @intFromEnum(InternPool.Index.manyptr_const_u8_sentinel_0_type),
|
||||
slice_const_u8_type = @intFromEnum(InternPool.Index.slice_const_u8_type),
|
||||
slice_const_u8_sentinel_0_type = @intFromEnum(InternPool.Index.slice_const_u8_sentinel_0_type),
|
||||
manyptr_const_slice_const_u8_type = @intFromEnum(InternPool.Index.manyptr_const_slice_const_u8_type),
|
||||
slice_const_slice_const_u8_type = @intFromEnum(InternPool.Index.slice_const_slice_const_u8_type),
|
||||
optional_type_type = @intFromEnum(InternPool.Index.optional_type_type),
|
||||
manyptr_const_type_type = @intFromEnum(InternPool.Index.manyptr_const_type_type),
|
||||
slice_const_type_type = @intFromEnum(InternPool.Index.slice_const_type_type),
|
||||
vector_8_i8_type = @intFromEnum(InternPool.Index.vector_8_i8_type),
|
||||
vector_16_i8_type = @intFromEnum(InternPool.Index.vector_16_i8_type),
|
||||
vector_32_i8_type = @intFromEnum(InternPool.Index.vector_32_i8_type),
|
||||
|
|
|
|||
|
|
@ -2017,8 +2017,7 @@ pub const Key = union(enum) {
|
|||
error_union_type: ErrorUnionType,
|
||||
simple_type: SimpleType,
|
||||
/// This represents a struct that has been explicitly declared in source code,
|
||||
/// or was created with `@Type`. It is unique and based on a declaration.
|
||||
/// It may be a tuple, if declared like this: `struct {A, B, C}`.
|
||||
/// or was created with `@Struct`. It is unique and based on a declaration.
|
||||
struct_type: NamespaceType,
|
||||
/// This is a tuple type. Tuples are logically similar to structs, but have some
|
||||
/// important differences in semantics; they do not undergo staged type resolution,
|
||||
|
|
@ -2175,7 +2174,7 @@ pub const Key = union(enum) {
|
|||
/// The union for which this is a tag type.
|
||||
union_type: Index,
|
||||
},
|
||||
/// This type originates from a reification via `@Type`, or from an anonymous initialization.
|
||||
/// This type originates from a reification via `@Enum`, `@Struct`, `@Union` or from an anonymous initialization.
|
||||
/// It is hashed based on its ZIR instruction index and fields, attributes, etc.
|
||||
/// To avoid making this key overly complex, the type-specific data is hashed by Sema.
|
||||
reified: struct {
|
||||
|
|
@ -4641,6 +4640,13 @@ pub const Index = enum(u32) {
|
|||
slice_const_u8_type,
|
||||
slice_const_u8_sentinel_0_type,
|
||||
|
||||
manyptr_const_slice_const_u8_type,
|
||||
slice_const_slice_const_u8_type,
|
||||
|
||||
optional_type_type,
|
||||
manyptr_const_type_type,
|
||||
slice_const_type_type,
|
||||
|
||||
vector_8_i8_type,
|
||||
vector_16_i8_type,
|
||||
vector_32_i8_type,
|
||||
|
|
@ -5201,6 +5207,45 @@ pub const static_keys: [static_len]Key = .{
|
|||
},
|
||||
} },
|
||||
|
||||
// [*]const []const u8
|
||||
.{ .ptr_type = .{
|
||||
.child = .slice_const_u8_type,
|
||||
.flags = .{
|
||||
.size = .many,
|
||||
.is_const = true,
|
||||
},
|
||||
} },
|
||||
|
||||
// []const []const u8
|
||||
.{ .ptr_type = .{
|
||||
.child = .slice_const_u8_type,
|
||||
.flags = .{
|
||||
.size = .slice,
|
||||
.is_const = true,
|
||||
},
|
||||
} },
|
||||
|
||||
// ?type
|
||||
.{ .opt_type = .type_type },
|
||||
|
||||
// [*]const type
|
||||
.{ .ptr_type = .{
|
||||
.child = .type_type,
|
||||
.flags = .{
|
||||
.size = .many,
|
||||
.is_const = true,
|
||||
},
|
||||
} },
|
||||
|
||||
// []const type
|
||||
.{ .ptr_type = .{
|
||||
.child = .type_type,
|
||||
.flags = .{
|
||||
.size = .slice,
|
||||
.is_const = true,
|
||||
},
|
||||
} },
|
||||
|
||||
// @Vector(8, i8)
|
||||
.{ .vector_type = .{ .len = 8, .child = .i8_type } },
|
||||
// @Vector(16, i8)
|
||||
|
|
@ -10225,16 +10270,8 @@ pub fn getGeneratedTagEnumType(
|
|||
}
|
||||
|
||||
pub const OpaqueTypeInit = struct {
|
||||
key: union(enum) {
|
||||
declared: struct {
|
||||
zir_index: TrackedInst.Index,
|
||||
captures: []const CaptureValue,
|
||||
},
|
||||
reified: struct {
|
||||
zir_index: TrackedInst.Index,
|
||||
// No type hash since reifid opaques have no data other than the `@Type` location
|
||||
},
|
||||
},
|
||||
zir_index: TrackedInst.Index,
|
||||
captures: []const CaptureValue,
|
||||
};
|
||||
|
||||
pub fn getOpaqueType(
|
||||
|
|
@ -10243,16 +10280,10 @@ pub fn getOpaqueType(
|
|||
tid: Zcu.PerThread.Id,
|
||||
ini: OpaqueTypeInit,
|
||||
) Allocator.Error!WipNamespaceType.Result {
|
||||
var gop = try ip.getOrPutKey(gpa, tid, .{ .opaque_type = switch (ini.key) {
|
||||
.declared => |d| .{ .declared = .{
|
||||
.zir_index = d.zir_index,
|
||||
.captures = .{ .external = d.captures },
|
||||
} },
|
||||
.reified => |r| .{ .reified = .{
|
||||
.zir_index = r.zir_index,
|
||||
.type_hash = 0,
|
||||
} },
|
||||
} });
|
||||
var gop = try ip.getOrPutKey(gpa, tid, .{ .opaque_type = .{ .declared = .{
|
||||
.zir_index = ini.zir_index,
|
||||
.captures = .{ .external = ini.captures },
|
||||
} } });
|
||||
defer gop.deinit();
|
||||
if (gop == .existing) return .{ .existing = gop.existing };
|
||||
|
||||
|
|
@ -10261,30 +10292,19 @@ pub fn getOpaqueType(
|
|||
const extra = local.getMutableExtra(gpa);
|
||||
try items.ensureUnusedCapacity(1);
|
||||
|
||||
try extra.ensureUnusedCapacity(@typeInfo(Tag.TypeOpaque).@"struct".fields.len + switch (ini.key) {
|
||||
.declared => |d| d.captures.len,
|
||||
.reified => 0,
|
||||
});
|
||||
try extra.ensureUnusedCapacity(@typeInfo(Tag.TypeOpaque).@"struct".fields.len + ini.captures.len);
|
||||
const extra_index = addExtraAssumeCapacity(extra, Tag.TypeOpaque{
|
||||
.name = undefined, // set by `finish`
|
||||
.name_nav = undefined, // set by `finish`
|
||||
.namespace = undefined, // set by `finish`
|
||||
.zir_index = switch (ini.key) {
|
||||
inline else => |x| x.zir_index,
|
||||
},
|
||||
.captures_len = switch (ini.key) {
|
||||
.declared => |d| @intCast(d.captures.len),
|
||||
.reified => std.math.maxInt(u32),
|
||||
},
|
||||
.zir_index = ini.zir_index,
|
||||
.captures_len = @intCast(ini.captures.len),
|
||||
});
|
||||
items.appendAssumeCapacity(.{
|
||||
.tag = .type_opaque,
|
||||
.data = extra_index,
|
||||
});
|
||||
switch (ini.key) {
|
||||
.declared => |d| extra.appendSliceAssumeCapacity(.{@ptrCast(d.captures)}),
|
||||
.reified => {},
|
||||
}
|
||||
extra.appendSliceAssumeCapacity(.{@ptrCast(ini.captures)});
|
||||
return .{
|
||||
.wip = .{
|
||||
.tid = tid,
|
||||
|
|
@ -10555,6 +10575,8 @@ pub fn slicePtrType(ip: *const InternPool, index: Index) Index {
|
|||
switch (index) {
|
||||
.slice_const_u8_type => return .manyptr_const_u8_type,
|
||||
.slice_const_u8_sentinel_0_type => return .manyptr_const_u8_sentinel_0_type,
|
||||
.slice_const_slice_const_u8_type => return .manyptr_const_slice_const_u8_type,
|
||||
.slice_const_type_type => return .manyptr_const_type_type,
|
||||
else => {},
|
||||
}
|
||||
const item = index.unwrap(ip).getItem(ip);
|
||||
|
|
@ -12013,8 +12035,13 @@ pub fn typeOf(ip: *const InternPool, index: Index) Index {
|
|||
.manyptr_u8_type,
|
||||
.manyptr_const_u8_type,
|
||||
.manyptr_const_u8_sentinel_0_type,
|
||||
.manyptr_const_slice_const_u8_type,
|
||||
.slice_const_u8_type,
|
||||
.slice_const_u8_sentinel_0_type,
|
||||
.slice_const_slice_const_u8_type,
|
||||
.optional_type_type,
|
||||
.manyptr_const_type_type,
|
||||
.slice_const_type_type,
|
||||
.vector_8_i8_type,
|
||||
.vector_16_i8_type,
|
||||
.vector_32_i8_type,
|
||||
|
|
@ -12355,8 +12382,12 @@ pub fn zigTypeTag(ip: *const InternPool, index: Index) std.builtin.TypeId {
|
|||
.manyptr_u8_type,
|
||||
.manyptr_const_u8_type,
|
||||
.manyptr_const_u8_sentinel_0_type,
|
||||
.manyptr_const_slice_const_u8_type,
|
||||
.slice_const_u8_type,
|
||||
.slice_const_u8_sentinel_0_type,
|
||||
.slice_const_slice_const_u8_type,
|
||||
.manyptr_const_type_type,
|
||||
.slice_const_type_type,
|
||||
=> .pointer,
|
||||
|
||||
.vector_8_i8_type,
|
||||
|
|
@ -12408,6 +12439,7 @@ pub fn zigTypeTag(ip: *const InternPool, index: Index) std.builtin.TypeId {
|
|||
.vector_8_f64_type,
|
||||
=> .vector,
|
||||
|
||||
.optional_type_type => .optional,
|
||||
.optional_noreturn_type => .optional,
|
||||
.anyerror_void_error_union_type => .error_union,
|
||||
.empty_tuple_type => .@"struct",
|
||||
|
|
|
|||
2517
src/Sema.zig
2517
src/Sema.zig
File diff suppressed because it is too large
Load diff
10
src/Type.zig
10
src/Type.zig
|
|
@ -317,7 +317,7 @@ pub fn print(ty: Type, writer: *std.Io.Writer, pt: Zcu.PerThread, ctx: ?*Compari
|
|||
.undefined,
|
||||
=> try writer.print("@TypeOf({s})", .{@tagName(s)}),
|
||||
|
||||
.enum_literal => try writer.writeAll("@Type(.enum_literal)"),
|
||||
.enum_literal => try writer.writeAll("@EnumLiteral()"),
|
||||
|
||||
.generic_poison => unreachable,
|
||||
},
|
||||
|
|
@ -3509,7 +3509,9 @@ pub fn typeDeclSrcLine(ty: Type, zcu: *Zcu) ?u32 {
|
|||
.union_decl => zir.extraData(Zir.Inst.UnionDecl, inst.data.extended.operand).data.src_line,
|
||||
.enum_decl => zir.extraData(Zir.Inst.EnumDecl, inst.data.extended.operand).data.src_line,
|
||||
.opaque_decl => zir.extraData(Zir.Inst.OpaqueDecl, inst.data.extended.operand).data.src_line,
|
||||
.reify => zir.extraData(Zir.Inst.Reify, inst.data.extended.operand).data.src_line,
|
||||
.reify_enum => zir.extraData(Zir.Inst.ReifyEnum, inst.data.extended.operand).data.src_line,
|
||||
.reify_struct => zir.extraData(Zir.Inst.ReifyStruct, inst.data.extended.operand).data.src_line,
|
||||
.reify_union => zir.extraData(Zir.Inst.ReifyUnion, inst.data.extended.operand).data.src_line,
|
||||
else => unreachable,
|
||||
},
|
||||
else => unreachable,
|
||||
|
|
@ -4280,6 +4282,10 @@ pub const manyptr_const_u8: Type = .{ .ip_index = .manyptr_const_u8_type };
|
|||
pub const manyptr_const_u8_sentinel_0: Type = .{ .ip_index = .manyptr_const_u8_sentinel_0_type };
|
||||
pub const slice_const_u8: Type = .{ .ip_index = .slice_const_u8_type };
|
||||
pub const slice_const_u8_sentinel_0: Type = .{ .ip_index = .slice_const_u8_sentinel_0_type };
|
||||
pub const slice_const_slice_const_u8: Type = .{ .ip_index = .slice_const_slice_const_u8_type };
|
||||
pub const slice_const_type: Type = .{ .ip_index = .slice_const_type_type };
|
||||
pub const optional_type: Type = .{ .ip_index = .optional_type_type };
|
||||
pub const optional_noreturn: Type = .{ .ip_index = .optional_noreturn_type };
|
||||
|
||||
pub const vector_8_i8: Type = .{ .ip_index = .vector_8_i8_type };
|
||||
pub const vector_16_i8: Type = .{ .ip_index = .vector_16_i8_type };
|
||||
|
|
|
|||
|
|
@ -2824,6 +2824,29 @@ pub fn resolveLazy(
|
|||
.val = resolved_val,
|
||||
}));
|
||||
},
|
||||
.error_union => |eu| switch (eu.val) {
|
||||
.err_name => return val,
|
||||
.payload => |payload| {
|
||||
const resolved_payload = try Value.fromInterned(payload).resolveLazy(arena, pt);
|
||||
if (resolved_payload.toIntern() == payload) return val;
|
||||
return .fromInterned(try pt.intern(.{ .error_union = .{
|
||||
.ty = eu.ty,
|
||||
.val = .{ .payload = resolved_payload.toIntern() },
|
||||
} }));
|
||||
},
|
||||
},
|
||||
.opt => |opt| switch (opt.val) {
|
||||
.none => return val,
|
||||
else => |payload| {
|
||||
const resolved_payload = try Value.fromInterned(payload).resolveLazy(arena, pt);
|
||||
if (resolved_payload.toIntern() == payload) return val;
|
||||
return .fromInterned(try pt.intern(.{ .opt = .{
|
||||
.ty = opt.ty,
|
||||
.val = resolved_payload.toIntern(),
|
||||
} }));
|
||||
},
|
||||
},
|
||||
|
||||
else => return val,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
24
src/Zcu.zig
24
src/Zcu.zig
|
|
@ -416,10 +416,13 @@ pub const BuiltinDecl = enum {
|
|||
Type,
|
||||
@"Type.Fn",
|
||||
@"Type.Fn.Param",
|
||||
@"Type.Fn.Param.Attributes",
|
||||
@"Type.Fn.Attributes",
|
||||
@"Type.Int",
|
||||
@"Type.Float",
|
||||
@"Type.Pointer",
|
||||
@"Type.Pointer.Size",
|
||||
@"Type.Pointer.Attributes",
|
||||
@"Type.Array",
|
||||
@"Type.Vector",
|
||||
@"Type.Optional",
|
||||
|
|
@ -427,10 +430,13 @@ pub const BuiltinDecl = enum {
|
|||
@"Type.ErrorUnion",
|
||||
@"Type.EnumField",
|
||||
@"Type.Enum",
|
||||
@"Type.Enum.Mode",
|
||||
@"Type.Union",
|
||||
@"Type.UnionField",
|
||||
@"Type.UnionField.Attributes",
|
||||
@"Type.Struct",
|
||||
@"Type.StructField",
|
||||
@"Type.StructField.Attributes",
|
||||
@"Type.ContainerLayout",
|
||||
@"Type.Opaque",
|
||||
@"Type.Declaration",
|
||||
|
|
@ -495,10 +501,13 @@ pub const BuiltinDecl = enum {
|
|||
.Type,
|
||||
.@"Type.Fn",
|
||||
.@"Type.Fn.Param",
|
||||
.@"Type.Fn.Param.Attributes",
|
||||
.@"Type.Fn.Attributes",
|
||||
.@"Type.Int",
|
||||
.@"Type.Float",
|
||||
.@"Type.Pointer",
|
||||
.@"Type.Pointer.Size",
|
||||
.@"Type.Pointer.Attributes",
|
||||
.@"Type.Array",
|
||||
.@"Type.Vector",
|
||||
.@"Type.Optional",
|
||||
|
|
@ -506,10 +515,13 @@ pub const BuiltinDecl = enum {
|
|||
.@"Type.ErrorUnion",
|
||||
.@"Type.EnumField",
|
||||
.@"Type.Enum",
|
||||
.@"Type.Enum.Mode",
|
||||
.@"Type.Union",
|
||||
.@"Type.UnionField",
|
||||
.@"Type.UnionField.Attributes",
|
||||
.@"Type.Struct",
|
||||
.@"Type.StructField",
|
||||
.@"Type.StructField.Attributes",
|
||||
.@"Type.ContainerLayout",
|
||||
.@"Type.Opaque",
|
||||
.@"Type.Declaration",
|
||||
|
|
@ -1745,28 +1757,28 @@ pub const SrcLoc = struct {
|
|||
const node = node_off.toAbsolute(src_loc.base_node);
|
||||
var buf: [1]Ast.Node.Index = undefined;
|
||||
const full = tree.fullFnProto(&buf, node).?;
|
||||
return tree.nodeToSpan(full.ast.align_expr.unwrap().?);
|
||||
return tree.nodeToSpan(full.ast.align_expr.unwrap() orelse node);
|
||||
},
|
||||
.node_offset_fn_type_addrspace => |node_off| {
|
||||
const tree = try src_loc.file_scope.getTree(zcu);
|
||||
const node = node_off.toAbsolute(src_loc.base_node);
|
||||
var buf: [1]Ast.Node.Index = undefined;
|
||||
const full = tree.fullFnProto(&buf, node).?;
|
||||
return tree.nodeToSpan(full.ast.addrspace_expr.unwrap().?);
|
||||
return tree.nodeToSpan(full.ast.addrspace_expr.unwrap() orelse node);
|
||||
},
|
||||
.node_offset_fn_type_section => |node_off| {
|
||||
const tree = try src_loc.file_scope.getTree(zcu);
|
||||
const node = node_off.toAbsolute(src_loc.base_node);
|
||||
var buf: [1]Ast.Node.Index = undefined;
|
||||
const full = tree.fullFnProto(&buf, node).?;
|
||||
return tree.nodeToSpan(full.ast.section_expr.unwrap().?);
|
||||
return tree.nodeToSpan(full.ast.section_expr.unwrap() orelse node);
|
||||
},
|
||||
.node_offset_fn_type_cc => |node_off| {
|
||||
const tree = try src_loc.file_scope.getTree(zcu);
|
||||
const node = node_off.toAbsolute(src_loc.base_node);
|
||||
var buf: [1]Ast.Node.Index = undefined;
|
||||
const full = tree.fullFnProto(&buf, node).?;
|
||||
return tree.nodeToSpan(full.ast.callconv_expr.unwrap().?);
|
||||
return tree.nodeToSpan(full.ast.callconv_expr.unwrap() orelse node);
|
||||
},
|
||||
|
||||
.node_offset_fn_type_ret_ty => |node_off| {
|
||||
|
|
@ -2684,7 +2696,9 @@ pub const LazySrcLoc = struct {
|
|||
.union_decl => zir.extraData(Zir.Inst.UnionDecl, inst.data.extended.operand).data.src_node,
|
||||
.enum_decl => zir.extraData(Zir.Inst.EnumDecl, inst.data.extended.operand).data.src_node,
|
||||
.opaque_decl => zir.extraData(Zir.Inst.OpaqueDecl, inst.data.extended.operand).data.src_node,
|
||||
.reify => zir.extraData(Zir.Inst.Reify, inst.data.extended.operand).data.node,
|
||||
.reify_enum => zir.extraData(Zir.Inst.ReifyEnum, inst.data.extended.operand).data.node,
|
||||
.reify_struct => zir.extraData(Zir.Inst.ReifyStruct, inst.data.extended.operand).data.node,
|
||||
.reify_union => zir.extraData(Zir.Inst.ReifyUnion, inst.data.extended.operand).data.node,
|
||||
else => unreachable,
|
||||
},
|
||||
else => unreachable,
|
||||
|
|
|
|||
|
|
@ -1416,6 +1416,9 @@ pub const Pool = struct {
|
|||
.null_type,
|
||||
.undefined_type,
|
||||
.enum_literal_type,
|
||||
.optional_type_type,
|
||||
.manyptr_const_type_type,
|
||||
.slice_const_type_type,
|
||||
=> return .void,
|
||||
.u1_type, .u8_type => return .u8,
|
||||
.i8_type => return .i8,
|
||||
|
|
@ -1525,6 +1528,73 @@ pub const Pool = struct {
|
|||
return pool.fromFields(allocator, .@"struct", &fields, kind);
|
||||
},
|
||||
|
||||
.manyptr_const_slice_const_u8_type => {
|
||||
const target = &mod.resolved_target.result;
|
||||
var fields: [2]Info.Field = .{
|
||||
.{
|
||||
.name = .{ .index = .ptr },
|
||||
.ctype = try pool.getPointer(allocator, .{
|
||||
.elem_ctype = .u8,
|
||||
.@"const" = true,
|
||||
.nonstring = true,
|
||||
}),
|
||||
.alignas = AlignAs.fromAbiAlignment(Type.ptrAbiAlignment(target)),
|
||||
},
|
||||
.{
|
||||
.name = .{ .index = .len },
|
||||
.ctype = .usize,
|
||||
.alignas = AlignAs.fromAbiAlignment(
|
||||
.fromByteUnits(std.zig.target.intAlignment(target, target.ptrBitWidth())),
|
||||
),
|
||||
},
|
||||
};
|
||||
const slice_const_u8 = try pool.fromFields(allocator, .@"struct", &fields, kind);
|
||||
return pool.getPointer(allocator, .{
|
||||
.elem_ctype = slice_const_u8,
|
||||
.@"const" = true,
|
||||
});
|
||||
},
|
||||
.slice_const_slice_const_u8_type => {
|
||||
const target = &mod.resolved_target.result;
|
||||
var fields: [2]Info.Field = .{
|
||||
.{
|
||||
.name = .{ .index = .ptr },
|
||||
.ctype = try pool.getPointer(allocator, .{
|
||||
.elem_ctype = .u8,
|
||||
.@"const" = true,
|
||||
.nonstring = true,
|
||||
}),
|
||||
.alignas = AlignAs.fromAbiAlignment(Type.ptrAbiAlignment(target)),
|
||||
},
|
||||
.{
|
||||
.name = .{ .index = .len },
|
||||
.ctype = .usize,
|
||||
.alignas = AlignAs.fromAbiAlignment(
|
||||
.fromByteUnits(std.zig.target.intAlignment(target, target.ptrBitWidth())),
|
||||
),
|
||||
},
|
||||
};
|
||||
const slice_const_u8 = try pool.fromFields(allocator, .@"struct", &fields, .forward);
|
||||
fields = .{
|
||||
.{
|
||||
.name = .{ .index = .ptr },
|
||||
.ctype = try pool.getPointer(allocator, .{
|
||||
.elem_ctype = slice_const_u8,
|
||||
.@"const" = true,
|
||||
}),
|
||||
.alignas = AlignAs.fromAbiAlignment(Type.ptrAbiAlignment(target)),
|
||||
},
|
||||
.{
|
||||
.name = .{ .index = .len },
|
||||
.ctype = .usize,
|
||||
.alignas = AlignAs.fromAbiAlignment(
|
||||
.fromByteUnits(std.zig.target.intAlignment(target, target.ptrBitWidth())),
|
||||
),
|
||||
},
|
||||
};
|
||||
return pool.fromFields(allocator, .@"struct", &fields, kind);
|
||||
},
|
||||
|
||||
.vector_8_i8_type => {
|
||||
const vector_ctype = try pool.getVector(allocator, .{
|
||||
.elem_ctype = .i8,
|
||||
|
|
|
|||
|
|
@ -4490,7 +4490,12 @@ fn updateContainerTypeWriterError(
|
|||
.enum_decl => @as(Zir.Inst.EnumDecl.Small, @bitCast(decl_inst.data.extended.small)).name_strategy,
|
||||
.union_decl => @as(Zir.Inst.UnionDecl.Small, @bitCast(decl_inst.data.extended.small)).name_strategy,
|
||||
.opaque_decl => @as(Zir.Inst.OpaqueDecl.Small, @bitCast(decl_inst.data.extended.small)).name_strategy,
|
||||
.reify => @as(Zir.Inst.NameStrategy, @enumFromInt(decl_inst.data.extended.small)),
|
||||
|
||||
.reify_enum,
|
||||
.reify_struct,
|
||||
.reify_union,
|
||||
=> @enumFromInt(decl_inst.data.extended.small),
|
||||
|
||||
else => unreachable,
|
||||
},
|
||||
else => unreachable,
|
||||
|
|
|
|||
|
|
@ -399,6 +399,7 @@ const Writer = struct {
|
|||
.splat,
|
||||
.reduce,
|
||||
.bitcast,
|
||||
.reify_int,
|
||||
.vector_type,
|
||||
.max,
|
||||
.min,
|
||||
|
|
@ -568,6 +569,8 @@ const Writer = struct {
|
|||
.work_group_id,
|
||||
.branch_hint,
|
||||
.float_op_result_ty,
|
||||
.reify_tuple,
|
||||
.reify_pointer_sentinel_ty,
|
||||
=> {
|
||||
const inst_data = self.code.extraData(Zir.Inst.UnNode, extended.operand).data;
|
||||
try self.writeInstRef(stream, inst_data.operand);
|
||||
|
|
@ -575,23 +578,13 @@ const Writer = struct {
|
|||
try self.writeSrcNode(stream, inst_data.node);
|
||||
},
|
||||
|
||||
.reify => {
|
||||
const inst_data = self.code.extraData(Zir.Inst.Reify, extended.operand).data;
|
||||
try stream.print("line({d}), ", .{inst_data.src_line});
|
||||
try self.writeInstRef(stream, inst_data.operand);
|
||||
try stream.writeAll(")) ");
|
||||
const prev_parent_decl_node = self.parent_decl_node;
|
||||
self.parent_decl_node = inst_data.node;
|
||||
defer self.parent_decl_node = prev_parent_decl_node;
|
||||
try self.writeSrcNode(stream, .zero);
|
||||
},
|
||||
|
||||
.builtin_extern,
|
||||
.c_define,
|
||||
.error_cast,
|
||||
.wasm_memory_grow,
|
||||
.prefetch,
|
||||
.c_va_arg,
|
||||
.reify_enum_value_slice_ty,
|
||||
=> {
|
||||
const inst_data = self.code.extraData(Zir.Inst.BinNode, extended.operand).data;
|
||||
try self.writeInstRef(stream, inst_data.lhs);
|
||||
|
|
@ -601,6 +594,95 @@ const Writer = struct {
|
|||
try self.writeSrcNode(stream, inst_data.node);
|
||||
},
|
||||
|
||||
.reify_slice_arg_ty => {
|
||||
const reify_slice_arg_info: Zir.Inst.ReifySliceArgInfo = @enumFromInt(extended.operand);
|
||||
const extra = self.code.extraData(Zir.Inst.UnNode, extended.operand).data;
|
||||
try stream.print("{t}, ", .{reify_slice_arg_info});
|
||||
try self.writeInstRef(stream, extra.operand);
|
||||
try stream.writeAll(")) ");
|
||||
try self.writeSrcNode(stream, extra.node);
|
||||
},
|
||||
|
||||
.reify_pointer => {
|
||||
const extra = self.code.extraData(Zir.Inst.ReifyPointer, extended.operand).data;
|
||||
try self.writeInstRef(stream, extra.size);
|
||||
try stream.writeAll(", ");
|
||||
try self.writeInstRef(stream, extra.attrs);
|
||||
try stream.writeAll(", ");
|
||||
try self.writeInstRef(stream, extra.elem_ty);
|
||||
try stream.writeAll(", ");
|
||||
try self.writeInstRef(stream, extra.sentinel);
|
||||
try stream.writeAll(")) ");
|
||||
try self.writeSrcNode(stream, extra.node);
|
||||
},
|
||||
.reify_fn => {
|
||||
const extra = self.code.extraData(Zir.Inst.ReifyFn, extended.operand).data;
|
||||
try self.writeInstRef(stream, extra.param_types);
|
||||
try stream.writeAll(", ");
|
||||
try self.writeInstRef(stream, extra.param_attrs);
|
||||
try stream.writeAll(", ");
|
||||
try self.writeInstRef(stream, extra.ret_ty);
|
||||
try stream.writeAll(", ");
|
||||
try self.writeInstRef(stream, extra.fn_attrs);
|
||||
try stream.writeAll(")) ");
|
||||
try self.writeSrcNode(stream, extra.node);
|
||||
},
|
||||
.reify_struct => {
|
||||
const extra = self.code.extraData(Zir.Inst.ReifyStruct, extended.operand).data;
|
||||
const name_strat: Zir.Inst.NameStrategy = @enumFromInt(extended.small);
|
||||
try stream.print("line({d}), {t}, ", .{ extra.src_line, name_strat });
|
||||
try self.writeInstRef(stream, extra.layout);
|
||||
try stream.writeAll(", ");
|
||||
try self.writeInstRef(stream, extra.backing_ty);
|
||||
try stream.writeAll(", ");
|
||||
try self.writeInstRef(stream, extra.field_names);
|
||||
try stream.writeAll(", ");
|
||||
try self.writeInstRef(stream, extra.field_types);
|
||||
try stream.writeAll(", ");
|
||||
try self.writeInstRef(stream, extra.field_attrs);
|
||||
try stream.writeAll(")) ");
|
||||
const prev_parent_decl_node = self.parent_decl_node;
|
||||
self.parent_decl_node = extra.node;
|
||||
defer self.parent_decl_node = prev_parent_decl_node;
|
||||
try self.writeSrcNode(stream, .zero);
|
||||
},
|
||||
.reify_union => {
|
||||
const extra = self.code.extraData(Zir.Inst.ReifyUnion, extended.operand).data;
|
||||
const name_strat: Zir.Inst.NameStrategy = @enumFromInt(extended.small);
|
||||
try stream.print("line({d}), {t}, ", .{ extra.src_line, name_strat });
|
||||
try self.writeInstRef(stream, extra.layout);
|
||||
try stream.writeAll(", ");
|
||||
try self.writeInstRef(stream, extra.arg_ty);
|
||||
try stream.writeAll(", ");
|
||||
try self.writeInstRef(stream, extra.field_names);
|
||||
try stream.writeAll(", ");
|
||||
try self.writeInstRef(stream, extra.field_types);
|
||||
try stream.writeAll(", ");
|
||||
try self.writeInstRef(stream, extra.field_attrs);
|
||||
try stream.writeAll(")) ");
|
||||
const prev_parent_decl_node = self.parent_decl_node;
|
||||
self.parent_decl_node = extra.node;
|
||||
defer self.parent_decl_node = prev_parent_decl_node;
|
||||
try self.writeSrcNode(stream, .zero);
|
||||
},
|
||||
.reify_enum => {
|
||||
const extra = self.code.extraData(Zir.Inst.ReifyEnum, extended.operand).data;
|
||||
const name_strat: Zir.Inst.NameStrategy = @enumFromInt(extended.small);
|
||||
try stream.print("line({d}), {t}, ", .{ extra.src_line, name_strat });
|
||||
try self.writeInstRef(stream, extra.tag_ty);
|
||||
try stream.writeAll(", ");
|
||||
try self.writeInstRef(stream, extra.mode);
|
||||
try stream.writeAll(", ");
|
||||
try self.writeInstRef(stream, extra.field_names);
|
||||
try stream.writeAll(", ");
|
||||
try self.writeInstRef(stream, extra.field_values);
|
||||
try stream.writeAll(")) ");
|
||||
const prev_parent_decl_node = self.parent_decl_node;
|
||||
self.parent_decl_node = extra.node;
|
||||
defer self.parent_decl_node = prev_parent_decl_node;
|
||||
try self.writeSrcNode(stream, .zero);
|
||||
},
|
||||
|
||||
.cmpxchg => try self.writeCmpxchg(stream, extended),
|
||||
.ptr_cast_full => try self.writePtrCastFull(stream, extended),
|
||||
.ptr_cast_no_dest => try self.writePtrCastNoDest(stream, extended),
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue