| ... | @@ -5747,6 +5747,7 @@ fn zirExport(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void | ... | @@ -5747,6 +5747,7 @@ fn zirExport(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void |
| 5747 | } | 5747 | } |
| 5748 | | 5748 | |
| 5749 | const export_ty = ptr_ty.childType(zcu); | 5749 | const export_ty = ptr_ty.childType(zcu); |
| | 5750 | try sema.ensureLayoutResolved(export_ty, src, .@"export"); |
| 5750 | if (!export_ty.validateExtern(.other, zcu)) { | 5751 | if (!export_ty.validateExtern(.other, zcu)) { |
| 5751 | return sema.failWithOwnedErrorMsg(block, msg: { | 5752 | return sema.failWithOwnedErrorMsg(block, msg: { |
| 5752 | const msg = try sema.errMsg(src, "unable to export type '{f}'", .{export_ty.fmt(pt)}); | 5753 | const msg = try sema.errMsg(src, "unable to export type '{f}'", .{export_ty.fmt(pt)}); |
| ... | @@ -6749,6 +6750,37 @@ fn analyzeCall( | ... | @@ -6749,6 +6750,37 @@ fn analyzeCall( |
| 6749 | } else func_src; | 6750 | } else func_src; |
| 6750 | | 6751 | |
| 6751 | const func_ty_info = zcu.typeToFunc(func_ty).?; | 6752 | const func_ty_info = zcu.typeToFunc(func_ty).?; |
| | 6753 | |
| | 6754 | for (func_ty_info.param_types.get(ip), 0..) |param_ty_ip, param_index| { |
| | 6755 | const arg_src = args_info.argSrc(block, param_index); |
| | 6756 | try sema.ensureLayoutResolved(.fromInterned(param_ty_ip), arg_src, .init); |
| | 6757 | } |
| | 6758 | try sema.ensureLayoutResolved(.fromInterned(func_ty_info.return_type), func_ret_ty_src, .return_type); |
| | 6759 | try sema.validateResolvedFuncType( |
| | 6760 | block, |
| | 6761 | func_ty_info.cc, |
| | 6762 | func_ty_info.param_types.get(ip), |
| | 6763 | .fromInterned(func_ty_info.return_type), |
| | 6764 | func_src, |
| | 6765 | maybe_func_inst, |
| | 6766 | ); |
| | 6767 | |
| | 6768 | if (!callConvIsCallable(func_ty_info.cc)) { |
| | 6769 | return sema.failWithOwnedErrorMsg(block, msg: { |
| | 6770 | const msg = try sema.errMsg( |
| | 6771 | func_src, |
| | 6772 | "unable to call function with calling convention '{s}'", |
| | 6773 | .{@tagName(func_ty_info.cc)}, |
| | 6774 | ); |
| | 6775 | errdefer msg.destroy(gpa); |
| | 6776 | if (maybe_func_inst) |func_inst| try sema.errNote(.{ |
| | 6777 | .base_node_inst = func_inst, |
| | 6778 | .offset = .nodeOffset(.zero), |
| | 6779 | }, msg, "function declared here", .{}); |
| | 6780 | break :msg msg; |
| | 6781 | }); |
| | 6782 | } |
| | 6783 | |
| 6752 | const any_comptime_params = func_ty_info.comptime_bits != 0 or ct: { | 6784 | const any_comptime_params = func_ty_info.comptime_bits != 0 or ct: { |
| 6753 | for (func_ty_info.param_types.get(ip)) |param_ty| { | 6785 | for (func_ty_info.param_types.get(ip)) |param_ty| { |
| 6754 | if (Type.fromInterned(param_ty).comptimeOnly(zcu)) break :ct true; | 6786 | if (Type.fromInterned(param_ty).comptimeOnly(zcu)) break :ct true; |
| ... | @@ -6771,22 +6803,6 @@ fn analyzeCall( | ... | @@ -6771,22 +6803,6 @@ fn analyzeCall( |
| 6771 | break :generic false; | 6803 | break :generic false; |
| 6772 | }; | 6804 | }; |
| 6773 | | 6805 | |
| 6774 | if (!callConvIsCallable(func_ty_info.cc)) { | | |
| 6775 | return sema.failWithOwnedErrorMsg(block, msg: { | | |
| 6776 | const msg = try sema.errMsg( | | |
| 6777 | func_src, | | |
| 6778 | "unable to call function with calling convention '{s}'", | | |
| 6779 | .{@tagName(func_ty_info.cc)}, | | |
| 6780 | ); | | |
| 6781 | errdefer msg.destroy(gpa); | | |
| 6782 | if (maybe_func_inst) |func_inst| try sema.errNote(.{ | | |
| 6783 | .base_node_inst = func_inst, | | |
| 6784 | .offset = .nodeOffset(.zero), | | |
| 6785 | }, msg, "function declared here", .{}); | | |
| 6786 | break :msg msg; | | |
| 6787 | }); | | |
| 6788 | } | | |
| 6789 | | | |
| 6790 | // We need this value in a few code paths. | 6806 | // We need this value in a few code paths. |
| 6791 | const callee_val = try sema.resolveDefinedValue(block, call_src, callee); | 6807 | const callee_val = try sema.resolveDefinedValue(block, call_src, callee); |
| 6792 | // If the callee is a comptime-known *non-extern* function, `func_val` is populated. | 6808 | // If the callee is a comptime-known *non-extern* function, `func_val` is populated. |
| ... | @@ -8755,11 +8771,12 @@ fn checkCallConvSupportsVarArgs(sema: *Sema, block: *Block, src: LazySrcLoc, cc: | ... | @@ -8755,11 +8771,12 @@ fn checkCallConvSupportsVarArgs(sema: *Sema, block: *Block, src: LazySrcLoc, cc: |
| 8755 | } | 8771 | } |
| 8756 | } | 8772 | } |
| 8757 | | 8773 | |
| 8758 | fn checkParamTypeCommon( | 8774 | fn checkParamType( |
| 8759 | sema: *Sema, | 8775 | sema: *Sema, |
| 8760 | block: *Block, | 8776 | block: *Block, |
| 8761 | param_idx: u32, | 8777 | param_idx: u32, |
| 8762 | param_ty: Type, | 8778 | param_ty: Type, |
| | 8779 | param_is_comptime: bool, |
| 8763 | param_is_noalias: bool, | 8780 | param_is_noalias: bool, |
| 8764 | param_src: LazySrcLoc, | 8781 | param_src: LazySrcLoc, |
| 8765 | cc: std.builtin.CallingConvention, | 8782 | cc: std.builtin.CallingConvention, |
| ... | @@ -8774,29 +8791,22 @@ fn checkParamTypeCommon( | ... | @@ -8774,29 +8791,22 @@ fn checkParamTypeCommon( |
| 8774 | opaque_str, param_ty.fmt(pt), | 8791 | opaque_str, param_ty.fmt(pt), |
| 8775 | }); | 8792 | }); |
| 8776 | } | 8793 | } |
| 8777 | if (!param_ty.isGenericPoison() and | 8794 | if (!target_util.fnCallConvAllowsZigTypes(cc)) { |
| 8778 | !target_util.fnCallConvAllowsZigTypes(cc) and | 8795 | if (param_is_comptime) { |
| 8779 | !param_ty.validateExtern(.param_ty, zcu)) | 8796 | return sema.fail(block, param_src, "comptime parameters not allowed in function with calling convention '{t}'", .{cc}); |
| 8780 | { | 8797 | } |
| 8781 | return sema.failWithOwnedErrorMsg(block, msg: { | 8798 | if (param_ty.isGenericPoison()) { |
| 8782 | const msg = try sema.errMsg(param_src, "parameter of type '{f}' not allowed in function with calling convention '{s}'", .{ | 8799 | return sema.fail(block, param_src, "generic parameters not allowed in function with calling convention '{t}'", .{cc}); |
| 8783 | param_ty.fmt(pt), @tagName(cc), | 8800 | } |
| 8784 | }); | 8801 | // The `validateExtern` check happens later, in `validateResolvedFuncType`. |
| 8785 | errdefer msg.destroy(sema.gpa); | | |
| 8786 | | | |
| 8787 | try sema.explainWhyTypeIsNotExtern(msg, param_src, param_ty, .param_ty); | | |
| 8788 | | | |
| 8789 | try sema.addDeclaredHereNote(msg, param_ty); | | |
| 8790 | break :msg msg; | | |
| 8791 | }); | | |
| 8792 | } | 8802 | } |
| 8793 | switch (cc) { | 8803 | switch (cc) { |
| 8794 | .x86_64_interrupt, .x86_interrupt => { | 8804 | .x86_64_interrupt, .x86_interrupt => { |
| 8795 | const err_code_size = target.ptrBitWidth(); | 8805 | const err_code_size = target.ptrBitWidth(); |
| 8796 | switch (param_idx) { | 8806 | switch (param_idx) { |
| 8797 | 0 => if (param_ty.zigTypeTag(zcu) != .pointer) return sema.fail(block, param_src, "first parameter of function with '{s}' calling convention must be a pointer type", .{@tagName(cc)}), | 8807 | 0 => if (param_ty.zigTypeTag(zcu) != .pointer) return sema.fail(block, param_src, "first parameter of function with '{t}' calling convention must be a pointer type", .{cc}), |
| 8798 | 1 => if (param_ty.bitSize(zcu) != err_code_size) return sema.fail(block, param_src, "second parameter of function with '{s}' calling convention must be a {d}-bit integer", .{ @tagName(cc), err_code_size }), | 8808 | 1 => if (param_ty.bitSize(zcu) != err_code_size) return sema.fail(block, param_src, "second parameter of function with '{t}' calling convention must be a {d}-bit integer", .{ cc, err_code_size }), |
| 8799 | else => return sema.fail(block, param_src, "'{s}' calling convention supports up to 2 parameters, found {d}", .{ @tagName(cc), param_idx + 1 }), | 8809 | else => return sema.fail(block, param_src, "'{t}' calling convention supports up to 2 parameters, found {d}", .{ cc, param_idx + 1 }), |
| 8800 | } | 8810 | } |
| 8801 | }, | 8811 | }, |
| 8802 | .arc_interrupt, | 8812 | .arc_interrupt, |
| ... | @@ -8812,7 +8822,7 @@ fn checkParamTypeCommon( | ... | @@ -8812,7 +8822,7 @@ fn checkParamTypeCommon( |
| 8812 | .m68k_interrupt, | 8822 | .m68k_interrupt, |
| 8813 | .msp430_interrupt, | 8823 | .msp430_interrupt, |
| 8814 | .avr_signal, | 8824 | .avr_signal, |
| 8815 | => return sema.fail(block, param_src, "parameters are not allowed with '{s}' calling convention", .{@tagName(cc)}), | 8825 | => return sema.fail(block, param_src, "parameters are not allowed with '{t}' calling convention", .{cc}), |
| 8816 | else => {}, | 8826 | else => {}, |
| 8817 | } | 8827 | } |
| 8818 | if (param_is_noalias and !param_ty.isGenericPoison() and !param_ty.isPtrAtRuntime(zcu) and !param_ty.isSliceAtRuntime(zcu)) { | 8828 | if (param_is_noalias and !param_ty.isGenericPoison() and !param_ty.isPtrAtRuntime(zcu) and !param_ty.isSliceAtRuntime(zcu)) { |
| ... | @@ -8820,7 +8830,7 @@ fn checkParamTypeCommon( | ... | @@ -8820,7 +8830,7 @@ fn checkParamTypeCommon( |
| 8820 | } | 8830 | } |
| 8821 | } | 8831 | } |
| 8822 | | 8832 | |
| 8823 | fn checkReturnTypeAndCallConvCommon( | 8833 | fn checkReturnTypeAndCallConv( |
| 8824 | sema: *Sema, | 8834 | sema: *Sema, |
| 8825 | block: *Block, | 8835 | block: *Block, |
| 8826 | bare_ret_ty: Type, | 8836 | bare_ret_ty: Type, |
| ... | @@ -8834,7 +8844,6 @@ fn checkReturnTypeAndCallConvCommon( | ... | @@ -8834,7 +8844,6 @@ fn checkReturnTypeAndCallConvCommon( |
| 8834 | ) CompileError!void { | 8844 | ) CompileError!void { |
| 8835 | const pt = sema.pt; | 8845 | const pt = sema.pt; |
| 8836 | const zcu = pt.zcu; | 8846 | const zcu = pt.zcu; |
| 8837 | const gpa = zcu.gpa; | | |
| 8838 | if (opt_varargs_src) |varargs_src| { | 8847 | if (opt_varargs_src) |varargs_src| { |
| 8839 | try sema.checkCallConvSupportsVarArgs(block, varargs_src, @"callconv"); | 8848 | try sema.checkCallConvSupportsVarArgs(block, varargs_src, @"callconv"); |
| 8840 | } | 8849 | } |
| ... | @@ -8848,21 +8857,14 @@ fn checkReturnTypeAndCallConvCommon( | ... | @@ -8848,21 +8857,14 @@ fn checkReturnTypeAndCallConvCommon( |
| 8848 | opaque_str, ies_ret_ty_prefix, bare_ret_ty.fmt(pt), | 8857 | opaque_str, ies_ret_ty_prefix, bare_ret_ty.fmt(pt), |
| 8849 | }); | 8858 | }); |
| 8850 | } | 8859 | } |
| 8851 | if (!bare_ret_ty.isGenericPoison() and | 8860 | if (!target_util.fnCallConvAllowsZigTypes(@"callconv")) { |
| 8852 | !target_util.fnCallConvAllowsZigTypes(@"callconv") and | 8861 | if (inferred_error_set) { |
| 8853 | (inferred_error_set or !bare_ret_ty.validateExtern(.ret_ty, zcu))) | 8862 | return sema.fail(block, ret_ty_src, "return type '!{f}' not allowed in function with calling convention '{t}'", .{ bare_ret_ty.fmt(pt), @"callconv" }); |
| 8854 | { | 8863 | } |
| 8855 | return sema.failWithOwnedErrorMsg(block, msg: { | 8864 | if (bare_ret_ty.isGenericPoison()) { |
| 8856 | const msg = try sema.errMsg(ret_ty_src, "return type '{s}{f}' not allowed in function with calling convention '{s}'", .{ | 8865 | return sema.fail(block, ret_ty_src, "generic return type not allowed in function with calling convention '{t}'", .{@"callconv"}); |
| 8857 | ies_ret_ty_prefix, bare_ret_ty.fmt(pt), @tagName(@"callconv"), | 8866 | } |
| 8858 | }); | 8867 | // The `validateExtern` check happens later, in `validateResolvedFuncType`. |
| 8859 | errdefer msg.destroy(gpa); | | |
| 8860 | if (!inferred_error_set) { | | |
| 8861 | try sema.explainWhyTypeIsNotExtern(msg, ret_ty_src, bare_ret_ty, .ret_ty); | | |
| 8862 | try sema.addDeclaredHereNote(msg, bare_ret_ty); | | |
| 8863 | } | | |
| 8864 | break :msg msg; | | |
| 8865 | }); | | |
| 8866 | } | 8868 | } |
| 8867 | validate_incoming_stack_align: { | 8869 | validate_incoming_stack_align: { |
| 8868 | const a: u64 = switch (@"callconv") { | 8870 | const a: u64 = switch (@"callconv") { |
| ... | @@ -8897,7 +8899,7 @@ fn checkReturnTypeAndCallConvCommon( | ... | @@ -8897,7 +8899,7 @@ fn checkReturnTypeAndCallConvCommon( |
| 8897 | else => false, | 8899 | else => false, |
| 8898 | }; | 8900 | }; |
| 8899 | if (!ret_ok) { | 8901 | if (!ret_ok) { |
| 8900 | return sema.fail(block, ret_ty_src, "function with calling convention '{s}' must return 'void' or 'noreturn'", .{@tagName(@"callconv")}); | 8902 | return sema.fail(block, ret_ty_src, "function with calling convention '{t}' must return 'void' or 'noreturn'", .{@"callconv"}); |
| 8901 | } | 8903 | } |
| 8902 | }, | 8904 | }, |
| 8903 | .@"inline" => if (is_noinline) { | 8905 | .@"inline" => if (is_noinline) { |
| ... | @@ -8918,18 +8920,76 @@ fn checkReturnTypeAndCallConvCommon( | ... | @@ -8918,18 +8920,76 @@ fn checkReturnTypeAndCallConvCommon( |
| 8918 | } | 8920 | } |
| 8919 | } | 8921 | } |
| 8920 | }; | 8922 | }; |
| 8921 | return sema.fail(block, callconv_src, "calling convention '{s}' only available on architectures {f}", .{ | 8923 | return sema.fail(block, callconv_src, "calling convention '{t}' only available on architectures {f}", .{ |
| 8922 | @tagName(@"callconv"), | 8924 | @"callconv", ArchListFormatter{ .archs = allowed_archs }, |
| 8923 | ArchListFormatter{ .archs = allowed_archs }, | | |
| 8924 | }); | 8925 | }); |
| 8925 | }, | 8926 | }, |
| 8926 | .bad_backend => |bad_backend| return sema.fail(block, callconv_src, "calling convention '{s}' not supported by compiler backend '{s}'", .{ | 8927 | .bad_backend => |bad_backend| return sema.fail(block, callconv_src, "calling convention '{t}' not supported by compiler backend '{t}'", .{ |
| 8927 | @tagName(@"callconv"), | 8928 | @"callconv", bad_backend, |
| 8928 | @tagName(bad_backend), | | |
| 8929 | }), | 8929 | }), |
| 8930 | } | 8930 | } |
| 8931 | } | 8931 | } |
| 8932 | | 8932 | |
| | 8933 | /// To avoid forcing type layout resolution too quickly, some validation of function types cannot be |
| | 8934 | /// performed when the type is first constructed, and instead must happen when either (a) a function |
| | 8935 | /// with that type is declared, or (b) a function with that type is called. That validation is |
| | 8936 | /// handled here. |
| | 8937 | /// |
| | 8938 | /// Asserts that all parameter types and return types have their layout fully resolved. |
| | 8939 | fn validateResolvedFuncType( |
| | 8940 | sema: *Sema, |
| | 8941 | block: *Block, |
| | 8942 | @"callconv": std.builtin.CallingConvention, |
| | 8943 | param_types: []const InternPool.Index, |
| | 8944 | ret_ty: Type, |
| | 8945 | src: LazySrcLoc, |
| | 8946 | maybe_func_decl_inst: ?InternPool.TrackedInst.Index, |
| | 8947 | ) SemaError!void { |
| | 8948 | const pt = sema.pt; |
| | 8949 | const zcu = pt.zcu; |
| | 8950 | const gpa = zcu.comp.gpa; |
| | 8951 | if (!target_util.fnCallConvAllowsZigTypes(@"callconv")) { |
| | 8952 | // Check that all parameter types are extern-compatible. |
| | 8953 | for (param_types, 0..) |param_ty_ip, param_index| { |
| | 8954 | const param_ty: Type = .fromInterned(param_ty_ip); |
| | 8955 | if (!param_ty.validateExtern(.param_ty, zcu)) { |
| | 8956 | const param_src: LazySrcLoc = if (maybe_func_decl_inst) |inst| .{ |
| | 8957 | .base_node_inst = inst, |
| | 8958 | .offset = .{ .fn_proto_param = .{ |
| | 8959 | .fn_proto_node_offset = .zero, |
| | 8960 | .param_index = @intCast(param_index), |
| | 8961 | } }, |
| | 8962 | } else src; |
| | 8963 | return sema.failWithOwnedErrorMsg(block, msg: { |
| | 8964 | const msg = try sema.errMsg(param_src, "parameter of type '{f}' not allowed in function with calling convention '{t}'", .{ |
| | 8965 | param_ty.fmt(pt), @"callconv", |
| | 8966 | }); |
| | 8967 | errdefer msg.destroy(gpa); |
| | 8968 | try sema.explainWhyTypeIsNotExtern(msg, param_src, param_ty, .param_ty); |
| | 8969 | try sema.addDeclaredHereNote(msg, param_ty); |
| | 8970 | break :msg msg; |
| | 8971 | }); |
| | 8972 | } |
| | 8973 | } |
| | 8974 | // Check that the return type is extern-compatible. |
| | 8975 | if (!ret_ty.validateExtern(.ret_ty, zcu)) { |
| | 8976 | const ret_ty_src: LazySrcLoc = if (maybe_func_decl_inst) |inst| .{ |
| | 8977 | .base_node_inst = inst, |
| | 8978 | .offset = .{ .node_offset_fn_type_ret_ty = .zero }, |
| | 8979 | } else src; |
| | 8980 | return sema.failWithOwnedErrorMsg(block, msg: { |
| | 8981 | const msg = try sema.errMsg(ret_ty_src, "return type '{f}' not allowed in function with calling convention '{t}'", .{ |
| | 8982 | ret_ty.fmt(pt), @"callconv", |
| | 8983 | }); |
| | 8984 | errdefer msg.destroy(gpa); |
| | 8985 | try sema.explainWhyTypeIsNotExtern(msg, ret_ty_src, ret_ty, .ret_ty); |
| | 8986 | try sema.addDeclaredHereNote(msg, ret_ty); |
| | 8987 | break :msg msg; |
| | 8988 | }); |
| | 8989 | } |
| | 8990 | } |
| | 8991 | } |
| | 8992 | |
| 8933 | fn callConvIsCallable(cc: std.builtin.CallingConvention.Tag) bool { | 8993 | fn callConvIsCallable(cc: std.builtin.CallingConvention.Tag) bool { |
| 8934 | return switch (cc) { | 8994 | return switch (cc) { |
| 8935 | .naked, | 8995 | .naked, |
| ... | @@ -9022,6 +9082,7 @@ fn funcCommon( | ... | @@ -9022,6 +9082,7 @@ fn funcCommon( |
| 9022 | const io = comp.io; | 9082 | const io = comp.io; |
| 9023 | const ip = &zcu.intern_pool; | 9083 | const ip = &zcu.intern_pool; |
| 9024 | | 9084 | |
| | 9085 | const src = block.nodeOffset(src_node_offset); |
| 9025 | const ret_ty_src = block.src(.{ .node_offset_fn_type_ret_ty = src_node_offset }); | 9086 | const ret_ty_src = block.src(.{ .node_offset_fn_type_ret_ty = src_node_offset }); |
| 9026 | const cc_src = block.src(.{ .node_offset_fn_type_cc = src_node_offset }); | 9087 | const cc_src = block.src(.{ .node_offset_fn_type_cc = src_node_offset }); |
| 9027 | | 9088 | |
| ... | @@ -9036,27 +9097,21 @@ fn funcCommon( | ... | @@ -9036,27 +9097,21 @@ fn funcCommon( |
| 9036 | .fn_proto_node_offset = src_node_offset, | 9097 | .fn_proto_node_offset = src_node_offset, |
| 9037 | .param_index = @intCast(i), | 9098 | .param_index = @intCast(i), |
| 9038 | } }); | 9099 | } }); |
| 9039 | const param_ty_generic = param_ty.isGenericPoison(); | | |
| 9040 | if (param_is_comptime) { | 9100 | if (param_is_comptime) { |
| 9041 | comptime_bits |= @as(u32, 1) << @intCast(i); // TODO: handle cast error | 9101 | comptime_bits |= @as(u32, 1) << @intCast(i); // TODO: handle cast error |
| 9042 | } | 9102 | } |
| 9043 | if (param_is_comptime and !target_util.fnCallConvAllowsZigTypes(cc)) { | 9103 | try sema.checkParamType( |
| 9044 | return sema.fail(block, param_src, "comptime parameters not allowed in function with calling convention '{s}'", .{@tagName(cc)}); | | |
| 9045 | } | | |
| 9046 | if (param_ty_generic and !target_util.fnCallConvAllowsZigTypes(cc)) { | | |
| 9047 | return sema.fail(block, param_src, "generic parameters not allowed in function with calling convention '{s}'", .{@tagName(cc)}); | | |
| 9048 | } | | |
| 9049 | try sema.checkParamTypeCommon( | | |
| 9050 | block, | 9104 | block, |
| 9051 | @intCast(i), | 9105 | @intCast(i), |
| 9052 | param_ty, | 9106 | param_ty, |
| | 9107 | param_is_comptime, |
| 9053 | is_noalias, | 9108 | is_noalias, |
| 9054 | param_src, | 9109 | param_src, |
| 9055 | cc, | 9110 | cc, |
| 9056 | ); | 9111 | ); |
| 9057 | } | 9112 | } |
| 9058 | | 9113 | |
| 9059 | try sema.checkReturnTypeAndCallConvCommon( | 9114 | try sema.checkReturnTypeAndCallConv( |
| 9060 | block, | 9115 | block, |
| 9061 | bare_return_type, | 9116 | bare_return_type, |
| 9062 | ret_ty_src, | 9117 | ret_ty_src, |
| ... | @@ -9072,9 +9127,29 @@ fn funcCommon( | ... | @@ -9072,9 +9127,29 @@ fn funcCommon( |
| 9072 | | 9127 | |
| 9073 | const param_types = block.params.items(.ty); | 9128 | const param_types = block.params.items(.ty); |
| 9074 | | 9129 | |
| | 9130 | if (has_body) { |
| | 9131 | for (param_types, 0..) |param_ty_ip, param_index| { |
| | 9132 | const param_ty: Type = .fromInterned(param_ty_ip); |
| | 9133 | const param_src = block.src(.{ .fn_proto_param = .{ |
| | 9134 | .fn_proto_node_offset = src_node_offset, |
| | 9135 | .param_index = @intCast(param_index), |
| | 9136 | } }); |
| | 9137 | try sema.ensureLayoutResolved(param_ty, param_src, .parameter); |
| | 9138 | } |
| | 9139 | try sema.ensureLayoutResolved(bare_return_type, ret_ty_src, .return_type); |
| | 9140 | try sema.validateResolvedFuncType( |
| | 9141 | block, |
| | 9142 | cc, |
| | 9143 | param_types, |
| | 9144 | bare_return_type, |
| | 9145 | src, |
| | 9146 | ip.getNav(sema.owner.unwrap().nav_val).srcInst(ip), |
| | 9147 | ); |
| | 9148 | } |
| | 9149 | |
| 9075 | if (inferred_error_set) { | 9150 | if (inferred_error_set) { |
| 9076 | assert(has_body); | 9151 | assert(has_body); |
| 9077 | const func_val: Value = .fromInterned(try ip.getFuncDeclIes(gpa, io, pt.tid, .{ | 9152 | return .fromIntern(try ip.getFuncDeclIes(gpa, io, pt.tid, .{ |
| 9078 | .owner_nav = sema.owner.unwrap().nav_val, | 9153 | .owner_nav = sema.owner.unwrap().nav_val, |
| 9079 | | 9154 | |
| 9080 | .param_types = param_types, | 9155 | .param_types = param_types, |
| ... | @@ -9091,8 +9166,6 @@ fn funcCommon( | ... | @@ -9091,8 +9166,6 @@ fn funcCommon( |
| 9091 | .lbrace_column = @as(u16, @truncate(src_locs.columns)), | 9166 | .lbrace_column = @as(u16, @truncate(src_locs.columns)), |
| 9092 | .rbrace_column = @as(u16, @truncate(src_locs.columns >> 16)), | 9167 | .rbrace_column = @as(u16, @truncate(src_locs.columns >> 16)), |
| 9093 | })); | 9168 | })); |
| 9094 | try sema.ensureLayoutResolved(func_val.typeOf(zcu), ret_ty_src, .return_type); | | |
| 9095 | return .fromValue(func_val); | | |
| 9096 | } | 9169 | } |
| 9097 | | 9170 | |
| 9098 | const func_ty = try ip.getFuncType(gpa, io, pt.tid, .{ | 9171 | const func_ty = try ip.getFuncType(gpa, io, pt.tid, .{ |
| ... | @@ -9106,7 +9179,6 @@ fn funcCommon( | ... | @@ -9106,7 +9179,6 @@ fn funcCommon( |
| 9106 | }); | 9179 | }); |
| 9107 | | 9180 | |
| 9108 | if (has_body) { | 9181 | if (has_body) { |
| 9109 | try sema.ensureLayoutResolved(.fromInterned(func_ty), ret_ty_src, .return_type); | | |
| 9110 | return .fromIntern(try ip.getFuncDecl(gpa, io, pt.tid, .{ | 9182 | return .fromIntern(try ip.getFuncDecl(gpa, io, pt.tid, .{ |
| 9111 | .owner_nav = sema.owner.unwrap().nav_val, | 9183 | .owner_nav = sema.owner.unwrap().nav_val, |
| 9112 | .ty = func_ty, | 9184 | .ty = func_ty, |
| ... | @@ -18256,19 +18328,6 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air | ... | @@ -18256,19 +18328,6 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 18256 | } | 18328 | } |
| 18257 | } else if (inst_data.size != .one and elem_ty.zigTypeTag(zcu) == .@"opaque") { | 18329 | } else if (inst_data.size != .one and elem_ty.zigTypeTag(zcu) == .@"opaque") { |
| 18258 | return sema.fail(block, elem_ty_src, "indexable pointer to opaque type '{f}' not allowed", .{elem_ty.fmt(pt)}); | 18330 | return sema.fail(block, elem_ty_src, "indexable pointer to opaque type '{f}' not allowed", .{elem_ty.fmt(pt)}); |
| 18259 | } else if (inst_data.size == .c) { | | |
| 18260 | if (!elem_ty.validateExtern(.other, zcu)) { | | |
| 18261 | const msg = msg: { | | |
| 18262 | const msg = try sema.errMsg(elem_ty_src, "C pointers cannot point to non-C-ABI-compatible type '{f}'", .{elem_ty.fmt(pt)}); | | |
| 18263 | errdefer msg.destroy(sema.gpa); | | |
| 18264 | | | |
| 18265 | try sema.explainWhyTypeIsNotExtern(msg, elem_ty_src, elem_ty, .other); | | |
| 18266 | | | |
| 18267 | try sema.addDeclaredHereNote(msg, elem_ty); | | |
| 18268 | break :msg msg; | | |
| 18269 | }; | | |
| 18270 | return sema.failWithOwnedErrorMsg(block, msg); | | |
| 18271 | } | | |
| 18272 | } | 18331 | } |
| 18273 | | 18332 | |
| 18274 | if (host_size != 0) { | 18333 | if (host_size != 0) { |
| ... | @@ -19800,16 +19859,6 @@ fn zirReifyPointer( | ... | @@ -19800,16 +19859,6 @@ fn zirReifyPointer( |
| 19800 | else => {}, | 19859 | else => {}, |
| 19801 | } | 19860 | } |
| 19802 | | 19861 | |
| 19803 | if (size == .c and !elem_ty.validateExtern(.other, zcu)) { | | |
| 19804 | return sema.failWithOwnedErrorMsg(block, msg: { | | |
| 19805 | const msg = try sema.errMsg(src, "C pointers cannot point to non-C-ABI-compatible type '{f}'", .{elem_ty.fmt(pt)}); | | |
| 19806 | errdefer msg.destroy(gpa); | | |
| 19807 | try sema.explainWhyTypeIsNotExtern(msg, elem_ty_src, elem_ty, .other); | | |
| 19808 | try sema.addDeclaredHereNote(msg, elem_ty); | | |
| 19809 | break :msg msg; | | |
| 19810 | }); | | |
| 19811 | } | | |
| 19812 | | | |
| 19813 | const sentinel_ty = try pt.optionalType(elem_ty.toIntern()); | 19862 | const sentinel_ty = try pt.optionalType(elem_ty.toIntern()); |
| 19814 | const sentinel_uncoerced = sema.resolveInst(extra.sentinel); | 19863 | const sentinel_uncoerced = sema.resolveInst(extra.sentinel); |
| 19815 | const sentinel_coerced = try sema.coerce(block, sentinel_ty, sentinel_uncoerced, sentinel_src); | 19864 | const sentinel_coerced = try sema.coerce(block, sentinel_ty, sentinel_uncoerced, sentinel_src); |
| ... | @@ -19898,10 +19947,11 @@ fn zirReifyFn( | ... | @@ -19898,10 +19947,11 @@ fn zirReifyFn( |
| 19898 | try param_attrs_arr.elemValue(pt, param_idx), | 19947 | try param_attrs_arr.elemValue(pt, param_idx), |
| 19899 | std.builtin.Type.Fn.Param.Attributes, | 19948 | std.builtin.Type.Fn.Param.Attributes, |
| 19900 | ); | 19949 | ); |
| 19901 | try sema.checkParamTypeCommon( | 19950 | try sema.checkParamType( |
| 19902 | block, | 19951 | block, |
| 19903 | @intCast(param_idx), | 19952 | @intCast(param_idx), |
| 19904 | param_ty, | 19953 | param_ty, |
| | 19954 | false, |
| 19905 | param_attrs.@"noalias", | 19955 | param_attrs.@"noalias", |
| 19906 | param_types_src, | 19956 | param_types_src, |
| 19907 | fn_attrs.@"callconv", | 19957 | fn_attrs.@"callconv", |
| ... | @@ -19919,7 +19969,7 @@ fn zirReifyFn( | ... | @@ -19919,7 +19969,7 @@ fn zirReifyFn( |
| 19919 | try sema.checkCallConvSupportsVarArgs(block, fn_attrs_src, fn_attrs.@"callconv"); | 19969 | try sema.checkCallConvSupportsVarArgs(block, fn_attrs_src, fn_attrs.@"callconv"); |
| 19920 | } | 19970 | } |
| 19921 | | 19971 | |
| 19922 | try sema.checkReturnTypeAndCallConvCommon( | 19972 | try sema.checkReturnTypeAndCallConv( |
| 19923 | block, | 19973 | block, |
| 19924 | ret_ty, | 19974 | ret_ty, |
| 19925 | ret_ty_src, | 19975 | ret_ty_src, |
| ... | @@ -19929,9 +19979,6 @@ fn zirReifyFn( | ... | @@ -19929,9 +19979,6 @@ fn zirReifyFn( |
| 19929 | false, | 19979 | false, |
| 19930 | false, | 19980 | false, |
| 19931 | ); | 19981 | ); |
| 19932 | if (ret_ty.comptimeOnly(zcu)) { | | |
| 19933 | return sema.fail(block, param_attrs_src, "cannot reify function type with comptime-only return type '{f}'", .{ret_ty.fmt(pt)}); | | |
| 19934 | } | | |
| 19935 | | 19982 | |
| 19936 | return .fromIntern(try ip.getFuncType(gpa, io, pt.tid, .{ | 19983 | return .fromIntern(try ip.getFuncType(gpa, io, pt.tid, .{ |
| 19937 | .param_types = param_types_ip, | 19984 | .param_types = param_types_ip, |
| ... | @@ -20615,7 +20662,7 @@ fn zirCVaArg(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) C | ... | @@ -20615,7 +20662,7 @@ fn zirCVaArg(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) C |
| 20615 | | 20662 | |
| 20616 | const va_list_ref = try sema.resolveVaListRef(block, va_list_src, extra.lhs); | 20663 | const va_list_ref = try sema.resolveVaListRef(block, va_list_src, extra.lhs); |
| 20617 | const arg_ty = try sema.resolveType(block, ty_src, extra.rhs); | 20664 | const arg_ty = try sema.resolveType(block, ty_src, extra.rhs); |
| 20618 | | 20665 | try sema.ensureLayoutResolved(arg_ty, ty_src, .parameter); |
| 20619 | if (!arg_ty.validateExtern(.param_ty, sema.pt.zcu)) { | 20666 | if (!arg_ty.validateExtern(.param_ty, sema.pt.zcu)) { |
| 20620 | const msg = msg: { | 20667 | const msg = msg: { |
| 20621 | const msg = try sema.errMsg(ty_src, "cannot get '{f}' from variadic argument", .{arg_ty.fmt(sema.pt)}); | 20668 | const msg = try sema.errMsg(ty_src, "cannot get '{f}' from variadic argument", .{arg_ty.fmt(sema.pt)}); |
| ... | @@ -24639,13 +24686,12 @@ fn zirBuiltinExtern( | ... | @@ -24639,13 +24686,12 @@ fn zirBuiltinExtern( |
| 24639 | return sema.fail(block, ty_src, "expected (optional) pointer", .{}); | 24686 | return sema.fail(block, ty_src, "expected (optional) pointer", .{}); |
| 24640 | } | 24687 | } |
| 24641 | if (!ty.validateExtern(.other, zcu)) { | 24688 | if (!ty.validateExtern(.other, zcu)) { |
| 24642 | const msg = msg: { | 24689 | return sema.failWithOwnedErrorMsg(block, msg: { |
| 24643 | const msg = try sema.errMsg(ty_src, "extern symbol cannot have type '{f}'", .{ty.fmt(pt)}); | 24690 | const msg = try sema.errMsg(ty_src, "extern symbol cannot have type '{f}'", .{ty.fmt(pt)}); |
| 24644 | errdefer msg.destroy(sema.gpa); | 24691 | errdefer msg.destroy(sema.gpa); |
| 24645 | try sema.explainWhyTypeIsNotExtern(msg, ty_src, ty, .other); | 24692 | try sema.explainWhyTypeIsNotExtern(msg, ty_src, ty, .other); |
| 24646 | break :msg msg; | 24693 | break :msg msg; |
| 24647 | }; | 24694 | }); |
| 24648 | return sema.failWithOwnedErrorMsg(block, msg); | | |
| 24649 | } | 24695 | } |
| 24650 | | 24696 | |
| 24651 | const options = try sema.resolveExternOptions(block, options_src, extra.rhs); | 24697 | const options = try sema.resolveExternOptions(block, options_src, extra.rhs); |
| ... | @@ -25034,7 +25080,7 @@ pub fn explainWhyTypeIsNotExtern( | ... | @@ -25034,7 +25080,7 @@ pub fn explainWhyTypeIsNotExtern( |
| 25034 | src_loc: LazySrcLoc, | 25080 | src_loc: LazySrcLoc, |
| 25035 | ty: Type, | 25081 | ty: Type, |
| 25036 | position: Type.ExternPosition, | 25082 | position: Type.ExternPosition, |
| 25037 | ) CompileError!void { | 25083 | ) SemaError!void { |
| 25038 | const pt = sema.pt; | 25084 | const pt = sema.pt; |
| 25039 | const zcu = pt.zcu; | 25085 | const zcu = pt.zcu; |
| 25040 | switch (ty.zigTypeTag(zcu)) { | 25086 | switch (ty.zigTypeTag(zcu)) { |