From b9c2837c1c9eddc903aeeb168b8d2daa48837ddb Mon Sep 17 00:00:00 2001 From: Veikka Tuominen Date: Thu, 2 Feb 2023 14:16:15 +0200 Subject: [PATCH 1/5] Sema: validate inferred error set payload type This was missed in b0a55e1b3be3a274546f9c18016e9609d546bdb0 --- src/Sema.zig | 31 +++++++++++-------- .../function_returning_opaque_type.zig | 12 +++---- .../invalid_error_union_payload_type.zig | 7 +++++ 3 files changed, 31 insertions(+), 19 deletions(-) diff --git a/src/Sema.zig b/src/Sema.zig index b7b3a55063..2dba678931 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -7669,19 +7669,23 @@ fn zirErrorUnionType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr error_set.fmt(sema.mod), }); } - if (payload.zigTypeTag() == .Opaque) { - return sema.fail(block, rhs_src, "error union with payload of opaque type '{}' not allowed", .{ - payload.fmt(sema.mod), - }); - } else if (payload.zigTypeTag() == .ErrorSet) { - return sema.fail(block, rhs_src, "error union with payload of error set type '{}' not allowed", .{ - payload.fmt(sema.mod), - }); - } + try sema.validateErrorUnionPayloadType(block, payload, rhs_src); const err_union_ty = try Type.errorUnion(sema.arena, error_set, payload, sema.mod); return sema.addType(err_union_ty); } +fn validateErrorUnionPayloadType(sema: *Sema, block: *Block, payload_ty: Type, payload_src: LazySrcLoc) !void { + if (payload_ty.zigTypeTag() == .Opaque) { + return sema.fail(block, payload_src, "error union with payload of opaque type '{}' not allowed", .{ + payload_ty.fmt(sema.mod), + }); + } else if (payload_ty.zigTypeTag() == .ErrorSet) { + return sema.fail(block, payload_src, "error union with payload of error set type '{}' not allowed", .{ + payload_ty.fmt(sema.mod), + }); + } +} + fn zirErrorValue(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { _ = block; const tracy = trace(@src()); @@ -8639,6 +8643,7 @@ fn funcCommon( const return_type = if (!inferred_error_set or ret_poison) bare_return_type else blk: { + try sema.validateErrorUnionPayloadType(block, bare_return_type, ret_ty_src); const node = try sema.gpa.create(Module.Fn.InferredErrorSetListNode); node.data = .{ .func = new_func }; maybe_inferred_error_set_node = node; @@ -8650,15 +8655,15 @@ fn funcCommon( }); }; - if (!bare_return_type.isValidReturnType()) { - const opaque_str = if (bare_return_type.zigTypeTag() == .Opaque) "opaque " else ""; + if (!return_type.isValidReturnType()) { + const opaque_str = if (return_type.zigTypeTag() == .Opaque) "opaque " else ""; const msg = msg: { const msg = try sema.errMsg(block, ret_ty_src, "{s}return type '{}' not allowed", .{ - opaque_str, bare_return_type.fmt(sema.mod), + opaque_str, return_type.fmt(sema.mod), }); errdefer msg.destroy(sema.gpa); - try sema.addDeclaredHereNote(msg, bare_return_type); + try sema.addDeclaredHereNote(msg, return_type); break :msg msg; }; return sema.failWithOwnedErrorMsg(msg); diff --git a/test/cases/compile_errors/function_returning_opaque_type.zig b/test/cases/compile_errors/function_returning_opaque_type.zig index caf5d74d40..26d70c86c1 100644 --- a/test/cases/compile_errors/function_returning_opaque_type.zig +++ b/test/cases/compile_errors/function_returning_opaque_type.zig @@ -1,11 +1,11 @@ const FooType = opaque {}; -export fn bar() !FooType { +export fn bar() FooType { return error.InvalidValue; } -export fn bav() !@TypeOf(null) { +export fn bav() @TypeOf(null) { return error.InvalidValue; } -export fn baz() !@TypeOf(undefined) { +export fn baz() @TypeOf(undefined) { return error.InvalidValue; } @@ -13,7 +13,7 @@ export fn baz() !@TypeOf(undefined) { // backend=stage2 // target=native // -// :2:18: error: opaque return type 'tmp.FooType' not allowed +// :2:17: error: opaque return type 'tmp.FooType' not allowed // :1:17: note: opaque declared here -// :5:18: error: return type '@TypeOf(null)' not allowed -// :8:18: error: return type '@TypeOf(undefined)' not allowed +// :5:17: error: return type '@TypeOf(null)' not allowed +// :8:17: error: return type '@TypeOf(undefined)' not allowed diff --git a/test/cases/compile_errors/invalid_error_union_payload_type.zig b/test/cases/compile_errors/invalid_error_union_payload_type.zig index f8646d9450..244eb765ec 100644 --- a/test/cases/compile_errors/invalid_error_union_payload_type.zig +++ b/test/cases/compile_errors/invalid_error_union_payload_type.zig @@ -4,6 +4,12 @@ comptime { comptime { _ = anyerror!anyerror; } +fn someFunction() !anyerror { + return error.C; +} +comptime { + _ = someFunction; +} // error // backend=stage2 @@ -11,3 +17,4 @@ comptime { // // :2:18: error: error union with payload of opaque type 'anyopaque' not allowed // :5:18: error: error union with payload of error set type 'anyerror' not allowed +// :7:20: error: error union with payload of error set type 'anyerror' not allowed From 31ed8d293ddb79d34306e0b23e76d8a361c8856f Mon Sep 17 00:00:00 2001 From: Veikka Tuominen Date: Thu, 2 Feb 2023 14:39:13 +0200 Subject: [PATCH 2/5] Sema: add missing peer type resolution for error unions Closes #14077 --- src/Sema.zig | 19 +++++++++++++++++++ test/behavior/cast.zig | 12 ++++++++++++ 2 files changed, 31 insertions(+) diff --git a/src/Sema.zig b/src/Sema.zig index 2dba678931..ddcdecb6b4 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -29761,6 +29761,25 @@ fn resolvePeerTypes( continue; } }, + .ErrorSet => { + chosen = candidate; + chosen_i = candidate_i + 1; + if (err_set_ty) |chosen_set_ty| { + if (.ok == try sema.coerceInMemoryAllowedErrorSets(block, chosen_set_ty, chosen_ty, src, src)) { + continue; + } + if (.ok == try sema.coerceInMemoryAllowedErrorSets(block, chosen_ty, chosen_set_ty, src, src)) { + err_set_ty = chosen_ty; + continue; + } + + err_set_ty = try chosen_set_ty.errorSetMerge(sema.arena, chosen_ty); + continue; + } else { + err_set_ty = chosen_ty; + continue; + } + }, else => {}, } diff --git a/test/behavior/cast.zig b/test/behavior/cast.zig index dbb4c07f64..30889aef04 100644 --- a/test/behavior/cast.zig +++ b/test/behavior/cast.zig @@ -1541,3 +1541,15 @@ test "single item pointer to pointer to array to slice" { const z1 = @as([]const i32, @as(*[1]i32, &x)); try expect(z1[0] == 1234); } + +test "peer type resolution forms error union" { + if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO + + var foo: i32 = 123; + const result = if (foo < 0) switch (-foo) { + 0 => unreachable, + 42 => error.AccessDenied, + else => unreachable, + } else @intCast(u32, foo); + try expect(try result == 123); +} From 8127a27eb11cec26203a8fa15afdee046d3ff507 Mon Sep 17 00:00:00 2001 From: Veikka Tuominen Date: Tue, 7 Feb 2023 15:20:11 +0200 Subject: [PATCH 3/5] zig fmt: do not consider tuples blocks Closes #14056 --- lib/std/zig/render.zig | 8 -------- src/AstGen.zig | 3 ++- src/codegen/llvm.zig | 4 +++- 3 files changed, 5 insertions(+), 10 deletions(-) diff --git a/lib/std/zig/render.zig b/lib/std/zig/render.zig index 1145007ff3..97bc85efac 100644 --- a/lib/std/zig/render.zig +++ b/lib/std/zig/render.zig @@ -2807,14 +2807,6 @@ fn nodeIsBlock(tag: Ast.Node.Tag) bool { .block_semicolon, .block_two, .block_two_semicolon, - .struct_init_dot, - .struct_init_dot_comma, - .struct_init_dot_two, - .struct_init_dot_two_comma, - .array_init_dot, - .array_init_dot_comma, - .array_init_dot_two, - .array_init_dot_two_comma, => true, else => false, }; diff --git a/src/AstGen.zig b/src/AstGen.zig index 10673a2b37..76a681abd3 100644 --- a/src/AstGen.zig +++ b/src/AstGen.zig @@ -1730,7 +1730,8 @@ fn structInitExprRlNone( .container_type = ty_inst, .name_start = str_index, }) } } - else .{ .rl = .none }; + else + .{ .rl = .none }; setExtra(astgen, extra_index, Zir.Inst.StructInitAnon.Item{ .field_name = str_index, .init = try expr(gz, scope, sub_ri, field_init), diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index e19c70f322..9c042120ad 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -2273,7 +2273,9 @@ pub const Object = struct { const full_di_fields: [2]*llvm.DIType = if (layout.tag_align >= layout.payload_align) - .{ tag_di, payload_di } else .{ payload_di, tag_di }; + .{ tag_di, payload_di } + else + .{ payload_di, tag_di }; const full_di_ty = dib.createStructType( compile_unit_scope, From 0328c9cbebd1ff907e9936c0986a9664c4509527 Mon Sep 17 00:00:00 2001 From: Veikka Tuominen Date: Fri, 10 Feb 2023 15:43:28 +0200 Subject: [PATCH 4/5] llvm: fix lowerDeclRefValue for extern function aliases Same as 0577069af5f5deb859762725736537d60c324453 for extern functions. Closes #14610 --- src/codegen/llvm.zig | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index 9c042120ad..8c6943bfdb 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -4164,6 +4164,10 @@ pub const DeclGen = struct { if (func.data.owner_decl != decl_index) { return self.lowerDeclRefValue(tv, func.data.owner_decl); } + } else if (decl.val.castTag(.extern_fn)) |func| { + if (func.data.owner_decl != decl_index) { + return self.lowerDeclRefValue(tv, func.data.owner_decl); + } } const is_fn_body = decl.ty.zigTypeTag() == .Fn; From 28413ffcbad7817c57fd62d5b9908eabdd43147d Mon Sep 17 00:00:00 2001 From: Veikka Tuominen Date: Sat, 11 Feb 2023 13:45:07 +0200 Subject: [PATCH 5/5] Sema: fix typo in `zirCUndef` Closes #14617 --- src/Sema.zig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Sema.zig b/src/Sema.zig index ddcdecb6b4..9eef07648d 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -21935,7 +21935,7 @@ fn zirCUndef( const src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node }; const name = try sema.resolveConstString(block, src, extra.operand, "name of macro being undefined must be comptime-known"); - try block.c_import_buf.?.writer().print("#undefine {s}\n", .{name}); + try block.c_import_buf.?.writer().print("#undef {s}\n", .{name}); return Air.Inst.Ref.void_value; }