Skip to content

Commit c538317

Browse files
mluggalichraghi
andcommitted
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 <[email protected]> Resolves: #10710
1 parent 3f2cf1c commit c538317

File tree

16 files changed

+2034
-1429
lines changed

16 files changed

+2034
-1429
lines changed

doc/langref.html.in

Lines changed: 74 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -638,7 +638,7 @@
638638
{#syntax#}i7{#endsyntax#} refers to a signed 7-bit integer. The maximum allowed bit-width of an
639639
integer type is {#syntax#}65535{#endsyntax#}.
640640
</p>
641-
{#see_also|Integers|Floats|void|Errors|@Type#}
641+
{#see_also|Integers|Floats|void|Errors|@Int#}
642642
{#header_close#}
643643
{#header_open|Primitive Values#}
644644
<div class="table-wrapper">
@@ -3723,9 +3723,9 @@ void do_a_thing(struct Foo *foo) {
37233723
<td>{#syntax#}x{#endsyntax#} is a {#syntax#}@FieldType(T, "a"){#endsyntax#}</td>
37243724
</tr>
37253725
<tr>
3726-
<th scope="row">{#syntax#}@Type(x){#endsyntax#}</th>
3726+
<th scope="row">{#syntax#}@Int(x, y){#endsyntax#}</th>
37273727
<td>-</td>
3728-
<td>{#syntax#}x{#endsyntax#} is a {#syntax#}std.builtin.Type{#endsyntax#}</td>
3728+
<td>{#syntax#}x{#endsyntax#} is a {#syntax#}std.builtin.Signedness{#endsyntax#}, {#syntax#}y{#endsyntax#} is a {#syntax#}u16{#endsyntax#}</td>
37293729
</tr>
37303730
<tr>
37313731
<th scope="row">{#syntax#}@typeInfo(x){#endsyntax#}</th>
@@ -3839,9 +3839,9 @@ void do_a_thing(struct Foo *foo) {
38393839
<td>{#syntax#}x{#endsyntax#} has no result location (typed initializers do not propagate result locations)</td>
38403840
</tr>
38413841
<tr>
3842-
<th scope="row">{#syntax#}@Type(x){#endsyntax#}</th>
3843-
<td>{#syntax#}ptr{#endsyntax#}</td>
3844-
<td>{#syntax#}x{#endsyntax#} has no result location</td>
3842+
<th scope="row">{#syntax#}@Int(x, y){#endsyntax#}</th>
3843+
<td>-</td>
3844+
<td>{#syntax#}x{#endsyntax#} and {#syntax#}y{#endsyntax#} do not have result locations</td>
38453845
</tr>
38463846
<tr>
38473847
<th scope="row">{#syntax#}@typeInfo(x){#endsyntax#}</th>
@@ -5755,41 +5755,75 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val
57555755
</p>
57565756
{#header_close#}
57575757

5758-
{#header_open|@Type#}
5759-
<pre>{#syntax#}@Type(comptime info: std.builtin.Type) type{#endsyntax#}</pre>
5760-
<p>
5761-
This function is the inverse of {#link|@typeInfo#}. It reifies type information
5762-
into a {#syntax#}type{#endsyntax#}.
5763-
</p>
5764-
<p>
5765-
It is available for the following types:
5766-
</p>
5767-
<ul>
5768-
<li>{#syntax#}type{#endsyntax#}</li>
5769-
<li>{#syntax#}noreturn{#endsyntax#}</li>
5770-
<li>{#syntax#}void{#endsyntax#}</li>
5771-
<li>{#syntax#}bool{#endsyntax#}</li>
5772-
<li>{#link|Integers#} - The maximum bit count for an integer type is {#syntax#}65535{#endsyntax#}.</li>
5773-
<li>{#link|Floats#}</li>
5774-
<li>{#link|Pointers#}</li>
5775-
<li>{#syntax#}comptime_int{#endsyntax#}</li>
5776-
<li>{#syntax#}comptime_float{#endsyntax#}</li>
5777-
<li>{#syntax#}@TypeOf(undefined){#endsyntax#}</li>
5778-
<li>{#syntax#}@TypeOf(null){#endsyntax#}</li>
5779-
<li>{#link|Arrays#}</li>
5780-
<li>{#link|Optionals#}</li>
5781-
<li>{#link|Error Set Type#}</li>
5782-
<li>{#link|Error Union Type#}</li>
5783-
<li>{#link|Vectors#}</li>
5784-
<li>{#link|opaque#}</li>
5785-
<li>{#syntax#}anyframe{#endsyntax#}</li>
5786-
<li>{#link|struct#}</li>
5787-
<li>{#link|enum#}</li>
5788-
<li>{#link|Enum Literals#}</li>
5789-
<li>{#link|union#}</li>
5790-
<li>{#link|Functions#}</li>
5791-
</ul>
5758+
{#header_open|@EnumLiteral#}
5759+
<pre>{#syntax#}@EnumLiteral() type{#endsyntax#}</pre>
5760+
<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>
5761+
{#header_close#}
5762+
5763+
{#header_open|@Int#}
5764+
<pre>{#syntax#}@Int(comptime signedness: std.builtin.Signedness, comptime bits: u16) type{#endsyntax#}</pre>
5765+
<p>Returns an integer type with the given signedness and bit width.</p>
5766+
<p>For instance, {#syntax#}@Int(.unsigned, 18){#endsyntax#} returns the type {#syntax#}u18{#endsyntax#}.</p>
57925767
{#header_close#}
5768+
5769+
{#header_open|@Tuple#}
5770+
<pre>{#syntax#}@Tuple(comptime field_types: []const type) type{#endsyntax#}</pre>
5771+
<p>Returns a {#link|tuple|Tuples#} type with the given field types.</p>
5772+
{#header_close#}
5773+
5774+
{#header_open|@Pointer#}
5775+
<pre>{#syntax#}@Pointer(
5776+
comptime size: std.builtin.Type.Pointer.Size,
5777+
comptime attrs: std.builtin.Type.Pointer.Attributes,
5778+
comptime Element: type,
5779+
comptime sentinel: ?Element,
5780+
) type{#endsyntax#}</pre>
5781+
<p>Returns a {#link|pointer|Pointers#} type with the properties specified by the arguments.</p>
5782+
{#header_close#}
5783+
5784+
{#header_open|@Fn#}
5785+
<pre>{#syntax#}@Fn(
5786+
comptime param_types: []const type,
5787+
comptime param_attrs: *const [param_types.len]std.builtin.Type.Fn.Param.Attributes,
5788+
comptime ReturnType: type,
5789+
comptime attrs: std.builtin.Type.Fn.Attributes,
5790+
) type{#endsyntax#}</pre>
5791+
<p>Returns a {#link|function|Functions#} type with the properties specified by the arguments.</p>
5792+
{#header_close#}
5793+
5794+
{#header_open|@Struct#}
5795+
<pre>{#syntax#}@Struct(
5796+
comptime layout: std.builtin.Type.ContainerLayout,
5797+
comptime BackingInt: ?type,
5798+
comptime field_names: []const []const u8,
5799+
comptime field_types: *const [field_names.len]type,
5800+
comptime field_attrs: *const [field_names.len]std.builtin.Type.StructField.Attributes,
5801+
) type{#endsyntax#}</pre>
5802+
<p>Returns a {#link|struct#} type with the properties specified by the arguments.</p>
5803+
{#header_close#}
5804+
5805+
{#header_open|@Union#}
5806+
<pre>{#syntax#}@Union(
5807+
comptime layout: std.builtin.Type.ContainerLayout,
5808+
/// Either the integer tag type, or the integer backing type, depending on `layout`.
5809+
comptime ArgType: ?type,
5810+
comptime field_names: []const []const u8,
5811+
comptime field_types: *const [field_names.len]type,
5812+
comptime field_attrs: *const [field_names.len]std.builtin.Type.UnionField.Attributes,
5813+
) type{#endsyntax#}</pre>
5814+
<p>Returns a {#link|union#} type with the properties specified by the arguments.</p>
5815+
{#header_close#}
5816+
5817+
{#header_open|@Enum#}
5818+
<pre>{#syntax#}@Enum(
5819+
comptime TagInt: type,
5820+
comptime mode: std.builtin.Type.Enum.Mode,
5821+
comptime field_names: []const []const u8,
5822+
comptime field_values: *const [field_names.len]TagInt,
5823+
) type{#endsyntax#}</pre>
5824+
<p>Returns an {#link|enum#} type with the properties specified by the arguments.</p>
5825+
{#header_close#}
5826+
57935827
{#header_open|@typeInfo#}
57945828
<pre>{#syntax#}@typeInfo(comptime T: type) std.builtin.Type{#endsyntax#}</pre>
57955829
<p>

lib/std/builtin.zig

Lines changed: 50 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -548,19 +548,19 @@ pub const TypeId = std.meta.Tag(Type);
548548
/// This data structure is used by the Zig language code generation and
549549
/// therefore must be kept in sync with the compiler implementation.
550550
pub const Type = union(enum) {
551-
type: void,
552-
void: void,
553-
bool: void,
554-
noreturn: void,
551+
type,
552+
void,
553+
bool,
554+
noreturn,
555555
int: Int,
556556
float: Float,
557557
pointer: Pointer,
558558
array: Array,
559559
@"struct": Struct,
560-
comptime_float: void,
561-
comptime_int: void,
562-
undefined: void,
563-
null: void,
560+
comptime_float,
561+
comptime_int,
562+
undefined,
563+
null,
564564
optional: Optional,
565565
error_union: ErrorUnion,
566566
error_set: ErrorSet,
@@ -571,7 +571,7 @@ pub const Type = union(enum) {
571571
frame: Frame,
572572
@"anyframe": AnyFrame,
573573
vector: Vector,
574-
enum_literal: void,
574+
enum_literal,
575575

576576
/// This data structure is used by the Zig language code generation and
577577
/// therefore must be kept in sync with the compiler implementation.
@@ -619,6 +619,16 @@ pub const Type = union(enum) {
619619
slice,
620620
c,
621621
};
622+
623+
/// This data structure is used by the Zig language code generation and
624+
/// therefore must be kept in sync with the compiler implementation.
625+
pub const Attributes = struct {
626+
@"const": bool = false,
627+
@"volatile": bool = false,
628+
@"allowzero": bool = false,
629+
@"addrspace": ?AddressSpace = null,
630+
@"align": ?usize = null,
631+
};
622632
};
623633

624634
/// This data structure is used by the Zig language code generation and
@@ -668,6 +678,14 @@ pub const Type = union(enum) {
668678
const dp: *const sf.type = @ptrCast(@alignCast(sf.default_value_ptr orelse return null));
669679
return dp.*;
670680
}
681+
682+
/// This data structure is used by the Zig language code generation and
683+
/// therefore must be kept in sync with the compiler implementation.
684+
pub const Attributes = struct {
685+
@"comptime": bool = false,
686+
@"align": ?usize = null,
687+
default_value_ptr: ?*const anyopaque = null,
688+
};
671689
};
672690

673691
/// This data structure is used by the Zig language code generation and
@@ -718,6 +736,10 @@ pub const Type = union(enum) {
718736
fields: []const EnumField,
719737
decls: []const Declaration,
720738
is_exhaustive: bool,
739+
740+
/// This data structure is used by the Zig language code generation and
741+
/// therefore must be kept in sync with the compiler implementation.
742+
pub const Mode = enum { exhaustive, nonexhaustive };
721743
};
722744

723745
/// This data structure is used by the Zig language code generation and
@@ -726,6 +748,12 @@ pub const Type = union(enum) {
726748
name: [:0]const u8,
727749
type: type,
728750
alignment: comptime_int,
751+
752+
/// This data structure is used by the Zig language code generation and
753+
/// therefore must be kept in sync with the compiler implementation.
754+
pub const Attributes = struct {
755+
@"align": ?usize = null,
756+
};
729757
};
730758

731759
/// This data structure is used by the Zig language code generation and
@@ -753,6 +781,19 @@ pub const Type = union(enum) {
753781
is_generic: bool,
754782
is_noalias: bool,
755783
type: ?type,
784+
785+
/// This data structure is used by the Zig language code generation and
786+
/// therefore must be kept in sync with the compiler implementation.
787+
pub const Attributes = struct {
788+
@"noalias": bool = false,
789+
};
790+
};
791+
792+
/// This data structure is used by the Zig language code generation and
793+
/// therefore must be kept in sync with the compiler implementation.
794+
pub const Attributes = struct {
795+
@"callconv": CallingConvention = .auto,
796+
varargs: bool = false,
756797
};
757798
};
758799

lib/std/zig.zig

Lines changed: 40 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -773,7 +773,6 @@ pub const EnvVar = enum {
773773
pub const SimpleComptimeReason = enum(u32) {
774774
// Evaluating at comptime because a builtin operand must be comptime-known.
775775
// These messages all mention a specific builtin.
776-
operand_Type,
777776
operand_setEvalBranchQuota,
778777
operand_setFloatMode,
779778
operand_branchHint,
@@ -809,25 +808,34 @@ pub const SimpleComptimeReason = enum(u32) {
809808
// Evaluating at comptime because types must be comptime-known.
810809
// Reasons other than `.type` are just more specific messages.
811810
type,
811+
int_signedness,
812+
int_bit_width,
812813
array_sentinel,
814+
array_length,
815+
pointer_size,
816+
pointer_attrs,
813817
pointer_sentinel,
814818
slice_sentinel,
815-
array_length,
816819
vector_length,
817-
error_set_contents,
818-
struct_fields,
819-
enum_fields,
820-
union_fields,
821-
function_ret_ty,
822-
function_parameters,
820+
fn_ret_ty,
821+
fn_param_types,
822+
fn_param_attrs,
823+
fn_attrs,
824+
struct_layout,
825+
struct_field_names,
826+
struct_field_types,
827+
struct_field_attrs,
828+
union_layout,
829+
union_field_names,
830+
union_field_types,
831+
union_field_attrs,
832+
tuple_field_types,
833+
enum_field_names,
834+
enum_field_values,
823835

824836
// Evaluating at comptime because decl/field name must be comptime-known.
825837
decl_name,
826838
field_name,
827-
struct_field_name,
828-
enum_field_name,
829-
union_field_name,
830-
tuple_field_name,
831839
tuple_field_index,
832840

833841
// Evaluating at comptime because it is an attribute of a global declaration.
@@ -856,7 +864,6 @@ pub const SimpleComptimeReason = enum(u32) {
856864
pub fn message(r: SimpleComptimeReason) []const u8 {
857865
return switch (r) {
858866
// zig fmt: off
859-
.operand_Type => "operand to '@Type' must be comptime-known",
860867
.operand_setEvalBranchQuota => "operand to '@setEvalBranchQuota' must be comptime-known",
861868
.operand_setFloatMode => "operand to '@setFloatMode' must be comptime-known",
862869
.operand_branchHint => "operand to '@branchHint' must be comptime-known",
@@ -888,24 +895,33 @@ pub const SimpleComptimeReason = enum(u32) {
888895
.clobber => "clobber must be comptime-known",
889896

890897
.type => "types must be comptime-known",
898+
.int_signedness => "integer signedness must be comptime-known",
899+
.int_bit_width => "integer bit width must be comptime-known",
891900
.array_sentinel => "array sentinel value must be comptime-known",
901+
.array_length => "array length must be comptime-known",
902+
.pointer_size => "pointer size must be comptime-known",
903+
.pointer_attrs => "pointer attributes must be comptime-known",
892904
.pointer_sentinel => "pointer sentinel value must be comptime-known",
893905
.slice_sentinel => "slice sentinel value must be comptime-known",
894-
.array_length => "array length must be comptime-known",
895906
.vector_length => "vector length must be comptime-known",
896-
.error_set_contents => "error set contents must be comptime-known",
897-
.struct_fields => "struct fields must be comptime-known",
898-
.enum_fields => "enum fields must be comptime-known",
899-
.union_fields => "union fields must be comptime-known",
900-
.function_ret_ty => "function return type must be comptime-known",
901-
.function_parameters => "function parameters must be comptime-known",
907+
.fn_ret_ty => "function return type must be comptime-known",
908+
.fn_param_types => "function parameter types must be comptime-known",
909+
.fn_param_attrs => "function parameter attributes must be comptime-known",
910+
.fn_attrs => "function attributes must be comptime-known",
911+
.struct_layout => "struct layout must be comptime-known",
912+
.struct_field_names => "struct field names must be comptime-known",
913+
.struct_field_types => "struct field types must be comptime-known",
914+
.struct_field_attrs => "struct field attributes must be comptime-known",
915+
.union_layout => "union layout must be comptime-known",
916+
.union_field_names => "union field names must be comptime-known",
917+
.union_field_types => "union field types must be comptime-known",
918+
.union_field_attrs => "union field attributes must be comptime-known",
919+
.tuple_field_types => "tuple field types must be comptime-known",
920+
.enum_field_names => "enum field names must be comptime-known",
921+
.enum_field_values => "enum field values must be comptime-known",
902922

903923
.decl_name => "declaration name must be comptime-known",
904924
.field_name => "field name must be comptime-known",
905-
.struct_field_name => "struct field name must be comptime-known",
906-
.enum_field_name => "enum field name must be comptime-known",
907-
.union_field_name => "union field name must be comptime-known",
908-
.tuple_field_name => "tuple field name must be comptime-known",
909925
.tuple_field_index => "tuple field index must be comptime-known",
910926

911927
.container_var_init => "initializer of container-level variable must be comptime-known",

0 commit comments

Comments
 (0)