motiejus/zig

fork of https://codeberg.org/ziglang/zig
git clone https://git.jakstys.lt/motiejus/zig.git
Log | Tree | Refs | README | LICENSE

commit b7bd44a654671e76f15ed1a4e1226c0d7cc20d92 (tree)
parent 8b66443d5008be91756c3c5567548ed18766ea11
Author: Jacob Young <jacobly0@users.noreply.github.com>
Date:   Sat,  1 Oct 2022 08:05:06 -0400

Sema: ensure builtin.StackTrace fields are analyzed

When encountering a fn type that returns an error (union), a backend
that supports error return tracing will want the StackTrace struct and
its fields to be analyzed.

Diffstat:
Msrc/Sema.zig | 15+++++++++++----
Msrc/codegen/llvm.zig | 1-
Mtest/standalone/issue_13030/main.zig | 9++++-----
3 files changed, 15 insertions(+), 10 deletions(-)

diff --git a/src/Sema.zig b/src/Sema.zig @@ -8107,6 +8107,13 @@ fn funcCommon( for (comptime_params) |ct| is_generic = is_generic or ct; is_generic = is_generic or ret_ty_requires_comptime; + if (!is_generic and sema.wantErrorReturnTracing(return_type)) { + // Make sure that StackTrace's fields are resolved so that the backend can + // lower this fn type. + const unresolved_stack_trace_ty = try sema.getBuiltinType(block, ret_ty_src, "StackTrace"); + _ = try sema.resolveTypeFields(block, ret_ty_src, unresolved_stack_trace_ty); + } + break :fn_ty try Type.Tag.function.create(sema.arena, .{ .param_types = param_types, .comptime_params = comptime_params.ptr, @@ -15631,7 +15638,7 @@ fn zirRetLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Zir return sema.analyzeRet(block, operand, src); } - if (sema.wantErrorReturnTracing()) { + if (sema.wantErrorReturnTracing(sema.fn_ret_ty)) { const is_non_err = try sema.analyzePtrIsNonErr(block, src, ret_ptr); return retWithErrTracing(sema, block, src, is_non_err, .ret_load, ret_ptr); } @@ -15698,11 +15705,11 @@ fn retWithErrTracing( return always_noreturn; } -fn wantErrorReturnTracing(sema: *Sema) bool { +fn wantErrorReturnTracing(sema: *Sema, fn_ret_ty: Type) bool { // TODO implement this feature in all the backends and then delete this check. const backend_supports_error_return_tracing = sema.mod.comp.bin_file.options.use_llvm; - return sema.fn_ret_ty.isError() and + return fn_ret_ty.isError() and sema.mod.comp.bin_file.options.error_return_tracing and backend_supports_error_return_tracing; } @@ -15754,7 +15761,7 @@ fn analyzeRet( try sema.resolveTypeLayout(block, src, sema.fn_ret_ty); - if (sema.wantErrorReturnTracing()) { + if (sema.wantErrorReturnTracing(sema.fn_ret_ty)) { // Avoid adding a frame to the error return trace in case the value is comptime-known // to be not an error. const is_non_err = try sema.analyzeIsNonErr(block, src, operand); diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig @@ -2335,7 +2335,6 @@ pub const Object = struct { const stack_trace_decl = builtin_namespace.decls .getKeyAdapted(stack_trace_str, Module.DeclAdapter{ .mod = mod }).?; - mod.ensureDeclAnalyzed(stack_trace_decl) catch unreachable; return mod.declPtr(stack_trace_decl).val.toType(undefined); } }; diff --git a/test/standalone/issue_13030/main.zig b/test/standalone/issue_13030/main.zig @@ -1,8 +1,7 @@ -const std = @import("std"); -fn a() error{}!void {} -fn b() std.meta.FnPtr(fn () error{}!void) { - return &a; +fn b(comptime T: type) ?@import("std").meta.FnPtr(fn () error{}!T) { + return null; } + export fn c() void { - _ = b(); + _ = b(void); }