authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-09-04 11:08:28-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-09-04 11:12:14-04:00
logac7703f65f7acc9137e28ded97659fbaadea4e66
tree41809dbfec90af3c6320239cd186f9ede7b8b8e1
parentb728cb6d4e882592129eef2e37f8fcd8fda78822
signaturelock-open Commit is signed but in an unrecognized format.

fixups and add documentation for `@Type`


7 files changed, 132 insertions(+), 51 deletions(-)

doc/docgen.zig+24-2
...@@ -321,6 +321,7 @@ fn genToc(allocator: *mem.Allocator, tokenizer: *Tokenizer) !Toc {...@@ -321,6 +321,7 @@ fn genToc(allocator: *mem.Allocator, tokenizer: *Tokenizer) !Toc {
321321
322 var header_stack_size: usize = 0;322 var header_stack_size: usize = 0;
323 var last_action = Action.Open;323 var last_action = Action.Open;
324 var last_columns: ?u8 = null;
324325
325 var toc_buf = try std.Buffer.initSize(allocator, 0);326 var toc_buf = try std.Buffer.initSize(allocator, 0);
326 defer toc_buf.deinit();327 defer toc_buf.deinit();
...@@ -361,7 +362,23 @@ fn genToc(allocator: *mem.Allocator, tokenizer: *Tokenizer) !Toc {...@@ -361,7 +362,23 @@ fn genToc(allocator: *mem.Allocator, tokenizer: *Tokenizer) !Toc {
361 _ = try eatToken(tokenizer, Token.Id.Separator);362 _ = try eatToken(tokenizer, Token.Id.Separator);
362 const content_token = try eatToken(tokenizer, Token.Id.TagContent);363 const content_token = try eatToken(tokenizer, Token.Id.TagContent);
363 const content = tokenizer.buffer[content_token.start..content_token.end];364 const content = tokenizer.buffer[content_token.start..content_token.end];
364 _ = try eatToken(tokenizer, Token.Id.BracketClose);365 var columns: ?u8 = null;
366 while (true) {
367 const bracket_tok = tokenizer.next();
368 switch (bracket_tok.id) {
369 .BracketClose => break,
370 .Separator => continue,
371 .TagContent => {
372 const param = tokenizer.buffer[bracket_tok.start..bracket_tok.end];
373 if (mem.eql(u8, param, "3col")) {
374 columns = 3;
375 } else {
376 return parseError(tokenizer, bracket_tok, "unrecognized header_open param: {}", param);
377 }
378 },
379 else => return parseError(tokenizer, bracket_tok, "invalid header_open token"),
380 }
381 }
365382
366 header_stack_size += 1;383 header_stack_size += 1;
367384
...@@ -381,10 +398,15 @@ fn genToc(allocator: *mem.Allocator, tokenizer: *Tokenizer) !Toc {...@@ -381,10 +398,15 @@ fn genToc(allocator: *mem.Allocator, tokenizer: *Tokenizer) !Toc {
381 if (last_action == Action.Open) {398 if (last_action == Action.Open) {
382 try toc.writeByte('\n');399 try toc.writeByte('\n');
383 try toc.writeByteNTimes(' ', header_stack_size * 4);400 try toc.writeByteNTimes(' ', header_stack_size * 4);
384 try toc.write("<ul>\n");401 if (last_columns) |n| {
402 try toc.print("<ul style=\"columns: {}\">\n", n);
403 } else {
404 try toc.write("<ul>\n");
405 }
385 } else {406 } else {
386 last_action = Action.Open;407 last_action = Action.Open;
387 }408 }
409 last_columns = columns;
388 try toc.writeByteNTimes(' ', 4 + header_stack_size * 4);410 try toc.writeByteNTimes(' ', 4 + header_stack_size * 4);
389 try toc.print("<li><a id=\"toc-{}\" href=\"#{}\">{}</a>", urlized, urlized, content);411 try toc.print("<li><a id=\"toc-{}\" href=\"#{}\">{}</a>", urlized, urlized, content);
390 } else if (mem.eql(u8, tag_name, "header_close")) {412 } else if (mem.eql(u8, tag_name, "header_close")) {
doc/langref.html.in+55-1
...@@ -6323,7 +6323,7 @@ fn readFile(allocator: *Allocator, filename: []const u8) ![]u8 {...@@ -6323,7 +6323,7 @@ fn readFile(allocator: *Allocator, filename: []const u8) ![]u8 {
6323 {#header_close#}6323 {#header_close#}
63246324
6325 {#header_close#}6325 {#header_close#}
6326 {#header_open|Builtin Functions#}6326 {#header_open|Builtin Functions|3col#}
6327 <p>6327 <p>
6328 Builtin functions are provided by the compiler and are prefixed with <code>@</code>.6328 Builtin functions are provided by the compiler and are prefixed with <code>@</code>.
6329 The {#syntax#}comptime{#endsyntax#} keyword on a parameter means that the parameter must be known6329 The {#syntax#}comptime{#endsyntax#} keyword on a parameter means that the parameter must be known
...@@ -7232,6 +7232,9 @@ fn add(a: i32, b: i32) i32 { return a + b; }...@@ -7232,6 +7232,9 @@ fn add(a: i32, b: i32) i32 { return a + b; }
7232 This function returns an integer type with the given signness and bit count. The maximum7232 This function returns an integer type with the given signness and bit count. The maximum
7233 bit count for an integer type is {#syntax#}65535{#endsyntax#}.7233 bit count for an integer type is {#syntax#}65535{#endsyntax#}.
7234 </p>7234 </p>
7235 <p>
7236 Deprecated. Use {#link|@Type#}.
7237 </p>
7235 {#header_close#}7238 {#header_close#}
72367239
7237 {#header_open|@memberCount#}7240 {#header_open|@memberCount#}
...@@ -7871,6 +7874,57 @@ test "integer truncation" {...@@ -7871,6 +7874,57 @@ test "integer truncation" {
7871 </p>7874 </p>
7872 {#header_close#}7875 {#header_close#}
78737876
7877 {#header_open|@Type#}
7878 <pre>{#syntax#}@Type(comptime info: @import("builtin").TypeInfo) type{#endsyntax#}</pre>
7879 <p>
7880 This function is the inverse of {#link|@typeInfo#}. It reifies type information
7881 into a {#syntax#}type{#endsyntax#}.
7882 </p>
7883 <p>
7884 It is available for the following types:
7885 </p>
7886 <ul>
7887 <li>{#syntax#}type{#endsyntax#}</li>
7888 <li>{#syntax#}noreturn{#endsyntax#}</li>
7889 <li>{#syntax#}void{#endsyntax#}</li>
7890 <li>{#syntax#}bool{#endsyntax#}</li>
7891 <li>{#link|Integers#}</li> - The maximum bit count for an integer type is {#syntax#}65535{#endsyntax#}.
7892 <li>{#link|Floats#}</li>
7893 <li>{#link|Pointers#}</li>
7894 <li>{#syntax#}comptime_int{#endsyntax#}</li>
7895 <li>{#syntax#}comptime_float{#endsyntax#}</li>
7896 <li>{#syntax#}@typeOf(undefined){#endsyntax#}</li>
7897 <li>{#syntax#}@typeOf(null){#endsyntax#}</li>
7898 </ul>
7899 <p>
7900 For these types it is a
7901 <a href="https://github.com/ziglang/zig/issues/2907">TODO in the compiler to implement</a>:
7902 </p>
7903 <ul>
7904 <li>Array</li>
7905 <li>Optional</li>
7906 <li>ErrorUnion</li>
7907 <li>ErrorSet</li>
7908 <li>Enum</li>
7909 <li>Opaque</li>
7910 <li>FnFrame</li>
7911 <li>AnyFrame</li>
7912 <li>Vector</li>
7913 <li>EnumLiteral</li>
7914 </ul>
7915 <p>
7916 For these types, {#syntax#}@Type{#endsyntax#} is not available.
7917 <a href="https://github.com/ziglang/zig/issues/383">There is an open proposal to allow unions and structs</a>.
7918 </p>
7919 <ul>
7920 <li>{#link|union#}</li>
7921 <li>{#link|Functions#}</li>
7922 <li>BoundFn</li>
7923 <li>ArgTuple</li>
7924 <li>{#link|struct#}</li>
7925 </ul>
7926 {#header_close#}
7927
7874 {#header_open|@typeId#}7928 {#header_open|@typeId#}
7875 <pre>{#syntax#}@typeId(comptime T: type) @import("builtin").TypeId{#endsyntax#}</pre>7929 <pre>{#syntax#}@typeId(comptime T: type) @import("builtin").TypeId{#endsyntax#}</pre>
7876 <p>7930 <p>
src/all_types.hpp+8
...@@ -54,6 +54,14 @@ enum PtrLen {...@@ -54,6 +54,14 @@ enum PtrLen {
54 PtrLenC,54 PtrLenC,
55};55};
5656
57// This one corresponds to the builtin.zig enum.
58enum BuiltinPtrSize {
59 BuiltinPtrSizeOne,
60 BuiltinPtrSizeMany,
61 BuiltinPtrSizeSlice,
62 BuiltinPtrSizeC,
63};
64
57enum UndefAllowed {65enum UndefAllowed {
58 UndefOk,66 UndefOk,
59 UndefBad,67 UndefBad,
src/codegen.cpp+19-14
...@@ -8161,20 +8161,25 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {...@@ -8161,20 +8161,25 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
8161 " };\n"8161 " };\n"
8162 " };\n"8162 " };\n"
8163 "};\n\n");8163 "};\n\n");
8164 assert(ContainerLayoutAuto == 0);8164 static_assert(ContainerLayoutAuto == 0, "");
8165 assert(ContainerLayoutExtern == 1);8165 static_assert(ContainerLayoutExtern == 1, "");
8166 assert(ContainerLayoutPacked == 2);8166 static_assert(ContainerLayoutPacked == 2, "");
81678167
8168 assert(CallingConventionUnspecified == 0);8168 static_assert(CallingConventionUnspecified == 0, "");
8169 assert(CallingConventionC == 1);8169 static_assert(CallingConventionC == 1, "");
8170 assert(CallingConventionCold == 2);8170 static_assert(CallingConventionCold == 2, "");
8171 assert(CallingConventionNaked == 3);8171 static_assert(CallingConventionNaked == 3, "");
8172 assert(CallingConventionStdcall == 4);8172 static_assert(CallingConventionStdcall == 4, "");
8173 assert(CallingConventionAsync == 5);8173 static_assert(CallingConventionAsync == 5, "");
81748174
8175 assert(FnInlineAuto == 0);8175 static_assert(FnInlineAuto == 0, "");
8176 assert(FnInlineAlways == 1);8176 static_assert(FnInlineAlways == 1, "");
8177 assert(FnInlineNever == 2);8177 static_assert(FnInlineNever == 2, "");
8178
8179 static_assert(BuiltinPtrSizeOne == 0, "");
8180 static_assert(BuiltinPtrSizeMany == 1, "");
8181 static_assert(BuiltinPtrSizeSlice == 2, "");
8182 static_assert(BuiltinPtrSizeC == 3, "");
8178 }8183 }
8179 {8184 {
8180 buf_appendf(contents,8185 buf_appendf(contents,
src/ir.cpp+17-21
...@@ -20115,25 +20115,26 @@ static Error ir_make_type_info_decls(IrAnalyze *ira, IrInstruction *source_instr...@@ -20115,25 +20115,26 @@ static Error ir_make_type_info_decls(IrAnalyze *ira, IrInstruction *source_instr
20115 return ErrorNone;20115 return ErrorNone;
20116}20116}
2011720117
20118static uint32_t ptr_len_to_size_enum_index(PtrLen ptr_len) {20118static BuiltinPtrSize ptr_len_to_size_enum_index(PtrLen ptr_len) {
20119 switch (ptr_len) {20119 switch (ptr_len) {
20120 case PtrLenSingle:20120 case PtrLenSingle:
20121 return 0;20121 return BuiltinPtrSizeOne;
20122 case PtrLenUnknown:20122 case PtrLenUnknown:
20123 return 1;20123 return BuiltinPtrSizeMany;
20124 case PtrLenC:20124 case PtrLenC:
20125 return 3;20125 return BuiltinPtrSizeC;
20126 }20126 }
20127 zig_unreachable();20127 zig_unreachable();
20128}20128}
2012920129
20130static PtrLen size_enum_index_to_ptr_len(uint32_t size_enum_index) {20130static PtrLen size_enum_index_to_ptr_len(BuiltinPtrSize size_enum_index) {
20131 switch (size_enum_index) {20131 switch (size_enum_index) {
20132 case 0:20132 case BuiltinPtrSizeOne:
20133 return PtrLenSingle;20133 return PtrLenSingle;
20134 case 1:20134 case BuiltinPtrSizeMany:
20135 case BuiltinPtrSizeSlice:
20135 return PtrLenUnknown;20136 return PtrLenUnknown;
20136 case 3:20137 case BuiltinPtrSizeC:
20137 return PtrLenC;20138 return PtrLenC;
20138 }20139 }
20139 zig_unreachable();20140 zig_unreachable();
...@@ -20142,10 +20143,10 @@ static PtrLen size_enum_index_to_ptr_len(uint32_t size_enum_index) {...@@ -20142,10 +20143,10 @@ static PtrLen size_enum_index_to_ptr_len(uint32_t size_enum_index) {
20142static ConstExprValue *create_ptr_like_type_info(IrAnalyze *ira, ZigType *ptr_type_entry) {20143static ConstExprValue *create_ptr_like_type_info(IrAnalyze *ira, ZigType *ptr_type_entry) {
20143 Error err;20144 Error err;
20144 ZigType *attrs_type;20145 ZigType *attrs_type;
20145 uint32_t size_enum_index;20146 BuiltinPtrSize size_enum_index;
20146 if (is_slice(ptr_type_entry)) {20147 if (is_slice(ptr_type_entry)) {
20147 attrs_type = ptr_type_entry->data.structure.fields[slice_ptr_index].type_entry;20148 attrs_type = ptr_type_entry->data.structure.fields[slice_ptr_index].type_entry;
20148 size_enum_index = 2;20149 size_enum_index = BuiltinPtrSizeSlice;
20149 } else if (ptr_type_entry->id == ZigTypeIdPointer) {20150 } else if (ptr_type_entry->id == ZigTypeIdPointer) {
20150 attrs_type = ptr_type_entry;20151 attrs_type = ptr_type_entry;
20151 size_enum_index = ptr_len_to_size_enum_index(ptr_type_entry->data.pointer.ptr_len);20152 size_enum_index = ptr_len_to_size_enum_index(ptr_type_entry->data.pointer.ptr_len);
...@@ -20892,21 +20893,16 @@ static ZigType *type_info_to_type(IrAnalyze *ira, IrInstruction *instruction, Zi...@@ -20892,21 +20893,16 @@ static ZigType *type_info_to_type(IrAnalyze *ira, IrInstruction *instruction, Zi
20892 assert(payload->type == type_info_pointer_type);20893 assert(payload->type == type_info_pointer_type);
20893 ConstExprValue *size_value = get_const_field(ira, payload, "size", 0);20894 ConstExprValue *size_value = get_const_field(ira, payload, "size", 0);
20894 assert(size_value->type == ir_type_info_get_type(ira, "Size", type_info_pointer_type));20895 assert(size_value->type == ir_type_info_get_type(ira, "Size", type_info_pointer_type));
20895 uint32_t size_enum_index = bigint_as_u32(&size_value->data.x_enum_tag);20896 BuiltinPtrSize size_enum_index = (BuiltinPtrSize)bigint_as_u32(&size_value->data.x_enum_tag);
20896 PtrLen ptr_len;20897 PtrLen ptr_len = size_enum_index_to_ptr_len(size_enum_index);
20897 if (size_enum_index == 2) {
20898 ptr_len = PtrLenUnknown; // TODO: is this right?
20899 } else {
20900 ptr_len = size_enum_index_to_ptr_len(size_enum_index);
20901 }
20902 ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen,20898 ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen,
20903 get_const_field_meta_type(ira, payload, "child", 4),20899 get_const_field_meta_type(ira, payload, "child", 4),
20904 get_const_field_bool(ira, payload, "is_const", 1),20900 get_const_field_bool(ira, payload, "is_const", 1),
20905 get_const_field_bool(ira, payload, "is_volatile", 2),20901 get_const_field_bool(ira, payload, "is_volatile", 2),
20906 ptr_len,20902 ptr_len,
20907 bigint_as_u32(get_const_field_lit_int(ira, payload, "alignment", 3)),20903 bigint_as_u32(get_const_field_lit_int(ira, payload, "alignment", 3)),
20908 0, // bit_offset_in_host???20904 0, // bit_offset_in_host
20909 0, // host_int_bytes???20905 0, // host_int_bytes
20910 get_const_field_bool(ira, payload, "is_allowzero", 5)20906 get_const_field_bool(ira, payload, "is_allowzero", 5)
20911 );20907 );
20912 if (size_enum_index != 2)20908 if (size_enum_index != 2)
...@@ -20932,7 +20928,7 @@ static ZigType *type_info_to_type(IrAnalyze *ira, IrInstruction *instruction, Zi...@@ -20932,7 +20928,7 @@ static ZigType *type_info_to_type(IrAnalyze *ira, IrInstruction *instruction, Zi
20932 case ZigTypeIdVector:20928 case ZigTypeIdVector:
20933 case ZigTypeIdEnumLiteral:20929 case ZigTypeIdEnumLiteral:
20934 ir_add_error(ira, instruction, buf_sprintf(20930 ir_add_error(ira, instruction, buf_sprintf(
20935 "TODO implement @Type forr 'TypeInfo.%s': see https://github.com/ziglang/zig/issues/2907\n", type_id_name(tagTypeId)));20931 "TODO implement @Type for 'TypeInfo.%s': see https://github.com/ziglang/zig/issues/2907", type_id_name(tagTypeId)));
20936 return nullptr;20932 return nullptr;
20937 case ZigTypeIdUnion:20933 case ZigTypeIdUnion:
20938 case ZigTypeIdFn:20934 case ZigTypeIdFn:
...@@ -20940,7 +20936,7 @@ static ZigType *type_info_to_type(IrAnalyze *ira, IrInstruction *instruction, Zi...@@ -20940,7 +20936,7 @@ static ZigType *type_info_to_type(IrAnalyze *ira, IrInstruction *instruction, Zi
20940 case ZigTypeIdArgTuple:20936 case ZigTypeIdArgTuple:
20941 case ZigTypeIdStruct:20937 case ZigTypeIdStruct:
20942 ir_add_error(ira, instruction, buf_sprintf(20938 ir_add_error(ira, instruction, buf_sprintf(
20943 "@Type not availble for 'TypeInfo.%s'\n", type_id_name(tagTypeId)));20939 "@Type not availble for 'TypeInfo.%s'", type_id_name(tagTypeId)));
20944 return nullptr;20940 return nullptr;
20945 }20941 }
20946 zig_unreachable();20942 zig_unreachable();
test/compile_errors.zig+9-9
...@@ -2,6 +2,15 @@ const tests = @import("tests.zig");...@@ -2,6 +2,15 @@ const tests = @import("tests.zig");
2const builtin = @import("builtin");2const builtin = @import("builtin");
33
4pub fn addCases(cases: *tests.CompileErrorContext) void {4pub fn addCases(cases: *tests.CompileErrorContext) void {
5 cases.add(
6 "attempt to create 17 bit float type",
7 \\const builtin = @import("builtin");
8 \\comptime {
9 \\ _ = @Type(builtin.TypeInfo { .Float = builtin.TypeInfo.Float { .bits = 17 } });
10 \\}
11 ,
12 "tmp.zig:3:32: error: 17-bit float unsupported",
13 );
514
6 cases.add(15 cases.add(
7 "wrong type for @Type",16 "wrong type for @Type",
...@@ -45,15 +54,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -45,15 +54,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
45 "tmp.zig:2:15: error: @Type not availble for 'TypeInfo.Struct'",54 "tmp.zig:2:15: error: @Type not availble for 'TypeInfo.Struct'",
46 );55 );
4756
48 cases.add(
49 "array not implemented for @Type",
50 \\export fn entry() void {
51 \\ _ = @Type(@typeInfo(enum{x}));
52 \\}
53 ,
54 "tmp.zig:2:15: error: TODO implement @Type forr 'TypeInfo.Enum': see https://github.com/ziglang/zig/issues/2907",
55 );
56
57 cases.add(57 cases.add(
58 "wrong type for result ptr to @asyncCall",58 "wrong type for result ptr to @asyncCall",
59 \\export fn entry() void {59 \\export fn entry() void {
test/stage1/behavior/type.zig-4
...@@ -38,8 +38,6 @@ test "Type.Int" {...@@ -38,8 +38,6 @@ test "Type.Int" {
38 testing.expect(u64 == @Type(TypeInfo { .Int = TypeInfo.Int { .is_signed = false, .bits = 64 } }));38 testing.expect(u64 == @Type(TypeInfo { .Int = TypeInfo.Int { .is_signed = false, .bits = 64 } }));
39 testing.expect(i64 == @Type(TypeInfo { .Int = TypeInfo.Int { .is_signed = true, .bits = 64 } }));39 testing.expect(i64 == @Type(TypeInfo { .Int = TypeInfo.Int { .is_signed = true, .bits = 64 } }));
40 testTypes([_]type {u8,u32,i64});40 testTypes([_]type {u8,u32,i64});
41 // TODO: should this work?
42 //testing.expect(u1 == @Type(TypeInfo.Int { .is_signed = false, .bits = 1 } ));
43}41}
4442
45test "Type.Float" {43test "Type.Float" {
...@@ -48,8 +46,6 @@ test "Type.Float" {...@@ -48,8 +46,6 @@ test "Type.Float" {
48 testing.expect(f64 == @Type(TypeInfo { .Float = TypeInfo.Float { .bits = 64 } }));46 testing.expect(f64 == @Type(TypeInfo { .Float = TypeInfo.Float { .bits = 64 } }));
49 testing.expect(f128 == @Type(TypeInfo { .Float = TypeInfo.Float { .bits = 128 } }));47 testing.expect(f128 == @Type(TypeInfo { .Float = TypeInfo.Float { .bits = 128 } }));
50 testTypes([_]type {f16, f32, f64, f128});48 testTypes([_]type {f16, f32, f64, f128});
51 // error: 17-bit float unsupported
52 //testing.expect(f16 == @Type(TypeInfo { .Float = TypeInfo.Float { .bits = 17 } }));
53}49}
5450
55test "Type.Pointer" {51test "Type.Pointer" {