From febc7d3cd63eefe91c7aaa95e3a274a0b44e353e Mon Sep 17 00:00:00 2001 From: Veikka Tuominen Date: Tue, 31 May 2022 16:21:36 +0300 Subject: [PATCH 1/4] Sema: take `dbg_stmt` into account in `zirResolveInferredAlloc` --- src/Sema.zig | 2 +- test/behavior/basic.zig | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/Sema.zig b/src/Sema.zig index 505810a158..ed8391a44d 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -2976,7 +2976,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com // Even though we reuse the constant instruction, we still remove it from the // block so that codegen does not see it. - block.instructions.shrinkRetainingCapacity(block.instructions.items.len - 3); + block.instructions.shrinkRetainingCapacity(search_index); sema.air_values.items[value_index] = try Value.Tag.decl_ref.create(sema.arena, new_decl_index); // if bitcast ty ref needs to be made const, make_ptr_const // ZIR handles it later, so we can just use the ty ref here. diff --git a/test/behavior/basic.zig b/test/behavior/basic.zig index e887a1d4b6..8bc1ad5cf2 100644 --- a/test/behavior/basic.zig +++ b/test/behavior/basic.zig @@ -977,3 +977,13 @@ test "weird array and tuple initializations" { .b = if (a) .{ .e = .a } else .{ .e = .b }, }; } + +test "array type comes from generic function" { + const S = struct { + fn A() type { + return struct { a: u8 = 0 }; + } + }; + const args = [_]S.A(){.{}}; + _ = args; +} From 36df79cd3779b27a63f449618459603ce549660a Mon Sep 17 00:00:00 2001 From: Veikka Tuominen Date: Tue, 31 May 2022 16:43:58 +0300 Subject: [PATCH 2/4] stage2: ignore generic return type when hashing function type Generic parameter types are already ignored. --- src/type.zig | 4 +++- test/behavior/basic.zig | 18 ++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/type.zig b/src/type.zig index ebb8bfd7c3..638145e8b1 100644 --- a/src/type.zig +++ b/src/type.zig @@ -1036,7 +1036,9 @@ pub const Type = extern union { std.hash.autoHash(hasher, std.builtin.TypeId.Fn); const fn_info = ty.fnInfo(); - hashWithHasher(fn_info.return_type, hasher, mod); + if (fn_info.return_type.tag() != .generic_poison) { + hashWithHasher(fn_info.return_type, hasher, mod); + } std.hash.autoHash(hasher, fn_info.alignment); std.hash.autoHash(hasher, fn_info.cc); std.hash.autoHash(hasher, fn_info.is_var_args); diff --git a/test/behavior/basic.zig b/test/behavior/basic.zig index 8bc1ad5cf2..32df664bae 100644 --- a/test/behavior/basic.zig +++ b/test/behavior/basic.zig @@ -987,3 +987,21 @@ test "array type comes from generic function" { const args = [_]S.A(){.{}}; _ = args; } + +test "generic function uses return type of other generic function" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO + + const S = struct { + fn call( + f: anytype, + args: anytype, + ) @TypeOf(@call(.{}, f, @as(@TypeOf(args), undefined))) { + return @call(.{}, f, args); + } + + fn func(arg: anytype) @TypeOf(arg) { + return arg; + } + }; + try std.testing.expect(S.call(S.func, .{@as(u8, 1)}) == 1); +} From 56608cbb3d5577d8931830fa02d3e2920925ceab Mon Sep 17 00:00:00 2001 From: Veikka Tuominen Date: Tue, 31 May 2022 17:14:37 +0300 Subject: [PATCH 3/4] Sema: do not add calls to `returnError` for comptime known non-error values --- src/Sema.zig | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/Sema.zig b/src/Sema.zig index ed8391a44d..d4c49973a1 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -13011,10 +13011,13 @@ fn analyzeRet( const backend_supports_error_return_tracing = sema.mod.comp.bin_file.options.use_llvm; - if ((sema.fn_ret_ty.zigTypeTag() == .ErrorSet or sema.typeOf(uncasted_operand).zigTypeTag() == .ErrorUnion) and + if (sema.fn_ret_ty.isError() and sema.mod.comp.bin_file.options.error_return_tracing and backend_supports_error_return_tracing) - { + ret_err: { + if (try sema.resolveMaybeUndefVal(block, src, operand)) |ret_val| { + if (ret_val.tag() != .@"error") break :ret_err; + } const return_err_fn = try sema.getBuiltin(block, src, "returnError"); const unresolved_stack_trace_ty = try sema.getBuiltinType(block, src, "StackTrace"); const stack_trace_ty = try sema.resolveTypeFields(block, src, unresolved_stack_trace_ty); From 282437c7538e3e70ce06cfee7affe976de28a780 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Tue, 31 May 2022 12:17:48 -0700 Subject: [PATCH 4/4] stage2: fix hash/eql on function types to account for generic callconv and generic alignment. --- src/type.zig | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/type.zig b/src/type.zig index 638145e8b1..9a072fa911 100644 --- a/src/type.zig +++ b/src/type.zig @@ -640,18 +640,18 @@ pub const Type = extern union { if (!eql(a_info.return_type, b_info.return_type, mod)) return false; - if (a_info.cc != b_info.cc) - return false; - - if (a_info.alignment != b_info.alignment) - return false; - if (a_info.is_var_args != b_info.is_var_args) return false; if (a_info.is_generic != b_info.is_generic) return false; + if (!a_info.cc_is_generic and a_info.cc != b_info.cc) + return false; + + if (!a_info.align_is_generic and a_info.alignment != b_info.alignment) + return false; + if (a_info.param_types.len != b_info.param_types.len) return false; @@ -1039,8 +1039,12 @@ pub const Type = extern union { if (fn_info.return_type.tag() != .generic_poison) { hashWithHasher(fn_info.return_type, hasher, mod); } - std.hash.autoHash(hasher, fn_info.alignment); - std.hash.autoHash(hasher, fn_info.cc); + if (!fn_info.align_is_generic) { + std.hash.autoHash(hasher, fn_info.alignment); + } + if (!fn_info.cc_is_generic) { + std.hash.autoHash(hasher, fn_info.cc); + } std.hash.autoHash(hasher, fn_info.is_var_args); std.hash.autoHash(hasher, fn_info.is_generic);