| ... | ... | @@ -5747,6 +5747,7 @@ fn zirExport(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void |
| 5747 | 5747 | } |
| 5748 | 5748 | |
| 5749 | 5749 | const export_ty = ptr_ty.childType(zcu); |
| 5750 | try sema.ensureLayoutResolved(export_ty, src, .@"export"); |
| 5750 | 5751 | if (!export_ty.validateExtern(.other, zcu)) { |
| 5751 | 5752 | return sema.failWithOwnedErrorMsg(block, msg: { |
| 5752 | 5753 | const msg = try sema.errMsg(src, "unable to export type '{f}'", .{export_ty.fmt(pt)}); |
| ... | ... | @@ -6749,6 +6750,37 @@ fn analyzeCall( |
| 6749 | 6750 | } else func_src; |
| 6750 | 6751 | |
| 6751 | 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 | 6784 | const any_comptime_params = func_ty_info.comptime_bits != 0 or ct: { |
| 6753 | 6785 | for (func_ty_info.param_types.get(ip)) |param_ty| { |
| 6754 | 6786 | if (Type.fromInterned(param_ty).comptimeOnly(zcu)) break :ct true; |
| ... | ... | @@ -6771,22 +6803,6 @@ fn analyzeCall( |
| 6771 | 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 | 6806 | // We need this value in a few code paths. |
| 6791 | 6807 | const callee_val = try sema.resolveDefinedValue(block, call_src, callee); |
| 6792 | 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 | 8771 | } |
| 8756 | 8772 | } |
| 8757 | 8773 | |
| 8758 | | fn checkParamTypeCommon( |
| 8774 | fn checkParamType( |
| 8759 | 8775 | sema: *Sema, |
| 8760 | 8776 | block: *Block, |
| 8761 | 8777 | param_idx: u32, |
| 8762 | 8778 | param_ty: Type, |
| 8779 | param_is_comptime: bool, |
| 8763 | 8780 | param_is_noalias: bool, |
| 8764 | 8781 | param_src: LazySrcLoc, |
| 8765 | 8782 | cc: std.builtin.CallingConvention, |
| ... | ... | @@ -8774,29 +8791,22 @@ fn checkParamTypeCommon( |
| 8774 | 8791 | opaque_str, param_ty.fmt(pt), |
| 8775 | 8792 | }); |
| 8776 | 8793 | } |
| 8777 | | if (!param_ty.isGenericPoison() and |
| 8778 | | !target_util.fnCallConvAllowsZigTypes(cc) and |
| 8779 | | !param_ty.validateExtern(.param_ty, zcu)) |
| 8780 | | { |
| 8781 | | return sema.failWithOwnedErrorMsg(block, msg: { |
| 8782 | | const msg = try sema.errMsg(param_src, "parameter of type '{f}' not allowed in function with calling convention '{s}'", .{ |
| 8783 | | param_ty.fmt(pt), @tagName(cc), |
| 8784 | | }); |
| 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 | | }); |
| 8794 | if (!target_util.fnCallConvAllowsZigTypes(cc)) { |
| 8795 | if (param_is_comptime) { |
| 8796 | return sema.fail(block, param_src, "comptime parameters not allowed in function with calling convention '{t}'", .{cc}); |
| 8797 | } |
| 8798 | if (param_ty.isGenericPoison()) { |
| 8799 | return sema.fail(block, param_src, "generic parameters not allowed in function with calling convention '{t}'", .{cc}); |
| 8800 | } |
| 8801 | // The `validateExtern` check happens later, in `validateResolvedFuncType`. |
| 8792 | 8802 | } |
| 8793 | 8803 | switch (cc) { |
| 8794 | 8804 | .x86_64_interrupt, .x86_interrupt => { |
| 8795 | 8805 | const err_code_size = target.ptrBitWidth(); |
| 8796 | 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)}), |
| 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 }), |
| 8799 | | else => return sema.fail(block, param_src, "'{s}' calling convention supports up to 2 parameters, found {d}", .{ @tagName(cc), param_idx + 1 }), |
| 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}), |
| 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 }), |
| 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 | 8812 | .arc_interrupt, |
| ... | ... | @@ -8812,7 +8822,7 @@ fn checkParamTypeCommon( |
| 8812 | 8822 | .m68k_interrupt, |
| 8813 | 8823 | .msp430_interrupt, |
| 8814 | 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 | 8826 | else => {}, |
| 8817 | 8827 | } |
| 8818 | 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 | 8830 | } |
| 8821 | 8831 | } |
| 8822 | 8832 | |
| 8823 | | fn checkReturnTypeAndCallConvCommon( |
| 8833 | fn checkReturnTypeAndCallConv( |
| 8824 | 8834 | sema: *Sema, |
| 8825 | 8835 | block: *Block, |
| 8826 | 8836 | bare_ret_ty: Type, |
| ... | ... | @@ -8834,7 +8844,6 @@ fn checkReturnTypeAndCallConvCommon( |
| 8834 | 8844 | ) CompileError!void { |
| 8835 | 8845 | const pt = sema.pt; |
| 8836 | 8846 | const zcu = pt.zcu; |
| 8837 | | const gpa = zcu.gpa; |
| 8838 | 8847 | if (opt_varargs_src) |varargs_src| { |
| 8839 | 8848 | try sema.checkCallConvSupportsVarArgs(block, varargs_src, @"callconv"); |
| 8840 | 8849 | } |
| ... | ... | @@ -8848,21 +8857,14 @@ fn checkReturnTypeAndCallConvCommon( |
| 8848 | 8857 | opaque_str, ies_ret_ty_prefix, bare_ret_ty.fmt(pt), |
| 8849 | 8858 | }); |
| 8850 | 8859 | } |
| 8851 | | if (!bare_ret_ty.isGenericPoison() and |
| 8852 | | !target_util.fnCallConvAllowsZigTypes(@"callconv") and |
| 8853 | | (inferred_error_set or !bare_ret_ty.validateExtern(.ret_ty, zcu))) |
| 8854 | | { |
| 8855 | | return sema.failWithOwnedErrorMsg(block, msg: { |
| 8856 | | const msg = try sema.errMsg(ret_ty_src, "return type '{s}{f}' not allowed in function with calling convention '{s}'", .{ |
| 8857 | | ies_ret_ty_prefix, bare_ret_ty.fmt(pt), @tagName(@"callconv"), |
| 8858 | | }); |
| 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 | | }); |
| 8860 | if (!target_util.fnCallConvAllowsZigTypes(@"callconv")) { |
| 8861 | if (inferred_error_set) { |
| 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" }); |
| 8863 | } |
| 8864 | if (bare_ret_ty.isGenericPoison()) { |
| 8865 | return sema.fail(block, ret_ty_src, "generic return type not allowed in function with calling convention '{t}'", .{@"callconv"}); |
| 8866 | } |
| 8867 | // The `validateExtern` check happens later, in `validateResolvedFuncType`. |
| 8866 | 8868 | } |
| 8867 | 8869 | validate_incoming_stack_align: { |
| 8868 | 8870 | const a: u64 = switch (@"callconv") { |
| ... | ... | @@ -8897,7 +8899,7 @@ fn checkReturnTypeAndCallConvCommon( |
| 8897 | 8899 | else => false, |
| 8898 | 8900 | }; |
| 8899 | 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 | 8905 | .@"inline" => if (is_noinline) { |
| ... | ... | @@ -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}", .{ |
| 8922 | | @tagName(@"callconv"), |
| 8923 | | ArchListFormatter{ .archs = allowed_archs }, |
| 8923 | return sema.fail(block, callconv_src, "calling convention '{t}' only available on architectures {f}", .{ |
| 8924 | @"callconv", 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 | | @tagName(@"callconv"), |
| 8928 | | @tagName(bad_backend), |
| 8927 | .bad_backend => |bad_backend| return sema.fail(block, callconv_src, "calling convention '{t}' not supported by compiler backend '{t}'", .{ |
| 8928 | @"callconv", 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 | 8993 | fn callConvIsCallable(cc: std.builtin.CallingConvention.Tag) bool { |
| 8934 | 8994 | return switch (cc) { |
| 8935 | 8995 | .naked, |
| ... | ... | @@ -9022,6 +9082,7 @@ fn funcCommon( |
| 9022 | 9082 | const io = comp.io; |
| 9023 | 9083 | const ip = &zcu.intern_pool; |
| 9024 | 9084 | |
| 9085 | const src = block.nodeOffset(src_node_offset); |
| 9025 | 9086 | const ret_ty_src = block.src(.{ .node_offset_fn_type_ret_ty = src_node_offset }); |
| 9026 | 9087 | const cc_src = block.src(.{ .node_offset_fn_type_cc = src_node_offset }); |
| 9027 | 9088 | |
| ... | ... | @@ -9036,27 +9097,21 @@ fn funcCommon( |
| 9036 | 9097 | .fn_proto_node_offset = src_node_offset, |
| 9037 | 9098 | .param_index = @intCast(i), |
| 9038 | 9099 | } }); |
| 9039 | | const param_ty_generic = param_ty.isGenericPoison(); |
| 9040 | 9100 | if (param_is_comptime) { |
| 9041 | 9101 | comptime_bits |= @as(u32, 1) << @intCast(i); // TODO: handle cast error |
| 9042 | 9102 | } |
| 9043 | | if (param_is_comptime and !target_util.fnCallConvAllowsZigTypes(cc)) { |
| 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( |
| 9103 | try sema.checkParamType( |
| 9050 | 9104 | block, |
| 9051 | 9105 | @intCast(i), |
| 9052 | 9106 | param_ty, |
| 9107 | param_is_comptime, |
| 9053 | 9108 | is_noalias, |
| 9054 | 9109 | param_src, |
| 9055 | 9110 | cc, |
| 9056 | 9111 | ); |
| 9057 | 9112 | } |
| 9058 | 9113 | |
| 9059 | | try sema.checkReturnTypeAndCallConvCommon( |
| 9114 | try sema.checkReturnTypeAndCallConv( |
| 9060 | 9115 | block, |
| 9061 | 9116 | bare_return_type, |
| 9062 | 9117 | ret_ty_src, |
| ... | ... | @@ -9072,9 +9127,29 @@ fn funcCommon( |
| 9072 | 9127 | |
| 9073 | 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 | 9150 | if (inferred_error_set) { |
| 9076 | 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 | 9153 | .owner_nav = sema.owner.unwrap().nav_val, |
| 9079 | 9154 | |
| 9080 | 9155 | .param_types = param_types, |
| ... | ... | @@ -9091,8 +9166,6 @@ fn funcCommon( |
| 9091 | 9166 | .lbrace_column = @as(u16, @truncate(src_locs.columns)), |
| 9092 | 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 | 9171 | const func_ty = try ip.getFuncType(gpa, io, pt.tid, .{ |
| ... | ... | @@ -9106,7 +9179,6 @@ fn funcCommon( |
| 9106 | 9179 | }); |
| 9107 | 9180 | |
| 9108 | 9181 | if (has_body) { |
| 9109 | | try sema.ensureLayoutResolved(.fromInterned(func_ty), ret_ty_src, .return_type); |
| 9110 | 9182 | return .fromIntern(try ip.getFuncDecl(gpa, io, pt.tid, .{ |
| 9111 | 9183 | .owner_nav = sema.owner.unwrap().nav_val, |
| 9112 | 9184 | .ty = func_ty, |
| ... | ... | @@ -18256,19 +18328,6 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 18256 | 18328 | } |
| 18257 | 18329 | } else if (inst_data.size != .one and elem_ty.zigTypeTag(zcu) == .@"opaque") { |
| 18258 | 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 | 18333 | if (host_size != 0) { |
| ... | ... | @@ -19800,16 +19859,6 @@ fn zirReifyPointer( |
| 19800 | 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 | 19862 | const sentinel_ty = try pt.optionalType(elem_ty.toIntern()); |
| 19814 | 19863 | const sentinel_uncoerced = sema.resolveInst(extra.sentinel); |
| 19815 | 19864 | const sentinel_coerced = try sema.coerce(block, sentinel_ty, sentinel_uncoerced, sentinel_src); |
| ... | ... | @@ -19898,10 +19947,11 @@ fn zirReifyFn( |
| 19898 | 19947 | try param_attrs_arr.elemValue(pt, param_idx), |
| 19899 | 19948 | std.builtin.Type.Fn.Param.Attributes, |
| 19900 | 19949 | ); |
| 19901 | | try sema.checkParamTypeCommon( |
| 19950 | try sema.checkParamType( |
| 19902 | 19951 | block, |
| 19903 | 19952 | @intCast(param_idx), |
| 19904 | 19953 | param_ty, |
| 19954 | false, |
| 19905 | 19955 | param_attrs.@"noalias", |
| 19906 | 19956 | param_types_src, |
| 19907 | 19957 | fn_attrs.@"callconv", |
| ... | ... | @@ -19919,7 +19969,7 @@ fn zirReifyFn( |
| 19919 | 19969 | try sema.checkCallConvSupportsVarArgs(block, fn_attrs_src, fn_attrs.@"callconv"); |
| 19920 | 19970 | } |
| 19921 | 19971 | |
| 19922 | | try sema.checkReturnTypeAndCallConvCommon( |
| 19972 | try sema.checkReturnTypeAndCallConv( |
| 19923 | 19973 | block, |
| 19924 | 19974 | ret_ty, |
| 19925 | 19975 | ret_ty_src, |
| ... | ... | @@ -19929,9 +19979,6 @@ fn zirReifyFn( |
| 19929 | 19979 | false, |
| 19930 | 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 | 19983 | return .fromIntern(try ip.getFuncType(gpa, io, pt.tid, .{ |
| 19937 | 19984 | .param_types = param_types_ip, |
| ... | ... | @@ -20615,7 +20662,7 @@ fn zirCVaArg(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) C |
| 20615 | 20662 | |
| 20616 | 20663 | const va_list_ref = try sema.resolveVaListRef(block, va_list_src, extra.lhs); |
| 20617 | 20664 | const arg_ty = try sema.resolveType(block, ty_src, extra.rhs); |
| 20618 | | |
| 20665 | try sema.ensureLayoutResolved(arg_ty, ty_src, .parameter); |
| 20619 | 20666 | if (!arg_ty.validateExtern(.param_ty, sema.pt.zcu)) { |
| 20620 | 20667 | const msg = msg: { |
| 20621 | 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 | 24686 | return sema.fail(block, ty_src, "expected (optional) pointer", .{}); |
| 24640 | 24687 | } |
| 24641 | 24688 | if (!ty.validateExtern(.other, zcu)) { |
| 24642 | | const msg = msg: { |
| 24689 | return sema.failWithOwnedErrorMsg(block, msg: { |
| 24643 | 24690 | const msg = try sema.errMsg(ty_src, "extern symbol cannot have type '{f}'", .{ty.fmt(pt)}); |
| 24644 | 24691 | errdefer msg.destroy(sema.gpa); |
| 24645 | 24692 | try sema.explainWhyTypeIsNotExtern(msg, ty_src, ty, .other); |
| 24646 | 24693 | break :msg msg; |
| 24647 | | }; |
| 24648 | | return sema.failWithOwnedErrorMsg(block, msg); |
| 24694 | }); |
| 24649 | 24695 | } |
| 24650 | 24696 | |
| 24651 | 24697 | const options = try sema.resolveExternOptions(block, options_src, extra.rhs); |
| ... | ... | @@ -25034,7 +25080,7 @@ pub fn explainWhyTypeIsNotExtern( |
| 25034 | 25080 | src_loc: LazySrcLoc, |
| 25035 | 25081 | ty: Type, |
| 25036 | 25082 | position: Type.ExternPosition, |
| 25037 | | ) CompileError!void { |
| 25083 | ) SemaError!void { |
| 25038 | 25084 | const pt = sema.pt; |
| 25039 | 25085 | const zcu = pt.zcu; |
| 25040 | 25086 | switch (ty.zigTypeTag(zcu)) { |