diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2022-03-18 00:12:22 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2022-03-18 00:12:22 -0700 |
| commit | f3f5a5d05b7056aceb408b701613242d053019ab (patch) | |
| tree | acb912950d734b0c25b38c1ae82a8558d1313057 /src/type.zig | |
| parent | 69d78bdae4a5d0ec5877add5936ae8e9daf09140 (diff) | |
| download | zig-f3f5a5d05b7056aceb408b701613242d053019ab.tar.gz zig-f3f5a5d05b7056aceb408b701613242d053019ab.zip | |
stage2: improve `@typeName`
* make it always return a fully qualified name. stage1 is inconsistent
about this.
* AstGen: fix anon_name_strategy to correctly be `func` when anon type
creation happens in the operand of the return expression.
* Sema: implement type names for the "function" naming strategy.
* Put "enum", "union", "opaque", or "struct" in place of "anon" when
creating respective anonymous Decl names.
* std.testing: add `expectStringStartsWith`. Didn't end up using it
after all.
Also this enables the real test runner for stage2 LLVM backend (sans
wasm32) since it works now.
Diffstat (limited to 'src/type.zig')
| -rw-r--r-- | src/type.zig | 126 |
1 files changed, 102 insertions, 24 deletions
diff --git a/src/type.zig b/src/type.zig index b3edc87585..139f126d3b 100644 --- a/src/type.zig +++ b/src/type.zig @@ -1793,7 +1793,7 @@ pub const Type = extern union { }, .error_set_inferred => { const func = ty.castTag(.error_set_inferred).?.data.func; - return writer.print("(inferred error set of {s})", .{func.owner_decl.name}); + return writer.print("@typeInfo(@typeInfo(@TypeOf({s})).Fn.return_type.?).ErrorUnion.error_set", .{func.owner_decl.name}); }, .error_set_merged => { const names = ty.castTag(.error_set_merged).?.data.keys(); @@ -1836,6 +1836,21 @@ pub const Type = extern union { .inferred_alloc_const => unreachable, .inferred_alloc_mut => unreachable, .generic_poison => unreachable, + .var_args_param => unreachable, + .bound_fn => unreachable, + + // TODO get rid of these Type.Tag values. + .atomic_order => unreachable, + .atomic_rmw_op => unreachable, + .calling_convention => unreachable, + .address_space => unreachable, + .float_mode => unreachable, + .reduce_op => unreachable, + .call_options => unreachable, + .prefetch_options => unreachable, + .export_options => unreachable, + .extern_options => unreachable, + .type_info => unreachable, .u1, .u8, @@ -1873,39 +1888,44 @@ pub const Type = extern union { .comptime_int, .comptime_float, .noreturn, - .var_args_param, - .bound_fn, => return maybeDupe(@tagName(t), ally, is_arena), - .enum_literal => return maybeDupe("@Type(.EnumLiteral)", ally, is_arena), - .@"null" => return maybeDupe("@Type(.Null)", ally, is_arena), - .@"undefined" => return maybeDupe("@Type(.Undefined)", ally, is_arena), + .enum_literal => return maybeDupe("@TypeOf(.enum_literal)", ally, is_arena), + .@"null" => return maybeDupe("@TypeOf(null)", ally, is_arena), + .@"undefined" => return maybeDupe("@TypeOf(undefined)", ally, is_arena), + .empty_struct_literal => return maybeDupe("@TypeOf(.{})", ally, is_arena), - .empty_struct, .empty_struct_literal => return maybeDupe("struct {}", ally, is_arena), + .empty_struct => { + const namespace = ty.castTag(.empty_struct).?.data; + var buffer = std.ArrayList(u8).init(ally); + defer buffer.deinit(); + try namespace.renderFullyQualifiedName("", buffer.writer()); + return buffer.toOwnedSliceSentinel(0); + }, .@"struct" => { const struct_obj = ty.castTag(.@"struct").?.data; - return try ally.dupeZ(u8, std.mem.sliceTo(struct_obj.owner_decl.name, 0)); + return try struct_obj.owner_decl.getFullyQualifiedName(ally); }, .@"union", .union_tagged => { const union_obj = ty.cast(Payload.Union).?.data; - return try ally.dupeZ(u8, std.mem.sliceTo(union_obj.owner_decl.name, 0)); + return try union_obj.owner_decl.getFullyQualifiedName(ally); }, .enum_full, .enum_nonexhaustive => { const enum_full = ty.cast(Payload.EnumFull).?.data; - return try ally.dupeZ(u8, std.mem.sliceTo(enum_full.owner_decl.name, 0)); + return try enum_full.owner_decl.getFullyQualifiedName(ally); }, .enum_simple => { const enum_simple = ty.castTag(.enum_simple).?.data; - return try ally.dupeZ(u8, std.mem.sliceTo(enum_simple.owner_decl.name, 0)); + return try enum_simple.owner_decl.getFullyQualifiedName(ally); }, .enum_numbered => { const enum_numbered = ty.castTag(.enum_numbered).?.data; - return try ally.dupeZ(u8, std.mem.sliceTo(enum_numbered.owner_decl.name, 0)); + return try enum_numbered.owner_decl.getFullyQualifiedName(ally); }, .@"opaque" => { const opaque_obj = ty.cast(Payload.Opaque).?.data; - return try ally.dupeZ(u8, std.mem.sliceTo(opaque_obj.owner_decl.name, 0)); + return try opaque_obj.owner_decl.getFullyQualifiedName(ally); }, .anyerror_void_error_union => return maybeDupe("anyerror!void", ally, is_arena), @@ -1919,21 +1939,79 @@ pub const Type = extern union { .manyptr_u8 => return maybeDupe("[*]u8", ally, is_arena), .manyptr_const_u8 => return maybeDupe("[*]const u8", ally, is_arena), .manyptr_const_u8_sentinel_0 => return maybeDupe("[*:0]const u8", ally, is_arena), - .atomic_order => return maybeDupe("AtomicOrder", ally, is_arena), - .atomic_rmw_op => return maybeDupe("AtomicRmwOp", ally, is_arena), - .calling_convention => return maybeDupe("CallingConvention", ally, is_arena), - .address_space => return maybeDupe("AddressSpace", ally, is_arena), - .float_mode => return maybeDupe("FloatMode", ally, is_arena), - .reduce_op => return maybeDupe("ReduceOp", ally, is_arena), - .call_options => return maybeDupe("CallOptions", ally, is_arena), - .prefetch_options => return maybeDupe("PrefetchOptions", ally, is_arena), - .export_options => return maybeDupe("ExportOptions", ally, is_arena), - .extern_options => return maybeDupe("ExternOptions", ally, is_arena), - .type_info => return maybeDupe("Type", ally, is_arena), + + .error_set_inferred => { + const func = ty.castTag(.error_set_inferred).?.data.func; + + var buf = std.ArrayList(u8).init(ally); + defer buf.deinit(); + try buf.appendSlice("@typeInfo(@typeInfo(@TypeOf("); + try func.owner_decl.renderFullyQualifiedName(buf.writer()); + try buf.appendSlice(")).Fn.return_type.?).ErrorUnion.error_set"); + return try buf.toOwnedSliceSentinel(0); + }, + + .function => { + const fn_info = ty.fnInfo(); + var buf = std.ArrayList(u8).init(ally); + defer buf.deinit(); + try buf.appendSlice("fn("); + for (fn_info.param_types) |param_type, i| { + if (i != 0) try buf.appendSlice(", "); + const param_name = try param_type.nameAllocAdvanced(ally, is_arena); + defer if (!is_arena) ally.free(param_name); + try buf.appendSlice(param_name); + } + if (fn_info.is_var_args) { + if (fn_info.param_types.len != 0) { + try buf.appendSlice(", "); + } + try buf.appendSlice("..."); + } + try buf.appendSlice(") "); + if (fn_info.cc != .Unspecified) { + try buf.appendSlice("callconv(."); + try buf.appendSlice(@tagName(fn_info.cc)); + try buf.appendSlice(") "); + } + if (fn_info.alignment != 0) { + try buf.writer().print("align({d}) ", .{fn_info.alignment}); + } + { + const ret_ty_name = try fn_info.return_type.nameAllocAdvanced(ally, is_arena); + defer if (!is_arena) ally.free(ret_ty_name); + try buf.appendSlice(ret_ty_name); + } + return try buf.toOwnedSliceSentinel(0); + }, + + .error_union => { + const error_union = ty.castTag(.error_union).?.data; + + var buf = std.ArrayList(u8).init(ally); + defer buf.deinit(); + + { + const err_set_ty_name = try error_union.error_set.nameAllocAdvanced(ally, is_arena); + defer if (!is_arena) ally.free(err_set_ty_name); + try buf.appendSlice(err_set_ty_name); + } + + try buf.appendSlice("!"); + + { + const payload_ty_name = try error_union.payload.nameAllocAdvanced(ally, is_arena); + defer if (!is_arena) ally.free(payload_ty_name); + try buf.appendSlice(payload_ty_name); + } + + return try buf.toOwnedSliceSentinel(0); + }, else => { // TODO this is wasteful and also an incorrect implementation of `@typeName` var buf = std.ArrayList(u8).init(ally); + defer buf.deinit(); try buf.writer().print("{}", .{ty}); return try buf.toOwnedSliceSentinel(0); }, |
