mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-06 13:54:21 +00:00
parent
0a88352689
commit
fd1eade4ca
3 changed files with 40 additions and 35 deletions
|
|
@ -4771,38 +4771,41 @@ static void analyze_fn_ir(CodeGen *g, ZigFn *fn, AstNode *return_type_node) {
|
||||||
if (return_err_set_type->data.error_set.infer_fn != nullptr &&
|
if (return_err_set_type->data.error_set.infer_fn != nullptr &&
|
||||||
return_err_set_type->data.error_set.incomplete)
|
return_err_set_type->data.error_set.incomplete)
|
||||||
{
|
{
|
||||||
ZigType *inferred_err_set_type;
|
// The inferred error set type is null if the function doesn't
|
||||||
|
// return any error
|
||||||
|
ZigType *inferred_err_set_type = nullptr;
|
||||||
|
|
||||||
if (fn->src_implicit_return_type->id == ZigTypeIdErrorSet) {
|
if (fn->src_implicit_return_type->id == ZigTypeIdErrorSet) {
|
||||||
inferred_err_set_type = fn->src_implicit_return_type;
|
inferred_err_set_type = fn->src_implicit_return_type;
|
||||||
} else if (fn->src_implicit_return_type->id == ZigTypeIdErrorUnion) {
|
} else if (fn->src_implicit_return_type->id == ZigTypeIdErrorUnion) {
|
||||||
inferred_err_set_type = fn->src_implicit_return_type->data.error_union.err_set_type;
|
inferred_err_set_type = fn->src_implicit_return_type->data.error_union.err_set_type;
|
||||||
} else {
|
|
||||||
add_node_error(g, return_type_node,
|
|
||||||
buf_sprintf("function with inferred error set must return at least one possible error"));
|
|
||||||
fn->anal_state = FnAnalStateInvalid;
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (inferred_err_set_type->data.error_set.infer_fn != nullptr &&
|
if (inferred_err_set_type != nullptr) {
|
||||||
inferred_err_set_type->data.error_set.incomplete)
|
if (inferred_err_set_type->data.error_set.infer_fn != nullptr &&
|
||||||
{
|
inferred_err_set_type->data.error_set.incomplete)
|
||||||
if (!resolve_inferred_error_set(g, inferred_err_set_type, return_type_node)) {
|
{
|
||||||
fn->anal_state = FnAnalStateInvalid;
|
if (!resolve_inferred_error_set(g, inferred_err_set_type, return_type_node)) {
|
||||||
return;
|
fn->anal_state = FnAnalStateInvalid;
|
||||||
}
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
return_err_set_type->data.error_set.incomplete = false;
|
|
||||||
if (type_is_global_error_set(inferred_err_set_type)) {
|
|
||||||
return_err_set_type->data.error_set.err_count = UINT32_MAX;
|
|
||||||
} else {
|
|
||||||
return_err_set_type->data.error_set.err_count = inferred_err_set_type->data.error_set.err_count;
|
|
||||||
if (inferred_err_set_type->data.error_set.err_count > 0) {
|
|
||||||
return_err_set_type->data.error_set.errors = heap::c_allocator.allocate<ErrorTableEntry *>(inferred_err_set_type->data.error_set.err_count);
|
|
||||||
for (uint32_t i = 0; i < inferred_err_set_type->data.error_set.err_count; i += 1) {
|
|
||||||
return_err_set_type->data.error_set.errors[i] = inferred_err_set_type->data.error_set.errors[i];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return_err_set_type->data.error_set.incomplete = false;
|
||||||
|
if (type_is_global_error_set(inferred_err_set_type)) {
|
||||||
|
return_err_set_type->data.error_set.err_count = UINT32_MAX;
|
||||||
|
} else {
|
||||||
|
return_err_set_type->data.error_set.err_count = inferred_err_set_type->data.error_set.err_count;
|
||||||
|
if (inferred_err_set_type->data.error_set.err_count > 0) {
|
||||||
|
return_err_set_type->data.error_set.errors = heap::c_allocator.allocate<ErrorTableEntry *>(inferred_err_set_type->data.error_set.err_count);
|
||||||
|
for (uint32_t i = 0; i < inferred_err_set_type->data.error_set.err_count; i += 1) {
|
||||||
|
return_err_set_type->data.error_set.errors[i] = inferred_err_set_type->data.error_set.errors[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return_err_set_type->data.error_set.incomplete = false;
|
||||||
|
return_err_set_type->data.error_set.err_count = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2734,16 +2734,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
|
||||||
"tmp.zig:5:5: error: else prong required when switching on type 'anyerror'",
|
"tmp.zig:5:5: error: else prong required when switching on type 'anyerror'",
|
||||||
});
|
});
|
||||||
|
|
||||||
cases.add("inferred error set with no returned error",
|
|
||||||
\\export fn entry() void {
|
|
||||||
\\ foo() catch unreachable;
|
|
||||||
\\}
|
|
||||||
\\fn foo() !void {
|
|
||||||
\\}
|
|
||||||
, &[_][]const u8{
|
|
||||||
"tmp.zig:4:11: error: function with inferred error set must return at least one possible error",
|
|
||||||
});
|
|
||||||
|
|
||||||
cases.add("error not handled in switch",
|
cases.add("error not handled in switch",
|
||||||
\\export fn entry() void {
|
\\export fn entry() void {
|
||||||
\\ foo(452) catch |err| switch (err) {
|
\\ foo(452) catch |err| switch (err) {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,7 @@
|
||||||
const expect = @import("std").testing.expect;
|
const std = @import("std");
|
||||||
|
const testing = std.testing;
|
||||||
|
const expect = testing.expect;
|
||||||
|
const expectEqual = testing.expectEqual;
|
||||||
|
|
||||||
test "params" {
|
test "params" {
|
||||||
expect(testParamsAdd(22, 11) == 33);
|
expect(testParamsAdd(22, 11) == 33);
|
||||||
|
|
@ -272,3 +275,12 @@ test "ability to give comptime types and non comptime types to same parameter" {
|
||||||
S.doTheTest();
|
S.doTheTest();
|
||||||
comptime S.doTheTest();
|
comptime S.doTheTest();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test "function with inferred error set but returning no error" {
|
||||||
|
const S = struct {
|
||||||
|
fn foo() !void {}
|
||||||
|
};
|
||||||
|
|
||||||
|
const return_ty = @typeInfo(@TypeOf(S.foo)).Fn.return_type.?;
|
||||||
|
expectEqual(0, @typeInfo(@typeInfo(return_ty).ErrorUnion.error_set).ErrorSet.?.len);
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue