| author | |
| committer | |
| log | 097766bba3d7f45df41a4233f849db99e1bb8676 |
| tree | 71f8f296c31380be83d99639dbfd4ca71d61bb2b |
| parent | fffbb511db5de611ca670fc13a223ddbe255c92c |
Resolves: #217027 files changed, 103 insertions(+), 1 deletions(-)
doc/langref.html.in+7| ... | ... | @@ -4879,6 +4879,13 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val |
| 4879 | 4879 | </p> |
| 4880 | 4880 | {#header_close#} |
| 4881 | 4881 | |
| 4882 | {#header_open|@FieldType#} | |
| 4883 | <pre>{#syntax#}@FieldType(comptime Type: type, comptime field_name: []const u8) type{#endsyntax#}</pre> | |
| 4884 | <p> | |
| 4885 | Given a type and the name of one of its fields, returns the type of that field. | |
| 4886 | </p> | |
| 4887 | {#header_close#} | |
| 4888 | ||
| 4882 | 4889 | {#header_open|@floatCast#} |
| 4883 | 4890 | <pre>{#syntax#}@floatCast(value: anytype) anytype{#endsyntax#}</pre> |
| 4884 | 4891 | <p> |
lib/std/zig/AstGen.zig+9| ... | ... | @@ -9274,6 +9274,15 @@ fn builtinCall( |
| 9274 | 9274 | }); |
| 9275 | 9275 | return rvalue(gz, ri, result, node); |
| 9276 | 9276 | }, |
| 9277 | .FieldType => { | |
| 9278 | const ty_inst = try typeExpr(gz, scope, params[0]); | |
| 9279 | const name_inst = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = .slice_const_u8_type } }, params[1]); | |
| 9280 | const result = try gz.addPlNode(.field_type_ref, node, Zir.Inst.FieldTypeRef{ | |
| 9281 | .container_type = ty_inst, | |
| 9282 | .field_name = name_inst, | |
| 9283 | }); | |
| 9284 | return rvalue(gz, ri, result, node); | |
| 9285 | }, | |
| 9277 | 9286 | |
| 9278 | 9287 | // zig fmt: off |
| 9279 | 9288 | .as => return as( gz, scope, ri, node, params[0], params[1]), |
lib/std/zig/AstRlAnnotate.zig+6-1| ... | ... | @@ -914,7 +914,6 @@ fn builtinCall(astrl: *AstRlAnnotate, block: ?*Block, ri: ResultInfo, node: Ast. |
| 914 | 914 | .work_item_id, |
| 915 | 915 | .work_group_size, |
| 916 | 916 | .work_group_id, |
| 917 | .field_parent_ptr, | |
| 918 | 917 | => { |
| 919 | 918 | _ = try astrl.expr(args[0], block, ResultInfo.type_only); |
| 920 | 919 | return false; |
| ... | ... | @@ -983,11 +982,17 @@ fn builtinCall(astrl: *AstRlAnnotate, block: ?*Block, ri: ResultInfo, node: Ast. |
| 983 | 982 | .has_decl, |
| 984 | 983 | .has_field, |
| 985 | 984 | .field, |
| 985 | .FieldType, | |
| 986 | 986 | => { |
| 987 | 987 | _ = try astrl.expr(args[0], block, ResultInfo.type_only); |
| 988 | 988 | _ = try astrl.expr(args[1], block, ResultInfo.type_only); |
| 989 | 989 | return false; |
| 990 | 990 | }, |
| 991 | .field_parent_ptr => { | |
| 992 | _ = try astrl.expr(args[0], block, ResultInfo.type_only); | |
| 993 | _ = try astrl.expr(args[1], block, ResultInfo.none); | |
| 994 | return false; | |
| 995 | }, | |
| 991 | 996 | .wasm_memory_grow => { |
| 992 | 997 | _ = try astrl.expr(args[0], block, ResultInfo.type_only); |
| 993 | 998 | _ = try astrl.expr(args[1], block, ResultInfo.type_only); |
lib/std/zig/BuiltinFn.zig+8| ... | ... | @@ -50,6 +50,7 @@ pub const Tag = enum { |
| 50 | 50 | @"extern", |
| 51 | 51 | field, |
| 52 | 52 | field_parent_ptr, |
| 53 | FieldType, | |
| 53 | 54 | float_cast, |
| 54 | 55 | int_from_float, |
| 55 | 56 | frame, |
| ... | ... | @@ -516,6 +517,13 @@ pub const list = list: { |
| 516 | 517 | .param_count = 2, |
| 517 | 518 | }, |
| 518 | 519 | }, |
| 520 | .{ | |
| 521 | "@FieldType", | |
| 522 | .{ | |
| 523 | .tag = .FieldType, | |
| 524 | .param_count = 2, | |
| 525 | }, | |
| 526 | }, | |
| 519 | 527 | .{ |
| 520 | 528 | "@floatCast", |
| 521 | 529 | .{ |
test/behavior/struct.zig+24| ... | ... | @@ -2159,3 +2159,27 @@ test "matching captures causes struct equivalence" { |
| 2159 | 2159 | comptime assert(@TypeOf(a) == @TypeOf(b)); |
| 2160 | 2160 | try expect(a.x == b.x); |
| 2161 | 2161 | } |
| 2162 | ||
| 2163 | test "struct @FieldType" { | |
| 2164 | const S = struct { | |
| 2165 | a: u32, | |
| 2166 | b: f64, | |
| 2167 | c: *@This(), | |
| 2168 | }; | |
| 2169 | ||
| 2170 | comptime assert(@FieldType(S, "a") == u32); | |
| 2171 | comptime assert(@FieldType(S, "b") == f64); | |
| 2172 | comptime assert(@FieldType(S, "c") == *S); | |
| 2173 | } | |
| 2174 | ||
| 2175 | test "extern struct @FieldType" { | |
| 2176 | const S = extern struct { | |
| 2177 | a: u32, | |
| 2178 | b: f64, | |
| 2179 | c: *@This(), | |
| 2180 | }; | |
| 2181 | ||
| 2182 | comptime assert(@FieldType(S, "a") == u32); | |
| 2183 | comptime assert(@FieldType(S, "b") == f64); | |
| 2184 | comptime assert(@FieldType(S, "c") == *S); | |
| 2185 | } |
test/behavior/union.zig+36| ... | ... | @@ -2339,3 +2339,39 @@ test "signed enum tag with negative value" { |
| 2339 | 2339 | |
| 2340 | 2340 | try expect(e.a == i); |
| 2341 | 2341 | } |
| 2342 | ||
| 2343 | test "union @FieldType" { | |
| 2344 | const U = union { | |
| 2345 | a: u32, | |
| 2346 | b: f64, | |
| 2347 | c: *@This(), | |
| 2348 | }; | |
| 2349 | ||
| 2350 | comptime assert(@FieldType(U, "a") == u32); | |
| 2351 | comptime assert(@FieldType(U, "b") == f64); | |
| 2352 | comptime assert(@FieldType(U, "c") == *U); | |
| 2353 | } | |
| 2354 | ||
| 2355 | test "tagged union @FieldType" { | |
| 2356 | const U = union(enum) { | |
| 2357 | a: u32, | |
| 2358 | b: f64, | |
| 2359 | c: *@This(), | |
| 2360 | }; | |
| 2361 | ||
| 2362 | comptime assert(@FieldType(U, "a") == u32); | |
| 2363 | comptime assert(@FieldType(U, "b") == f64); | |
| 2364 | comptime assert(@FieldType(U, "c") == *U); | |
| 2365 | } | |
| 2366 | ||
| 2367 | test "extern union @FieldType" { | |
| 2368 | const U = extern union { | |
| 2369 | a: u32, | |
| 2370 | b: f64, | |
| 2371 | c: *@This(), | |
| 2372 | }; | |
| 2373 | ||
| 2374 | comptime assert(@FieldType(U, "a") == u32); | |
| 2375 | comptime assert(@FieldType(U, "b") == f64); | |
| 2376 | comptime assert(@FieldType(U, "c") == *U); | |
| 2377 | } |
test/cases/compile_errors/invalid_field_type_usage.zig created+13| ... | ... | @@ -0,0 +1,13 @@ |
| 1 | export fn foo() void { | |
| 2 | _ = @FieldType(u8, "a"); | |
| 3 | } | |
| 4 | export fn bar() void { | |
| 5 | const S = struct { a: u8 }; | |
| 6 | _ = @FieldType(S, "b"); | |
| 7 | } | |
| 8 | ||
| 9 | // error | |
| 10 | // | |
| 11 | // :2:20: error: expected struct or union; found 'u8' | |
| 12 | // :6:23: error: no field named 'b' in struct 'tmp.bar.S' | |
| 13 | // :5:15: note: struct declared here |