authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2022-10-01 08:05:06-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2022-10-01 08:09:43-04:00
logb7bd44a654671e76f15ed1a4e1226c0d7cc20d92
tree11ca1df0e17e1cae1c63f4c8d6091298d4de22f4
parent8b66443d5008be91756c3c5567548ed18766ea11

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.

3 files changed, 15 insertions(+), 10 deletions(-)

src/Sema.zig+11-4
......@@ -8107,6 +8107,13 @@ fn funcCommon(
81078107 for (comptime_params) |ct| is_generic = is_generic or ct;
81088108 is_generic = is_generic or ret_ty_requires_comptime;
81098109
8110 if (!is_generic and sema.wantErrorReturnTracing(return_type)) {
8111 // Make sure that StackTrace's fields are resolved so that the backend can
8112 // lower this fn type.
8113 const unresolved_stack_trace_ty = try sema.getBuiltinType(block, ret_ty_src, "StackTrace");
8114 _ = try sema.resolveTypeFields(block, ret_ty_src, unresolved_stack_trace_ty);
8115 }
8116
81108117 break :fn_ty try Type.Tag.function.create(sema.arena, .{
81118118 .param_types = param_types,
81128119 .comptime_params = comptime_params.ptr,
......@@ -15631,7 +15638,7 @@ fn zirRetLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Zir
1563115638 return sema.analyzeRet(block, operand, src);
1563215639 }
1563315640
15634 if (sema.wantErrorReturnTracing()) {
15641 if (sema.wantErrorReturnTracing(sema.fn_ret_ty)) {
1563515642 const is_non_err = try sema.analyzePtrIsNonErr(block, src, ret_ptr);
1563615643 return retWithErrTracing(sema, block, src, is_non_err, .ret_load, ret_ptr);
1563715644 }
......@@ -15698,11 +15705,11 @@ fn retWithErrTracing(
1569815705 return always_noreturn;
1569915706}
1570015707
15701fn wantErrorReturnTracing(sema: *Sema) bool {
15708fn wantErrorReturnTracing(sema: *Sema, fn_ret_ty: Type) bool {
1570215709 // TODO implement this feature in all the backends and then delete this check.
1570315710 const backend_supports_error_return_tracing = sema.mod.comp.bin_file.options.use_llvm;
1570415711
15705 return sema.fn_ret_ty.isError() and
15712 return fn_ret_ty.isError() and
1570615713 sema.mod.comp.bin_file.options.error_return_tracing and
1570715714 backend_supports_error_return_tracing;
1570815715}
......@@ -15754,7 +15761,7 @@ fn analyzeRet(
1575415761
1575515762 try sema.resolveTypeLayout(block, src, sema.fn_ret_ty);
1575615763
15757 if (sema.wantErrorReturnTracing()) {
15764 if (sema.wantErrorReturnTracing(sema.fn_ret_ty)) {
1575815765 // Avoid adding a frame to the error return trace in case the value is comptime-known
1575915766 // to be not an error.
1576015767 const is_non_err = try sema.analyzeIsNonErr(block, src, operand);
src/codegen/llvm.zig-1
......@@ -2335,7 +2335,6 @@ pub const Object = struct {
23352335 const stack_trace_decl = builtin_namespace.decls
23362336 .getKeyAdapted(stack_trace_str, Module.DeclAdapter{ .mod = mod }).?;
23372337
2338 mod.ensureDeclAnalyzed(stack_trace_decl) catch unreachable;
23392338 return mod.declPtr(stack_trace_decl).val.toType(undefined);
23402339 }
23412340};
test/standalone/issue_13030/main.zig+4-5
......@@ -1,8 +1,7 @@
1const std = @import("std");
2fn a() error{}!void {}
3fn b() std.meta.FnPtr(fn () error{}!void) {
4 return &a;
1fn b(comptime T: type) ?@import("std").meta.FnPtr(fn () error{}!T) {
2 return null;
53}
4
65export fn c() void {
7 _ = b();
6 _ = b(void);
87}