commit 317cb629fb919938569b9ef8a782e1f9619d6244 (tree)
parent 8d288a5fa77485121c3d3eafeedaaa381884c245
Author: kkHAIKE <kkhaike@gmail.com>
Date: Sun, 25 Sep 2022 21:14:15 +0800
Sema: fix resolveInferredErrorSet panic when generic inline function
Diffstat:
3 files changed, 23 insertions(+), 1 deletion(-)
diff --git a/src/Sema.zig b/src/Sema.zig
@@ -28499,7 +28499,13 @@ fn resolveInferredErrorSet(
// in this case, it may be a generic function which would cause an assertion failure
// if we called `ensureFuncBodyAnalyzed` on it here.
const ies_func_owner_decl = sema.mod.declPtr(ies.func.owner_decl);
- if (ies_func_owner_decl.ty.fnInfo().return_type.errorUnionSet().castTag(.error_set_inferred).?.data == ies) {
+ const ies_func_info = ies_func_owner_decl.ty.fnInfo();
+ // if ies declared by a inline function with generic return type, the return_type should be generic_poison,
+ // because inline function does not create a new declaration, and the ies has been filled with analyzeCall,
+ // so here we can simply skip this case.
+ if (ies_func_info.return_type.tag() == .generic_poison) {
+ assert(ies_func_info.cc == .Inline);
+ } else if (ies_func_info.return_type.errorUnionSet().castTag(.error_set_inferred).?.data == ies) {
// In this case we are dealing with the actual InferredErrorSet object that
// corresponds to the function, not one created to track an inline/comptime call.
try sema.ensureFuncBodyAnalyzed(ies.func);
diff --git a/test/behavior.zig b/test/behavior.zig
@@ -87,6 +87,7 @@ test {
_ = @import("behavior/bugs/12430.zig");
_ = @import("behavior/bugs/12486.zig");
_ = @import("behavior/bugs/12551.zig");
+ _ = @import("behavior/bugs/12644.zig");
_ = @import("behavior/bugs/12680.zig");
_ = @import("behavior/bugs/12776.zig");
_ = @import("behavior/bugs/12786.zig");
diff --git a/test/behavior/bugs/12644.zig b/test/behavior/bugs/12644.zig
@@ -0,0 +1,15 @@
+const std = @import("std");
+
+inline fn foo(comptime T: type) !T {
+ return error.AnError;
+}
+
+fn main0() !void {
+ _ = try foo(u8);
+}
+
+test "issue12644" {
+ main0() catch |e| {
+ try std.testing.expect(e == error.AnError);
+ };
+}