diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2022-02-19 15:02:50 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2022-02-19 15:11:18 -0700 |
| commit | 746435a9549b1dee6d39e73991592a26cdd582ac (patch) | |
| tree | 09553253738e7b0b46c2e73eda2bb3ea2c1036af /src | |
| parent | b0cdd3d0e691b20043bb7fb763f983b25bfcb2d2 (diff) | |
| download | zig-746435a9549b1dee6d39e73991592a26cdd582ac.tar.gz zig-746435a9549b1dee6d39e73991592a26cdd582ac.zip | |
Sema: implement `@typeInfo` for list literals
Diffstat (limited to 'src')
| -rw-r--r-- | src/Sema.zig | 124 | ||||
| -rw-r--r-- | src/type.zig | 9 |
2 files changed, 88 insertions, 45 deletions
diff --git a/src/Sema.zig b/src/Sema.zig index 38cfb63f27..ed568250fd 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -4192,12 +4192,12 @@ fn analyzeCall( .auto, .always_inline, .compile_time, + .no_async, => {}, .async_kw, .never_tail, .never_inline, - .no_async, .always_tail, => return sema.fail(block, call_src, "TODO implement call with modifier {}", .{ modifier, @@ -10035,51 +10035,93 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai var buffer: Value.ToTypeBuffer = undefined; break :t try struct_field_ty_decl.val.toType(&buffer).copy(fields_anon_decl.arena()); }; - const struct_ty = try sema.resolveTypeFields(block, src, ty); - const struct_fields = struct_ty.structFields(); - const struct_field_vals = try fields_anon_decl.arena().alloc(Value, struct_fields.count()); const layout = struct_ty.containerLayout(); - for (struct_field_vals) |*field_val, i| { - const field = struct_fields.values()[i]; - const name = struct_fields.keys()[i]; - const name_val = v: { - var anon_decl = try block.startAnonDecl(src); - defer anon_decl.deinit(); - const bytes = try anon_decl.arena().dupeZ(u8, name); - const new_decl = try anon_decl.finish( - try Type.Tag.array_u8_sentinel_0.create(anon_decl.arena(), bytes.len), - try Value.Tag.bytes.create(anon_decl.arena(), bytes[0 .. bytes.len + 1]), - ); - break :v try Value.Tag.decl_ref.create(fields_anon_decl.arena(), new_decl); - }; + const struct_field_vals = fv: { + if (struct_ty.castTag(.tuple)) |payload| { + const field_types = payload.data.types; + const struct_field_vals = try fields_anon_decl.arena().alloc(Value, field_types.len); + for (struct_field_vals) |*struct_field_val, i| { + const field_ty = field_types[i]; + const name_val = v: { + var anon_decl = try block.startAnonDecl(src); + defer anon_decl.deinit(); + const bytes = try std.fmt.allocPrintZ(anon_decl.arena(), "{d}", .{i}); + const new_decl = try anon_decl.finish( + try Type.Tag.array_u8_sentinel_0.create(anon_decl.arena(), bytes.len), + try Value.Tag.bytes.create(anon_decl.arena(), bytes[0 .. bytes.len + 1]), + ); + break :v try Value.Tag.decl_ref.create(fields_anon_decl.arena(), new_decl); + }; - const struct_field_fields = try fields_anon_decl.arena().create([5]Value); - const opt_default_val = if (field.default_val.tag() == .unreachable_value) - null - else - field.default_val; - const default_val_ptr = try sema.optRefValue(block, src, field.ty, opt_default_val); - const alignment = switch (layout) { - .Auto, .Extern => field.normalAlignment(target), - .Packed => field.packedAlignment(), - }; + const struct_field_fields = try fields_anon_decl.arena().create([5]Value); + const field_val = payload.data.values[i]; + const is_comptime = field_val.tag() != .unreachable_value; + const opt_default_val = if (is_comptime) field_val else null; + const default_val_ptr = try sema.optRefValue(block, src, field_ty, opt_default_val); + const alignment = field_ty.abiAlignment(target); + + struct_field_fields.* = .{ + // name: []const u8, + name_val, + // field_type: type, + try Value.Tag.ty.create(fields_anon_decl.arena(), field_ty), + // default_value: ?*const anyopaque, + try default_val_ptr.copy(fields_anon_decl.arena()), + // is_comptime: bool, + Value.makeBool(is_comptime), + // alignment: comptime_int, + try Value.Tag.int_u64.create(fields_anon_decl.arena(), alignment), + }; + struct_field_val.* = try Value.Tag.@"struct".create(fields_anon_decl.arena(), struct_field_fields); + } + break :fv struct_field_vals; + } + const struct_fields = struct_ty.structFields(); + const struct_field_vals = try fields_anon_decl.arena().alloc(Value, struct_fields.count()); + + for (struct_field_vals) |*field_val, i| { + const field = struct_fields.values()[i]; + const name = struct_fields.keys()[i]; + const name_val = v: { + var anon_decl = try block.startAnonDecl(src); + defer anon_decl.deinit(); + const bytes = try anon_decl.arena().dupeZ(u8, name); + const new_decl = try anon_decl.finish( + try Type.Tag.array_u8_sentinel_0.create(anon_decl.arena(), bytes.len), + try Value.Tag.bytes.create(anon_decl.arena(), bytes[0 .. bytes.len + 1]), + ); + break :v try Value.Tag.decl_ref.create(fields_anon_decl.arena(), new_decl); + }; - struct_field_fields.* = .{ - // name: []const u8, - name_val, - // field_type: type, - try Value.Tag.ty.create(fields_anon_decl.arena(), field.ty), - // default_value: ?*const anyopaque, - try default_val_ptr.copy(fields_anon_decl.arena()), - // is_comptime: bool, - Value.makeBool(field.is_comptime), - // alignment: comptime_int, - try Value.Tag.int_u64.create(fields_anon_decl.arena(), alignment), - }; - field_val.* = try Value.Tag.@"struct".create(fields_anon_decl.arena(), struct_field_fields); - } + const struct_field_fields = try fields_anon_decl.arena().create([5]Value); + const opt_default_val = if (field.default_val.tag() == .unreachable_value) + null + else + field.default_val; + const default_val_ptr = try sema.optRefValue(block, src, field.ty, opt_default_val); + const alignment = switch (layout) { + .Auto, .Extern => field.normalAlignment(target), + .Packed => field.packedAlignment(), + }; + + struct_field_fields.* = .{ + // name: []const u8, + name_val, + // field_type: type, + try Value.Tag.ty.create(fields_anon_decl.arena(), field.ty), + // default_value: ?*const anyopaque, + try default_val_ptr.copy(fields_anon_decl.arena()), + // is_comptime: bool, + Value.makeBool(field.is_comptime), + // alignment: comptime_int, + try Value.Tag.int_u64.create(fields_anon_decl.arena(), alignment), + }; + field_val.* = try Value.Tag.@"struct".create(fields_anon_decl.arena(), struct_field_fields); + } + break :fv struct_field_vals; + }; const fields_val = v: { const new_decl = try fields_anon_decl.finish( diff --git a/src/type.zig b/src/type.zig index 27fdb0abc8..d8463a6ba8 100644 --- a/src/type.zig +++ b/src/type.zig @@ -2031,21 +2031,21 @@ pub const Type = extern union { .empty_struct, .void, .anyopaque, - => return 0, - .empty_struct_literal, .type, .comptime_int, .comptime_float, - .noreturn, .@"null", .@"undefined", .enum_literal, + .type_info, + => return 0, + + .noreturn, .inferred_alloc_const, .inferred_alloc_mut, .@"opaque", .var_args_param, - .type_info, .bound_fn, => unreachable, @@ -4782,6 +4782,7 @@ pub const Type = extern union { base: Payload = .{ .tag = .tuple }, data: struct { types: []Type, + /// unreachable_value elements are used to indicate runtime-known. values: []Value, }, }; |
