| ... | @@ -5049,13 +5049,13 @@ pub fn analyzeExport( | ... | @@ -5049,13 +5049,13 @@ pub fn analyzeExport( |
| 5049 | try mod.ensureDeclAnalyzed(exported_decl_index); | 5049 | try mod.ensureDeclAnalyzed(exported_decl_index); |
| 5050 | const exported_decl = mod.declPtr(exported_decl_index); | 5050 | const exported_decl = mod.declPtr(exported_decl_index); |
| 5051 | | 5051 | |
| 5052 | if (!(try sema.validateExternType(exported_decl.ty, .other))) { | 5052 | if (!sema.validateExternType(exported_decl.ty, .other)) { |
| 5053 | const msg = msg: { | 5053 | const msg = msg: { |
| 5054 | const msg = try sema.errMsg(block, src, "unable to export type '{}'", .{exported_decl.ty.fmt(sema.mod)}); | 5054 | const msg = try sema.errMsg(block, src, "unable to export type '{}'", .{exported_decl.ty.fmt(sema.mod)}); |
| 5055 | errdefer msg.destroy(sema.gpa); | 5055 | errdefer msg.destroy(sema.gpa); |
| 5056 | | 5056 | |
| 5057 | const src_decl = sema.mod.declPtr(block.src_decl); | 5057 | const src_decl = sema.mod.declPtr(block.src_decl); |
| 5058 | try sema.explainWhyTypeIsNotExtern(block, src, msg, src.toSrcLoc(src_decl), exported_decl.ty, .other); | 5058 | try sema.explainWhyTypeIsNotExtern(msg, src.toSrcLoc(src_decl), exported_decl.ty, .other); |
| 5059 | | 5059 | |
| 5060 | try sema.addDeclaredHereNote(msg, exported_decl.ty); | 5060 | try sema.addDeclaredHereNote(msg, exported_decl.ty); |
| 5061 | break :msg msg; | 5061 | break :msg msg; |
| ... | @@ -7634,7 +7634,7 @@ fn funcCommon( | ... | @@ -7634,7 +7634,7 @@ fn funcCommon( |
| 7634 | }; | 7634 | }; |
| 7635 | return sema.failWithOwnedErrorMsg(block, msg); | 7635 | return sema.failWithOwnedErrorMsg(block, msg); |
| 7636 | } | 7636 | } |
| 7637 | if (!Type.fnCallingConventionAllowsZigTypes(cc_workaround) and !(try sema.validateExternType(return_type, .ret_ty))) { | 7637 | if (!Type.fnCallingConventionAllowsZigTypes(cc_workaround) and !sema.validateExternType(return_type, .ret_ty)) { |
| 7638 | const msg = msg: { | 7638 | const msg = msg: { |
| 7639 | const msg = try sema.errMsg(block, ret_ty_src, "return type '{}' not allowed in function with calling convention '{s}'", .{ | 7639 | const msg = try sema.errMsg(block, ret_ty_src, "return type '{}' not allowed in function with calling convention '{s}'", .{ |
| 7640 | return_type.fmt(sema.mod), @tagName(cc_workaround), | 7640 | return_type.fmt(sema.mod), @tagName(cc_workaround), |
| ... | @@ -7642,7 +7642,7 @@ fn funcCommon( | ... | @@ -7642,7 +7642,7 @@ fn funcCommon( |
| 7642 | errdefer msg.destroy(sema.gpa); | 7642 | errdefer msg.destroy(sema.gpa); |
| 7643 | | 7643 | |
| 7644 | const src_decl = sema.mod.declPtr(block.src_decl); | 7644 | const src_decl = sema.mod.declPtr(block.src_decl); |
| 7645 | try sema.explainWhyTypeIsNotExtern(block, ret_ty_src, msg, ret_ty_src.toSrcLoc(src_decl), return_type, .ret_ty); | 7645 | try sema.explainWhyTypeIsNotExtern(msg, ret_ty_src.toSrcLoc(src_decl), return_type, .ret_ty); |
| 7646 | | 7646 | |
| 7647 | try sema.addDeclaredHereNote(msg, return_type); | 7647 | try sema.addDeclaredHereNote(msg, return_type); |
| 7648 | break :msg msg; | 7648 | break :msg msg; |
| ... | @@ -7830,7 +7830,7 @@ fn analyzeParameter( | ... | @@ -7830,7 +7830,7 @@ fn analyzeParameter( |
| 7830 | }; | 7830 | }; |
| 7831 | return sema.failWithOwnedErrorMsg(block, msg); | 7831 | return sema.failWithOwnedErrorMsg(block, msg); |
| 7832 | } | 7832 | } |
| 7833 | if (!Type.fnCallingConventionAllowsZigTypes(cc) and !(try sema.validateExternType(param.ty, .param_ty))) { | 7833 | if (!Type.fnCallingConventionAllowsZigTypes(cc) and !sema.validateExternType(param.ty, .param_ty)) { |
| 7834 | const msg = msg: { | 7834 | const msg = msg: { |
| 7835 | const msg = try sema.errMsg(block, param_src, "parameter of type '{}' not allowed in function with calling convention '{s}'", .{ | 7835 | const msg = try sema.errMsg(block, param_src, "parameter of type '{}' not allowed in function with calling convention '{s}'", .{ |
| 7836 | param.ty.fmt(sema.mod), @tagName(cc), | 7836 | param.ty.fmt(sema.mod), @tagName(cc), |
| ... | @@ -7838,7 +7838,7 @@ fn analyzeParameter( | ... | @@ -7838,7 +7838,7 @@ fn analyzeParameter( |
| 7838 | errdefer msg.destroy(sema.gpa); | 7838 | errdefer msg.destroy(sema.gpa); |
| 7839 | | 7839 | |
| 7840 | const src_decl = sema.mod.declPtr(block.src_decl); | 7840 | const src_decl = sema.mod.declPtr(block.src_decl); |
| 7841 | try sema.explainWhyTypeIsNotExtern(block, param_src, msg, param_src.toSrcLoc(src_decl), param.ty, .param_ty); | 7841 | try sema.explainWhyTypeIsNotExtern(msg, param_src.toSrcLoc(src_decl), param.ty, .param_ty); |
| 7842 | | 7842 | |
| 7843 | try sema.addDeclaredHereNote(msg, param.ty); | 7843 | try sema.addDeclaredHereNote(msg, param.ty); |
| 7844 | break :msg msg; | 7844 | break :msg msg; |
| ... | @@ -14866,13 +14866,13 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air | ... | @@ -14866,13 +14866,13 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 14866 | } else if (inst_data.size == .Many and elem_ty.zigTypeTag() == .Opaque) { | 14866 | } else if (inst_data.size == .Many and elem_ty.zigTypeTag() == .Opaque) { |
| 14867 | return sema.fail(block, elem_ty_src, "unknown-length pointer to opaque not allowed", .{}); | 14867 | return sema.fail(block, elem_ty_src, "unknown-length pointer to opaque not allowed", .{}); |
| 14868 | } else if (inst_data.size == .C) { | 14868 | } else if (inst_data.size == .C) { |
| 14869 | if (!(try sema.validateExternType(elem_ty, .other))) { | 14869 | if (!sema.validateExternType(elem_ty, .other)) { |
| 14870 | const msg = msg: { | 14870 | const msg = msg: { |
| 14871 | const msg = try sema.errMsg(block, elem_ty_src, "C pointers cannot point to non-C-ABI-compatible type '{}'", .{elem_ty.fmt(sema.mod)}); | 14871 | const msg = try sema.errMsg(block, elem_ty_src, "C pointers cannot point to non-C-ABI-compatible type '{}'", .{elem_ty.fmt(sema.mod)}); |
| 14872 | errdefer msg.destroy(sema.gpa); | 14872 | errdefer msg.destroy(sema.gpa); |
| 14873 | | 14873 | |
| 14874 | const src_decl = sema.mod.declPtr(block.src_decl); | 14874 | const src_decl = sema.mod.declPtr(block.src_decl); |
| 14875 | try sema.explainWhyTypeIsNotExtern(block, elem_ty_src, msg, elem_ty_src.toSrcLoc(src_decl), elem_ty, .other); | 14875 | try sema.explainWhyTypeIsNotExtern(msg, elem_ty_src.toSrcLoc(src_decl), elem_ty, .other); |
| 14876 | | 14876 | |
| 14877 | try sema.addDeclaredHereNote(msg, elem_ty); | 14877 | try sema.addDeclaredHereNote(msg, elem_ty); |
| 14878 | break :msg msg; | 14878 | break :msg msg; |
| ... | @@ -15950,13 +15950,13 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I | ... | @@ -15950,13 +15950,13 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I |
| 15950 | } else if (ptr_size == .Many and elem_ty.zigTypeTag() == .Opaque) { | 15950 | } else if (ptr_size == .Many and elem_ty.zigTypeTag() == .Opaque) { |
| 15951 | return sema.fail(block, src, "unknown-length pointer to opaque not allowed", .{}); | 15951 | return sema.fail(block, src, "unknown-length pointer to opaque not allowed", .{}); |
| 15952 | } else if (ptr_size == .C) { | 15952 | } else if (ptr_size == .C) { |
| 15953 | if (!(try sema.validateExternType(elem_ty, .other))) { | 15953 | if (!sema.validateExternType(elem_ty, .other)) { |
| 15954 | const msg = msg: { | 15954 | const msg = msg: { |
| 15955 | const msg = try sema.errMsg(block, src, "C pointers cannot point to non-C-ABI-compatible type '{}'", .{elem_ty.fmt(sema.mod)}); | 15955 | const msg = try sema.errMsg(block, src, "C pointers cannot point to non-C-ABI-compatible type '{}'", .{elem_ty.fmt(sema.mod)}); |
| 15956 | errdefer msg.destroy(sema.gpa); | 15956 | errdefer msg.destroy(sema.gpa); |
| 15957 | | 15957 | |
| 15958 | const src_decl = sema.mod.declPtr(block.src_decl); | 15958 | const src_decl = sema.mod.declPtr(block.src_decl); |
| 15959 | try sema.explainWhyTypeIsNotExtern(block, src, msg, src.toSrcLoc(src_decl), elem_ty, .other); | 15959 | try sema.explainWhyTypeIsNotExtern(msg, src.toSrcLoc(src_decl), elem_ty, .other); |
| 15960 | | 15960 | |
| 15961 | try sema.addDeclaredHereNote(msg, elem_ty); | 15961 | try sema.addDeclaredHereNote(msg, elem_ty); |
| 15962 | break :msg msg; | 15962 | break :msg msg; |
| ... | @@ -19736,7 +19736,7 @@ const ExternPosition = enum { | ... | @@ -19736,7 +19736,7 @@ const ExternPosition = enum { |
| 19736 | | 19736 | |
| 19737 | /// Returns true if `ty` is allowed in extern types. | 19737 | /// Returns true if `ty` is allowed in extern types. |
| 19738 | /// Does *NOT* require `ty` to be resolved in any way. | 19738 | /// Does *NOT* require `ty` to be resolved in any way. |
| 19739 | fn validateExternType(sema: *Sema, ty: Type, position: ExternPosition) CompileError!bool { | 19739 | fn validateExternType(sema: *Sema, ty: Type, position: ExternPosition) bool { |
| 19740 | switch (ty.zigTypeTag()) { | 19740 | switch (ty.zigTypeTag()) { |
| 19741 | .Type, | 19741 | .Type, |
| 19742 | .ComptimeFloat, | 19742 | .ComptimeFloat, |
| ... | @@ -19781,8 +19781,6 @@ fn validateExternType(sema: *Sema, ty: Type, position: ExternPosition) CompileEr | ... | @@ -19781,8 +19781,6 @@ fn validateExternType(sema: *Sema, ty: Type, position: ExternPosition) CompileEr |
| 19781 | | 19781 | |
| 19782 | fn explainWhyTypeIsNotExtern( | 19782 | fn explainWhyTypeIsNotExtern( |
| 19783 | sema: *Sema, | 19783 | sema: *Sema, |
| 19784 | block: *Block, | | |
| 19785 | src: LazySrcLoc, | | |
| 19786 | msg: *Module.ErrorMsg, | 19784 | msg: *Module.ErrorMsg, |
| 19787 | src_loc: Module.SrcLoc, | 19785 | src_loc: Module.SrcLoc, |
| 19788 | ty: Type, | 19786 | ty: Type, |
| ... | @@ -19826,7 +19824,7 @@ fn explainWhyTypeIsNotExtern( | ... | @@ -19826,7 +19824,7 @@ fn explainWhyTypeIsNotExtern( |
| 19826 | var buf: Type.Payload.Bits = undefined; | 19824 | var buf: Type.Payload.Bits = undefined; |
| 19827 | const tag_ty = ty.intTagType(&buf); | 19825 | const tag_ty = ty.intTagType(&buf); |
| 19828 | try mod.errNoteNonLazy(src_loc, msg, "enum tag type '{}' is not extern compatible", .{tag_ty.fmt(sema.mod)}); | 19826 | try mod.errNoteNonLazy(src_loc, msg, "enum tag type '{}' is not extern compatible", .{tag_ty.fmt(sema.mod)}); |
| 19829 | try sema.explainWhyTypeIsNotExtern(block, src, msg, src_loc, tag_ty, position); | 19827 | try sema.explainWhyTypeIsNotExtern(msg, src_loc, tag_ty, position); |
| 19830 | }, | 19828 | }, |
| 19831 | .Struct => try mod.errNoteNonLazy(src_loc, msg, "only structs with packed or extern layout are extern compatible", .{}), | 19829 | .Struct => try mod.errNoteNonLazy(src_loc, msg, "only structs with packed or extern layout are extern compatible", .{}), |
| 19832 | .Union => try mod.errNoteNonLazy(src_loc, msg, "only unions with packed or extern layout are extern compatible", .{}), | 19830 | .Union => try mod.errNoteNonLazy(src_loc, msg, "only unions with packed or extern layout are extern compatible", .{}), |
| ... | @@ -19836,13 +19834,87 @@ fn explainWhyTypeIsNotExtern( | ... | @@ -19836,13 +19834,87 @@ fn explainWhyTypeIsNotExtern( |
| 19836 | } else if (position == .param_ty) { | 19834 | } else if (position == .param_ty) { |
| 19837 | return mod.errNoteNonLazy(src_loc, msg, "arrays are not allowed as a parameter type", .{}); | 19835 | return mod.errNoteNonLazy(src_loc, msg, "arrays are not allowed as a parameter type", .{}); |
| 19838 | } | 19836 | } |
| 19839 | try sema.explainWhyTypeIsNotExtern(block, src, msg, src_loc, ty.elemType2(), position); | 19837 | try sema.explainWhyTypeIsNotExtern(msg, src_loc, ty.elemType2(), position); |
| 19840 | }, | 19838 | }, |
| 19841 | .Vector => try sema.explainWhyTypeIsNotExtern(block, src, msg, src_loc, ty.elemType2(), position), | 19839 | .Vector => try sema.explainWhyTypeIsNotExtern(msg, src_loc, ty.elemType2(), position), |
| 19842 | .Optional => try mod.errNoteNonLazy(src_loc, msg, "only pointer like optionals are extern compatible", .{}), | 19840 | .Optional => try mod.errNoteNonLazy(src_loc, msg, "only pointer like optionals are extern compatible", .{}), |
| 19843 | } | 19841 | } |
| 19844 | } | 19842 | } |
| 19845 | | 19843 | |
| | 19844 | /// Returns true if `ty` is allowed in packed types. |
| | 19845 | /// Does *NOT* require `ty` to be resolved in any way. |
| | 19846 | fn validatePackedType(ty: Type) bool { |
| | 19847 | switch (ty.zigTypeTag()) { |
| | 19848 | .Type, |
| | 19849 | .ComptimeFloat, |
| | 19850 | .ComptimeInt, |
| | 19851 | .EnumLiteral, |
| | 19852 | .Undefined, |
| | 19853 | .Null, |
| | 19854 | .ErrorUnion, |
| | 19855 | .ErrorSet, |
| | 19856 | .BoundFn, |
| | 19857 | .Frame, |
| | 19858 | .NoReturn, |
| | 19859 | .Opaque, |
| | 19860 | .AnyFrame, |
| | 19861 | .Fn, |
| | 19862 | .Array, |
| | 19863 | .Optional, |
| | 19864 | => return false, |
| | 19865 | .Void, |
| | 19866 | .Bool, |
| | 19867 | .Float, |
| | 19868 | .Pointer, |
| | 19869 | .Int, |
| | 19870 | .Vector, |
| | 19871 | .Enum, |
| | 19872 | => return true, |
| | 19873 | .Struct, .Union => return ty.containerLayout() == .Packed, |
| | 19874 | } |
| | 19875 | } |
| | 19876 | |
| | 19877 | fn explainWhyTypeIsNotPacked( |
| | 19878 | sema: *Sema, |
| | 19879 | msg: *Module.ErrorMsg, |
| | 19880 | src_loc: Module.SrcLoc, |
| | 19881 | ty: Type, |
| | 19882 | ) CompileError!void { |
| | 19883 | const mod = sema.mod; |
| | 19884 | switch (ty.zigTypeTag()) { |
| | 19885 | .Void, |
| | 19886 | .Bool, |
| | 19887 | .Float, |
| | 19888 | .Pointer, |
| | 19889 | .Int, |
| | 19890 | .Vector, |
| | 19891 | .Enum, |
| | 19892 | => return, |
| | 19893 | .Type, |
| | 19894 | .ComptimeFloat, |
| | 19895 | .ComptimeInt, |
| | 19896 | .EnumLiteral, |
| | 19897 | .Undefined, |
| | 19898 | .Null, |
| | 19899 | .BoundFn, |
| | 19900 | .Frame, |
| | 19901 | .NoReturn, |
| | 19902 | .Opaque, |
| | 19903 | .ErrorUnion, |
| | 19904 | .ErrorSet, |
| | 19905 | .AnyFrame, |
| | 19906 | .Optional, |
| | 19907 | .Array, |
| | 19908 | => try mod.errNoteNonLazy(src_loc, msg, "type has no guaranteed in-memory representation", .{}), |
| | 19909 | .Fn => { |
| | 19910 | try mod.errNoteNonLazy(src_loc, msg, "type has no guaranteed in-memory representation", .{}); |
| | 19911 | try mod.errNoteNonLazy(src_loc, msg, "use '*const ' to make a function pointer type", .{}); |
| | 19912 | }, |
| | 19913 | .Struct => try mod.errNoteNonLazy(src_loc, msg, "only packed structs layout are allowed in packed types", .{}), |
| | 19914 | .Union => try mod.errNoteNonLazy(src_loc, msg, "only packed unions layout are allowed in packed types", .{}), |
| | 19915 | } |
| | 19916 | } |
| | 19917 | |
| 19846 | pub const PanicId = enum { | 19918 | pub const PanicId = enum { |
| 19847 | unreach, | 19919 | unreach, |
| 19848 | unwrap_null, | 19920 | unwrap_null, |
| ... | @@ -26919,28 +26991,41 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void | ... | @@ -26919,28 +26991,41 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void |
| 26919 | const field = &struct_obj.fields.values()[i]; | 26991 | const field = &struct_obj.fields.values()[i]; |
| 26920 | field.ty = try field_ty.copy(decl_arena_allocator); | 26992 | field.ty = try field_ty.copy(decl_arena_allocator); |
| 26921 | | 26993 | |
| 26922 | if (struct_obj.layout == .Extern and !(try sema.validateExternType(field.ty, .other))) { | 26994 | if (field_ty.zigTypeTag() == .Opaque) { |
| | 26995 | const msg = msg: { |
| | 26996 | const tree = try sema.getAstTree(&block_scope); |
| | 26997 | const field_src = enumFieldSrcLoc(decl, tree.*, struct_obj.node_offset, i); |
| | 26998 | const msg = try sema.errMsg(&block_scope, field_src, "opaque types have unknown size and therefore cannot be directly embedded in structs", .{}); |
| | 26999 | errdefer msg.destroy(sema.gpa); |
| | 27000 | |
| | 27001 | try sema.addDeclaredHereNote(msg, field_ty); |
| | 27002 | break :msg msg; |
| | 27003 | }; |
| | 27004 | return sema.failWithOwnedErrorMsg(&block_scope, msg); |
| | 27005 | } |
| | 27006 | if (struct_obj.layout == .Extern and !sema.validateExternType(field.ty, .other)) { |
| 26923 | const msg = msg: { | 27007 | const msg = msg: { |
| 26924 | const tree = try sema.getAstTree(&block_scope); | 27008 | const tree = try sema.getAstTree(&block_scope); |
| 26925 | const fields_src = enumFieldSrcLoc(decl, tree.*, struct_obj.node_offset, i); | 27009 | const fields_src = enumFieldSrcLoc(decl, tree.*, struct_obj.node_offset, i); |
| 26926 | const msg = try sema.errMsg(&block_scope, fields_src, "extern structs cannot contain fields of type '{}'", .{field.ty.fmt(sema.mod)}); | 27010 | const msg = try sema.errMsg(&block_scope, fields_src, "extern structs cannot contain fields of type '{}'", .{field.ty.fmt(sema.mod)}); |
| 26927 | errdefer msg.destroy(sema.gpa); | 27011 | errdefer msg.destroy(sema.gpa); |
| 26928 | | 27012 | |
| 26929 | try sema.explainWhyTypeIsNotExtern(&block_scope, fields_src, msg, fields_src.toSrcLoc(decl), field.ty, .other); | 27013 | try sema.explainWhyTypeIsNotExtern(msg, fields_src.toSrcLoc(decl), field.ty, .other); |
| 26930 | | 27014 | |
| 26931 | try sema.addDeclaredHereNote(msg, field.ty); | 27015 | try sema.addDeclaredHereNote(msg, field.ty); |
| 26932 | break :msg msg; | 27016 | break :msg msg; |
| 26933 | }; | 27017 | }; |
| 26934 | return sema.failWithOwnedErrorMsg(&block_scope, msg); | 27018 | return sema.failWithOwnedErrorMsg(&block_scope, msg); |
| 26935 | } | 27019 | } else if (struct_obj.layout == .Packed and !(validatePackedType(field.ty))) { |
| 26936 | if (field_ty.zigTypeTag() == .Opaque) { | | |
| 26937 | const msg = msg: { | 27020 | const msg = msg: { |
| 26938 | const tree = try sema.getAstTree(&block_scope); | 27021 | const tree = try sema.getAstTree(&block_scope); |
| 26939 | const field_src = enumFieldSrcLoc(decl, tree.*, struct_obj.node_offset, i); | 27022 | const fields_src = enumFieldSrcLoc(decl, tree.*, struct_obj.node_offset, i); |
| 26940 | const msg = try sema.errMsg(&block_scope, field_src, "opaque types have unknown size and therefore cannot be directly embedded in structs", .{}); | 27023 | const msg = try sema.errMsg(&block_scope, fields_src, "packed structs cannot contain fields of type '{}'", .{field.ty.fmt(sema.mod)}); |
| 26941 | errdefer msg.destroy(sema.gpa); | 27024 | errdefer msg.destroy(sema.gpa); |
| 26942 | | 27025 | |
| 26943 | try sema.addDeclaredHereNote(msg, field_ty); | 27026 | try sema.explainWhyTypeIsNotPacked(msg, fields_src.toSrcLoc(decl), field.ty); |
| | 27027 | |
| | 27028 | try sema.addDeclaredHereNote(msg, field.ty); |
| 26944 | break :msg msg; | 27029 | break :msg msg; |
| 26945 | }; | 27030 | }; |
| 26946 | return sema.failWithOwnedErrorMsg(&block_scope, msg); | 27031 | return sema.failWithOwnedErrorMsg(&block_scope, msg); |
| ... | @@ -27243,27 +27328,40 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void { | ... | @@ -27243,27 +27328,40 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void { |
| 27243 | } | 27328 | } |
| 27244 | } | 27329 | } |
| 27245 | | 27330 | |
| 27246 | if (union_obj.layout == .Extern and !(try sema.validateExternType(field_ty, .union_field))) { | 27331 | if (field_ty.zigTypeTag() == .Opaque) { |
| 27247 | const msg = msg: { | 27332 | const msg = msg: { |
| 27248 | const tree = try sema.getAstTree(&block_scope); | 27333 | const tree = try sema.getAstTree(&block_scope); |
| 27249 | const field_src = enumFieldSrcLoc(decl, tree.*, union_obj.node_offset, field_i); | 27334 | const field_src = enumFieldSrcLoc(decl, tree.*, union_obj.node_offset, field_i); |
| 27250 | const msg = try sema.errMsg(&block_scope, field_src, "extern unions cannot contain fields of type '{}'", .{field_ty.fmt(sema.mod)}); | 27335 | const msg = try sema.errMsg(&block_scope, field_src, "opaque types have unknown size and therefore cannot be directly embedded in unions", .{}); |
| 27251 | errdefer msg.destroy(sema.gpa); | 27336 | errdefer msg.destroy(sema.gpa); |
| 27252 | | 27337 | |
| 27253 | try sema.explainWhyTypeIsNotExtern(&block_scope, field_src, msg, field_src.toSrcLoc(decl), field_ty, .union_field); | | |
| 27254 | | | |
| 27255 | try sema.addDeclaredHereNote(msg, field_ty); | 27338 | try sema.addDeclaredHereNote(msg, field_ty); |
| 27256 | break :msg msg; | 27339 | break :msg msg; |
| 27257 | }; | 27340 | }; |
| 27258 | return sema.failWithOwnedErrorMsg(&block_scope, msg); | 27341 | return sema.failWithOwnedErrorMsg(&block_scope, msg); |
| 27259 | } | 27342 | } |
| 27260 | if (field_ty.zigTypeTag() == .Opaque) { | 27343 | if (union_obj.layout == .Extern and !sema.validateExternType(field_ty, .union_field)) { |
| 27261 | const msg = msg: { | 27344 | const msg = msg: { |
| 27262 | const tree = try sema.getAstTree(&block_scope); | 27345 | const tree = try sema.getAstTree(&block_scope); |
| 27263 | const field_src = enumFieldSrcLoc(decl, tree.*, union_obj.node_offset, field_i); | 27346 | const field_src = enumFieldSrcLoc(decl, tree.*, union_obj.node_offset, field_i); |
| 27264 | const msg = try sema.errMsg(&block_scope, field_src, "opaque types have unknown size and therefore cannot be directly embedded in unions", .{}); | 27347 | const msg = try sema.errMsg(&block_scope, field_src, "extern unions cannot contain fields of type '{}'", .{field_ty.fmt(sema.mod)}); |
| 27265 | errdefer msg.destroy(sema.gpa); | 27348 | errdefer msg.destroy(sema.gpa); |
| 27266 | | 27349 | |
| | 27350 | try sema.explainWhyTypeIsNotExtern(msg, field_src.toSrcLoc(decl), field_ty, .union_field); |
| | 27351 | |
| | 27352 | try sema.addDeclaredHereNote(msg, field_ty); |
| | 27353 | break :msg msg; |
| | 27354 | }; |
| | 27355 | return sema.failWithOwnedErrorMsg(&block_scope, msg); |
| | 27356 | } else if (union_obj.layout == .Packed and !(validatePackedType(field_ty))) { |
| | 27357 | const msg = msg: { |
| | 27358 | const tree = try sema.getAstTree(&block_scope); |
| | 27359 | const fields_src = enumFieldSrcLoc(decl, tree.*, union_obj.node_offset, field_i); |
| | 27360 | const msg = try sema.errMsg(&block_scope, fields_src, "packed unions cannot contain fields of type '{}'", .{field_ty.fmt(sema.mod)}); |
| | 27361 | errdefer msg.destroy(sema.gpa); |
| | 27362 | |
| | 27363 | try sema.explainWhyTypeIsNotPacked(msg, fields_src.toSrcLoc(decl), field_ty); |
| | 27364 | |
| 27267 | try sema.addDeclaredHereNote(msg, field_ty); | 27365 | try sema.addDeclaredHereNote(msg, field_ty); |
| 27268 | break :msg msg; | 27366 | break :msg msg; |
| 27269 | }; | 27367 | }; |