authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2023-02-02 14:16:15+02:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2023-02-11 14:36:54+02:00
logb9c2837c1c9eddc903aeeb168b8d2daa48837ddb
tree7ea90436aec6a914cc1f467b8e7dc99250c5c98e
parenta5d25fabdaf7e68f375874b9bda402acaeb9545d

Sema: validate inferred error set payload type

This was missed in b0a55e1b3be3a274546f9c18016e9609d546bdb0

3 files changed, 30 insertions(+), 18 deletions(-)

src/Sema.zig+17-12
...@@ -7669,17 +7669,21 @@ fn zirErrorUnionType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr...@@ -7669,17 +7669,21 @@ fn zirErrorUnionType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr
7669 error_set.fmt(sema.mod),7669 error_set.fmt(sema.mod),
7670 });7670 });
7671 }7671 }
7672 if (payload.zigTypeTag() == .Opaque) {7672 try sema.validateErrorUnionPayloadType(block, payload, rhs_src);
7673 return sema.fail(block, rhs_src, "error union with payload of opaque type '{}' not allowed", .{7673 const err_union_ty = try Type.errorUnion(sema.arena, error_set, payload, sema.mod);
7674 payload.fmt(sema.mod),7674 return sema.addType(err_union_ty);
7675}
7676
7677fn validateErrorUnionPayloadType(sema: *Sema, block: *Block, payload_ty: Type, payload_src: LazySrcLoc) !void {
7678 if (payload_ty.zigTypeTag() == .Opaque) {
7679 return sema.fail(block, payload_src, "error union with payload of opaque type '{}' not allowed", .{
7680 payload_ty.fmt(sema.mod),
7675 });7681 });
7676 } else if (payload.zigTypeTag() == .ErrorSet) {7682 } else if (payload_ty.zigTypeTag() == .ErrorSet) {
7677 return sema.fail(block, rhs_src, "error union with payload of error set type '{}' not allowed", .{7683 return sema.fail(block, payload_src, "error union with payload of error set type '{}' not allowed", .{
7678 payload.fmt(sema.mod),7684 payload_ty.fmt(sema.mod),
7679 });7685 });
7680 }7686 }
7681 const err_union_ty = try Type.errorUnion(sema.arena, error_set, payload, sema.mod);
7682 return sema.addType(err_union_ty);
7683}7687}
76847688
7685fn zirErrorValue(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {7689fn zirErrorValue(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
...@@ -8639,6 +8643,7 @@ fn funcCommon(...@@ -8639,6 +8643,7 @@ fn funcCommon(
8639 const return_type = if (!inferred_error_set or ret_poison)8643 const return_type = if (!inferred_error_set or ret_poison)
8640 bare_return_type8644 bare_return_type
8641 else blk: {8645 else blk: {
8646 try sema.validateErrorUnionPayloadType(block, bare_return_type, ret_ty_src);
8642 const node = try sema.gpa.create(Module.Fn.InferredErrorSetListNode);8647 const node = try sema.gpa.create(Module.Fn.InferredErrorSetListNode);
8643 node.data = .{ .func = new_func };8648 node.data = .{ .func = new_func };
8644 maybe_inferred_error_set_node = node;8649 maybe_inferred_error_set_node = node;
...@@ -8650,15 +8655,15 @@ fn funcCommon(...@@ -8650,15 +8655,15 @@ fn funcCommon(
8650 });8655 });
8651 };8656 };
86528657
8653 if (!bare_return_type.isValidReturnType()) {8658 if (!return_type.isValidReturnType()) {
8654 const opaque_str = if (bare_return_type.zigTypeTag() == .Opaque) "opaque " else "";8659 const opaque_str = if (return_type.zigTypeTag() == .Opaque) "opaque " else "";
8655 const msg = msg: {8660 const msg = msg: {
8656 const msg = try sema.errMsg(block, ret_ty_src, "{s}return type '{}' not allowed", .{8661 const msg = try sema.errMsg(block, ret_ty_src, "{s}return type '{}' not allowed", .{
8657 opaque_str, bare_return_type.fmt(sema.mod),8662 opaque_str, return_type.fmt(sema.mod),
8658 });8663 });
8659 errdefer msg.destroy(sema.gpa);8664 errdefer msg.destroy(sema.gpa);
86608665
8661 try sema.addDeclaredHereNote(msg, bare_return_type);8666 try sema.addDeclaredHereNote(msg, return_type);
8662 break :msg msg;8667 break :msg msg;
8663 };8668 };
8664 return sema.failWithOwnedErrorMsg(msg);8669 return sema.failWithOwnedErrorMsg(msg);
test/cases/compile_errors/function_returning_opaque_type.zig+6-6
...@@ -1,11 +1,11 @@...@@ -1,11 +1,11 @@
1const FooType = opaque {};1const FooType = opaque {};
2export fn bar() !FooType {2export fn bar() FooType {
3 return error.InvalidValue;3 return error.InvalidValue;
4}4}
5export fn bav() !@TypeOf(null) {5export fn bav() @TypeOf(null) {
6 return error.InvalidValue;6 return error.InvalidValue;
7}7}
8export fn baz() !@TypeOf(undefined) {8export fn baz() @TypeOf(undefined) {
9 return error.InvalidValue;9 return error.InvalidValue;
10}10}
1111
...@@ -13,7 +13,7 @@ export fn baz() !@TypeOf(undefined) {...@@ -13,7 +13,7 @@ export fn baz() !@TypeOf(undefined) {
13// backend=stage213// backend=stage2
14// target=native14// target=native
15//15//
16// :2:18: error: opaque return type 'tmp.FooType' not allowed16// :2:17: error: opaque return type 'tmp.FooType' not allowed
17// :1:17: note: opaque declared here17// :1:17: note: opaque declared here
18// :5:18: error: return type '@TypeOf(null)' not allowed18// :5:17: error: return type '@TypeOf(null)' not allowed
19// :8:18: error: return type '@TypeOf(undefined)' not allowed19// :8:17: error: return type '@TypeOf(undefined)' not allowed
test/cases/compile_errors/invalid_error_union_payload_type.zig+7
...@@ -4,6 +4,12 @@ comptime {...@@ -4,6 +4,12 @@ comptime {
4comptime {4comptime {
5 _ = anyerror!anyerror;5 _ = anyerror!anyerror;
6}6}
7fn someFunction() !anyerror {
8 return error.C;
9}
10comptime {
11 _ = someFunction;
12}
713
8// error14// error
9// backend=stage215// backend=stage2
...@@ -11,3 +17,4 @@ comptime {...@@ -11,3 +17,4 @@ comptime {
11//17//
12// :2:18: error: error union with payload of opaque type 'anyopaque' not allowed18// :2:18: error: error union with payload of opaque type 'anyopaque' not allowed
13// :5:18: error: error union with payload of error set type 'anyerror' not allowed19// :5:18: error: error union with payload of error set type 'anyerror' not allowed
20// :7:20: error: error union with payload of error set type 'anyerror' not allowed