| author | |
| committer | |
| log | dc815e5e8f194a03988624a6bf7e739ddfe0d3b4 |
| tree | b464bf4b82f344c7b20cf9af212b95c0a42bc893 |
| parent | 8b3f15f21824e77e776336d8be5832502946621b |
| parent | 122c76a1670e4b925ccdabaa771f59e5df6d43aa |
| signature |
Stage2 validate extern types19 files changed, 313 insertions(+), 116 deletions(-)
lib/compiler_rt/multi3.zig+2-2| ... | ... | @@ -59,12 +59,12 @@ const twords = extern union { |
| 59 | 59 | s: S, |
| 60 | 60 | |
| 61 | 61 | const S = if (native_endian == .Little) |
| 62 | struct { | |
| 62 | extern struct { | |
| 63 | 63 | low: u64, |
| 64 | 64 | high: u64, |
| 65 | 65 | } |
| 66 | 66 | else |
| 67 | struct { | |
| 67 | extern struct { | |
| 68 | 68 | high: u64, |
| 69 | 69 | low: u64, |
| 70 | 70 | }; |
lib/compiler_rt/shift.zig+2-2| ... | ... | @@ -31,9 +31,9 @@ fn Dwords(comptime T: type, comptime signed_half: bool) type { |
| 31 | 31 | |
| 32 | 32 | all: T, |
| 33 | 33 | s: if (native_endian == .Little) |
| 34 | struct { low: HalfT, high: HalfT } | |
| 34 | extern struct { low: HalfT, high: HalfT } | |
| 35 | 35 | else |
| 36 | struct { high: HalfT, low: HalfT }, | |
| 36 | extern struct { high: HalfT, low: HalfT }, | |
| 37 | 37 | }; |
| 38 | 38 | } |
| 39 | 39 |
lib/std/c/haiku.zig+2-2| ... | ... | @@ -30,8 +30,8 @@ pub extern "c" fn _kern_get_current_team() i32; |
| 30 | 30 | pub const sem_t = extern struct { |
| 31 | 31 | type: i32, |
| 32 | 32 | u: extern union { |
| 33 | named_sem_id: ?i32, | |
| 34 | unnamed_sem: ?i32, | |
| 33 | named_sem_id: i32, | |
| 34 | unnamed_sem: i32, | |
| 35 | 35 | }, |
| 36 | 36 | padding: [2]i32, |
| 37 | 37 | }; |
lib/std/start.zig+1-1| ... | ... | @@ -108,7 +108,7 @@ fn callMain2() noreturn { |
| 108 | 108 | exit2(0); |
| 109 | 109 | } |
| 110 | 110 | |
| 111 | fn wasiMain2() noreturn { | |
| 111 | fn wasiMain2() callconv(.C) noreturn { | |
| 112 | 112 | switch (@typeInfo(@typeInfo(@TypeOf(root.main)).Fn.return_type.?)) { |
| 113 | 113 | .Void => { |
| 114 | 114 | root.main(); |
src/Sema.zig+177-9| ... | ... | @@ -4740,12 +4740,19 @@ pub fn analyzeExport( |
| 4740 | 4740 | |
| 4741 | 4741 | try mod.ensureDeclAnalyzed(exported_decl_index); |
| 4742 | 4742 | const exported_decl = mod.declPtr(exported_decl_index); |
| 4743 | // TODO run the same checks as we do for C ABI struct fields | |
| 4744 | switch (exported_decl.ty.zigTypeTag()) { | |
| 4745 | .Fn, .Int, .Enum, .Struct, .Union, .Array, .Float, .Pointer, .Optional => {}, | |
| 4746 | else => return sema.fail(block, src, "unable to export type '{}'", .{ | |
| 4747 | exported_decl.ty.fmt(sema.mod), | |
| 4748 | }), | |
| 4743 | ||
| 4744 | if (!(try sema.validateExternType(exported_decl.ty, .other))) { | |
| 4745 | const msg = msg: { | |
| 4746 | const msg = try sema.errMsg(block, src, "unable to export type '{}'", .{exported_decl.ty.fmt(sema.mod)}); | |
| 4747 | errdefer msg.destroy(sema.gpa); | |
| 4748 | ||
| 4749 | const src_decl = sema.mod.declPtr(block.src_decl); | |
| 4750 | try sema.explainWhyTypeIsNotExtern(block, src, msg, src.toSrcLoc(src_decl), exported_decl.ty, .other); | |
| 4751 | ||
| 4752 | try sema.addDeclaredHereNote(msg, exported_decl.ty); | |
| 4753 | break :msg msg; | |
| 4754 | }; | |
| 4755 | return sema.failWithOwnedErrorMsg(block, msg); | |
| 4749 | 4756 | } |
| 4750 | 4757 | |
| 4751 | 4758 | const gpa = mod.gpa; |
| ... | ... | @@ -13799,7 +13806,20 @@ fn validatePtrTy(sema: *Sema, block: *Block, elem_src: LazySrcLoc, ty: Type) Com |
| 13799 | 13806 | } else if (ptr_info.size == .Many and pointee_tag == .Opaque) { |
| 13800 | 13807 | return sema.fail(block, elem_src, "unknown-length pointer to opaque not allowed", .{}); |
| 13801 | 13808 | } else if (ptr_info.size == .C) { |
| 13802 | // TODO check extern type | |
| 13809 | const elem_ty = ptr_info.pointee_type; | |
| 13810 | if (!(try sema.validateExternType(elem_ty, .other))) { | |
| 13811 | const msg = msg: { | |
| 13812 | const msg = try sema.errMsg(block, elem_src, "C pointers cannot point to non-C-ABI-compatible type '{}'", .{elem_ty.fmt(sema.mod)}); | |
| 13813 | errdefer msg.destroy(sema.gpa); | |
| 13814 | ||
| 13815 | const src_decl = sema.mod.declPtr(block.src_decl); | |
| 13816 | try sema.explainWhyTypeIsNotExtern(block, elem_src, msg, elem_src.toSrcLoc(src_decl), elem_ty, .other); | |
| 13817 | ||
| 13818 | try sema.addDeclaredHereNote(msg, elem_ty); | |
| 13819 | break :msg msg; | |
| 13820 | }; | |
| 13821 | return sema.failWithOwnedErrorMsg(block, msg); | |
| 13822 | } | |
| 13803 | 13823 | if (pointee_tag == .Opaque) { |
| 13804 | 13824 | return sema.fail(block, elem_src, "C pointers cannot point to opaque types", .{}); |
| 13805 | 13825 | } |
| ... | ... | @@ -18098,10 +18118,12 @@ fn explainWhyTypeIsComptime( |
| 18098 | 18118 | .NoReturn, |
| 18099 | 18119 | .Undefined, |
| 18100 | 18120 | .Null, |
| 18101 | .Opaque, | |
| 18102 | .Optional, | |
| 18103 | 18121 | => return, |
| 18104 | 18122 | |
| 18123 | .Opaque => { | |
| 18124 | try mod.errNoteNonLazy(src_loc, msg, "opaque type '{}' has undefined size", .{ty.fmt(sema.mod)}); | |
| 18125 | }, | |
| 18126 | ||
| 18105 | 18127 | .Array, .Vector => { |
| 18106 | 18128 | try sema.explainWhyTypeIsComptime(block, src, msg, src_loc, ty.elemType()); |
| 18107 | 18129 | }, |
| ... | ... | @@ -18124,6 +18146,10 @@ fn explainWhyTypeIsComptime( |
| 18124 | 18146 | try sema.explainWhyTypeIsComptime(block, src, msg, src_loc, ty.elemType()); |
| 18125 | 18147 | }, |
| 18126 | 18148 | |
| 18149 | .Optional => { | |
| 18150 | var buf: Type.Payload.ElemType = undefined; | |
| 18151 | try sema.explainWhyTypeIsComptime(block, src, msg, src_loc, ty.optionalChild(&buf)); | |
| 18152 | }, | |
| 18127 | 18153 | .ErrorUnion => { |
| 18128 | 18154 | try sema.explainWhyTypeIsComptime(block, src, msg, src_loc, ty.errorUnionPayload()); |
| 18129 | 18155 | }, |
| ... | ... | @@ -18163,6 +18189,120 @@ fn explainWhyTypeIsComptime( |
| 18163 | 18189 | } |
| 18164 | 18190 | } |
| 18165 | 18191 | |
| 18192 | const ExternPosition = enum { | |
| 18193 | ret_ty, | |
| 18194 | param_ty, | |
| 18195 | union_field, | |
| 18196 | other, | |
| 18197 | }; | |
| 18198 | ||
| 18199 | fn validateExternType(sema: *Sema, ty: Type, position: ExternPosition) CompileError!bool { | |
| 18200 | switch (ty.zigTypeTag()) { | |
| 18201 | .Type, | |
| 18202 | .ComptimeFloat, | |
| 18203 | .ComptimeInt, | |
| 18204 | .EnumLiteral, | |
| 18205 | .Undefined, | |
| 18206 | .Null, | |
| 18207 | .ErrorUnion, | |
| 18208 | .ErrorSet, | |
| 18209 | .BoundFn, | |
| 18210 | .Frame, | |
| 18211 | => return false, | |
| 18212 | .Void => return position == .union_field, | |
| 18213 | .NoReturn => return position == .ret_ty, | |
| 18214 | .Opaque, | |
| 18215 | .Bool, | |
| 18216 | .Float, | |
| 18217 | .Pointer, | |
| 18218 | .AnyFrame, | |
| 18219 | => return true, | |
| 18220 | .Int => switch (ty.intInfo(sema.mod.getTarget()).bits) { | |
| 18221 | 8, 16, 32, 64, 128 => return true, | |
| 18222 | else => return false, | |
| 18223 | }, | |
| 18224 | .Fn => return !ty.fnCallingConventionAllowsZigTypes(), | |
| 18225 | .Enum => { | |
| 18226 | var buf: Type.Payload.Bits = undefined; | |
| 18227 | return sema.validateExternType(ty.intTagType(&buf), position); | |
| 18228 | }, | |
| 18229 | .Struct, .Union => switch (ty.containerLayout()) { | |
| 18230 | .Extern, .Packed => return true, | |
| 18231 | else => return false, | |
| 18232 | }, | |
| 18233 | .Array => { | |
| 18234 | if (position == .ret_ty or position == .param_ty) return false; | |
| 18235 | return sema.validateExternType(ty.elemType2(), .other); | |
| 18236 | }, | |
| 18237 | .Vector => return sema.validateExternType(ty.elemType2(), .other), | |
| 18238 | .Optional => return ty.isPtrLikeOptional(), | |
| 18239 | } | |
| 18240 | } | |
| 18241 | ||
| 18242 | fn explainWhyTypeIsNotExtern( | |
| 18243 | sema: *Sema, | |
| 18244 | block: *Block, | |
| 18245 | src: LazySrcLoc, | |
| 18246 | msg: *Module.ErrorMsg, | |
| 18247 | src_loc: Module.SrcLoc, | |
| 18248 | ty: Type, | |
| 18249 | position: ExternPosition, | |
| 18250 | ) CompileError!void { | |
| 18251 | const mod = sema.mod; | |
| 18252 | switch (ty.zigTypeTag()) { | |
| 18253 | .Opaque, | |
| 18254 | .Bool, | |
| 18255 | .Float, | |
| 18256 | .Pointer, | |
| 18257 | .AnyFrame, | |
| 18258 | => return, | |
| 18259 | ||
| 18260 | .Type, | |
| 18261 | .ComptimeFloat, | |
| 18262 | .ComptimeInt, | |
| 18263 | .EnumLiteral, | |
| 18264 | .Undefined, | |
| 18265 | .Null, | |
| 18266 | .ErrorUnion, | |
| 18267 | .ErrorSet, | |
| 18268 | .BoundFn, | |
| 18269 | .Frame, | |
| 18270 | => return, | |
| 18271 | ||
| 18272 | .Void => try mod.errNoteNonLazy(src_loc, msg, "'void' is a zero bit type; for C 'void' use 'anyopaque'", .{}), | |
| 18273 | .NoReturn => try mod.errNoteNonLazy(src_loc, msg, "'noreturn' is only allowed as a return type", .{}), | |
| 18274 | .Int => if (ty.intInfo(sema.mod.getTarget()).bits > 128) { | |
| 18275 | try mod.errNoteNonLazy(src_loc, msg, "only integers with less than 128 bits are extern compatible", .{}); | |
| 18276 | } else { | |
| 18277 | try mod.errNoteNonLazy(src_loc, msg, "only integers with power of two bits are extern compatible", .{}); | |
| 18278 | }, | |
| 18279 | .Fn => switch (ty.fnCallingConvention()) { | |
| 18280 | .Unspecified => try mod.errNoteNonLazy(src_loc, msg, "extern function must specify calling convention", .{}), | |
| 18281 | .Async => try mod.errNoteNonLazy(src_loc, msg, "async function cannot be extern", .{}), | |
| 18282 | .Inline => try mod.errNoteNonLazy(src_loc, msg, "inline function cannot be extern", .{}), | |
| 18283 | else => return, | |
| 18284 | }, | |
| 18285 | .Enum => { | |
| 18286 | var buf: Type.Payload.Bits = undefined; | |
| 18287 | const tag_ty = ty.intTagType(&buf); | |
| 18288 | try mod.errNoteNonLazy(src_loc, msg, "enum tag type '{}' is not extern compatible", .{tag_ty.fmt(sema.mod)}); | |
| 18289 | try sema.explainWhyTypeIsNotExtern(block, src, msg, src_loc, tag_ty, position); | |
| 18290 | }, | |
| 18291 | .Struct => try mod.errNoteNonLazy(src_loc, msg, "only structs with packed or extern layout are extern compatible", .{}), | |
| 18292 | .Union => try mod.errNoteNonLazy(src_loc, msg, "only unions with packed or extern layout are extern compatible", .{}), | |
| 18293 | .Array => { | |
| 18294 | if (position == .ret_ty) { | |
| 18295 | try mod.errNoteNonLazy(src_loc, msg, "arrays are not allowed as a return type", .{}); | |
| 18296 | } else if (position == .param_ty) { | |
| 18297 | try mod.errNoteNonLazy(src_loc, msg, "arrays are not allowed as a parameter type", .{}); | |
| 18298 | } | |
| 18299 | try sema.explainWhyTypeIsNotExtern(block, src, msg, src_loc, ty.elemType2(), position); | |
| 18300 | }, | |
| 18301 | .Vector => try sema.explainWhyTypeIsNotExtern(block, src, msg, src_loc, ty.elemType2(), position), | |
| 18302 | .Optional => try mod.errNoteNonLazy(src_loc, msg, "only pointer like optionals are extern compatible", .{}), | |
| 18303 | } | |
| 18304 | } | |
| 18305 | ||
| 18166 | 18306 | pub const PanicId = enum { |
| 18167 | 18307 | unreach, |
| 18168 | 18308 | unwrap_null, |
| ... | ... | @@ -24006,6 +24146,20 @@ fn resolveStructFully( |
| 24006 | 24146 | struct_obj.status = .fully_resolved_wip; |
| 24007 | 24147 | for (struct_obj.fields.values()) |field| { |
| 24008 | 24148 | try sema.resolveTypeFully(block, src, field.ty); |
| 24149 | ||
| 24150 | if (struct_obj.layout == .Extern and !(try sema.validateExternType(field.ty, .other))) { | |
| 24151 | const msg = msg: { | |
| 24152 | const msg = try sema.errMsg(block, src, "extern structs cannot contain fields of type '{}'", .{field.ty.fmt(sema.mod)}); | |
| 24153 | errdefer msg.destroy(sema.gpa); | |
| 24154 | ||
| 24155 | const src_decl = sema.mod.declPtr(block.src_decl); | |
| 24156 | try sema.explainWhyTypeIsNotExtern(block, src, msg, src.toSrcLoc(src_decl), field.ty, .other); | |
| 24157 | ||
| 24158 | try sema.addDeclaredHereNote(msg, field.ty); | |
| 24159 | break :msg msg; | |
| 24160 | }; | |
| 24161 | return sema.failWithOwnedErrorMsg(block, msg); | |
| 24162 | } | |
| 24009 | 24163 | } |
| 24010 | 24164 | struct_obj.status = .fully_resolved; |
| 24011 | 24165 | } |
| ... | ... | @@ -24039,6 +24193,20 @@ fn resolveUnionFully( |
| 24039 | 24193 | union_obj.status = .fully_resolved_wip; |
| 24040 | 24194 | for (union_obj.fields.values()) |field| { |
| 24041 | 24195 | try sema.resolveTypeFully(block, src, field.ty); |
| 24196 | ||
| 24197 | if (union_obj.layout == .Extern and !(try sema.validateExternType(field.ty, .union_field))) { | |
| 24198 | const msg = msg: { | |
| 24199 | const msg = try sema.errMsg(block, src, "extern unions cannot contain fields of type '{}'", .{field.ty.fmt(sema.mod)}); | |
| 24200 | errdefer msg.destroy(sema.gpa); | |
| 24201 | ||
| 24202 | const src_decl = sema.mod.declPtr(block.src_decl); | |
| 24203 | try sema.explainWhyTypeIsNotExtern(block, src, msg, src.toSrcLoc(src_decl), field.ty, .union_field); | |
| 24204 | ||
| 24205 | try sema.addDeclaredHereNote(msg, field.ty); | |
| 24206 | break :msg msg; | |
| 24207 | }; | |
| 24208 | return sema.failWithOwnedErrorMsg(block, msg); | |
| 24209 | } | |
| 24042 | 24210 | } |
| 24043 | 24211 | union_obj.status = .fully_resolved; |
| 24044 | 24212 | } |
src/type.zig+8-1| ... | ... | @@ -3935,7 +3935,6 @@ pub const Type = extern union { |
| 3935 | 3935 | |
| 3936 | 3936 | /// Returns true if the type is optional and would be lowered to a single pointer |
| 3937 | 3937 | /// address value, using 0 for null. Note that this returns true for C pointers. |
| 3938 | /// See also `hasOptionalRepr`. | |
| 3939 | 3938 | pub fn isPtrLikeOptional(self: Type) bool { |
| 3940 | 3939 | switch (self.tag()) { |
| 3941 | 3940 | .optional_single_const_pointer, |
| ... | ... | @@ -4630,6 +4629,14 @@ pub const Type = extern union { |
| 4630 | 4629 | }; |
| 4631 | 4630 | } |
| 4632 | 4631 | |
| 4632 | /// Asserts the type is a function. | |
| 4633 | pub fn fnCallingConventionAllowsZigTypes(self: Type) bool { | |
| 4634 | return switch (self.fnCallingConvention()) { | |
| 4635 | .Unspecified, .Async, .Inline, .PtxKernel => true, | |
| 4636 | else => false, | |
| 4637 | }; | |
| 4638 | } | |
| 4639 | ||
| 4633 | 4640 | /// Asserts the type is a function. |
| 4634 | 4641 | pub fn fnIsVarArgs(self: Type) bool { |
| 4635 | 4642 | return switch (self.tag()) { |
test/behavior/union.zig+4-3| ... | ... | @@ -84,18 +84,19 @@ test "comptime union field access" { |
| 84 | 84 | |
| 85 | 85 | const FooExtern = extern union { |
| 86 | 86 | int: i32, |
| 87 | str: struct { | |
| 88 | slice: []const u8, | |
| 87 | str: extern struct { | |
| 88 | slice: [*:0]const u8, | |
| 89 | 89 | }, |
| 90 | 90 | }; |
| 91 | 91 | |
| 92 | 92 | test "basic extern unions" { |
| 93 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | |
| 93 | 94 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 94 | 95 | |
| 95 | 96 | var foo = FooExtern{ .int = 1 }; |
| 96 | 97 | try expect(foo.int == 1); |
| 97 | 98 | foo.str.slice = "Well"; |
| 98 | try expect(std.mem.eql(u8, foo.str.slice, "Well")); | |
| 99 | try expect(std.mem.eql(u8, std.mem.sliceTo(foo.str.slice, 0), "Well")); | |
| 99 | 100 | } |
| 100 | 101 | |
| 101 | 102 | const ExternPtrOrInt = extern union { |
test/cases/compile_errors/c_pointer_to_void.zig created+11| ... | ... | @@ -0,0 +1,11 @@ |
| 1 | export fn entry() void { | |
| 2 | var a: [*c]void = undefined; | |
| 3 | _ = a; | |
| 4 | } | |
| 5 | ||
| 6 | // error | |
| 7 | // backend=stage2 | |
| 8 | // target=native | |
| 9 | // | |
| 10 | // :1:1: error: C pointers cannot point to non-C-ABI-compatible type 'void' | |
| 11 | // :1:1: note: 'void' is a zero bit type; for C 'void' use 'anyopaque' |
test/cases/compile_errors/exported_enum_without_explicit_integer_tag_type.zig created+18| ... | ... | @@ -0,0 +1,18 @@ |
| 1 | const E = enum { one, two }; | |
| 2 | comptime { | |
| 3 | @export(E, .{ .name = "E" }); | |
| 4 | } | |
| 5 | const e: E = .two; | |
| 6 | comptime { | |
| 7 | @export(e, .{ .name = "e" }); | |
| 8 | } | |
| 9 | ||
| 10 | // error | |
| 11 | // backend=stage2 | |
| 12 | // target=native | |
| 13 | // | |
| 14 | // :3:5: error: unable to export type 'type' | |
| 15 | // :7:5: error: unable to export type 'tmp.E' | |
| 16 | // :7:5: note: enum tag type 'u1' is not extern compatible | |
| 17 | // :7:5: note: only integers with power of two bits are extern compatible | |
| 18 | // :1:11: note: enum declared here |
test/cases/compile_errors/extern_struct_with_extern-compatible_but_inferred_integer_tag_type.zig created+45| ... | ... | @@ -0,0 +1,45 @@ |
| 1 | pub const E = enum { | |
| 2 | @"0",@"1",@"2",@"3",@"4",@"5",@"6",@"7",@"8",@"9",@"10",@"11",@"12", | |
| 3 | @"13",@"14",@"15",@"16",@"17",@"18",@"19",@"20",@"21",@"22",@"23", | |
| 4 | @"24",@"25",@"26",@"27",@"28",@"29",@"30",@"31",@"32",@"33",@"34", | |
| 5 | @"35",@"36",@"37",@"38",@"39",@"40",@"41",@"42",@"43",@"44",@"45", | |
| 6 | @"46",@"47",@"48",@"49",@"50",@"51",@"52",@"53",@"54",@"55",@"56", | |
| 7 | @"57",@"58",@"59",@"60",@"61",@"62",@"63",@"64",@"65",@"66",@"67", | |
| 8 | @"68",@"69",@"70",@"71",@"72",@"73",@"74",@"75",@"76",@"77",@"78", | |
| 9 | @"79",@"80",@"81",@"82",@"83",@"84",@"85",@"86",@"87",@"88",@"89", | |
| 10 | @"90",@"91",@"92",@"93",@"94",@"95",@"96",@"97",@"98",@"99",@"100", | |
| 11 | @"101",@"102",@"103",@"104",@"105",@"106",@"107",@"108",@"109", | |
| 12 | @"110",@"111",@"112",@"113",@"114",@"115",@"116",@"117",@"118", | |
| 13 | @"119",@"120",@"121",@"122",@"123",@"124",@"125",@"126",@"127", | |
| 14 | @"128",@"129",@"130",@"131",@"132",@"133",@"134",@"135",@"136", | |
| 15 | @"137",@"138",@"139",@"140",@"141",@"142",@"143",@"144",@"145", | |
| 16 | @"146",@"147",@"148",@"149",@"150",@"151",@"152",@"153",@"154", | |
| 17 | @"155",@"156",@"157",@"158",@"159",@"160",@"161",@"162",@"163", | |
| 18 | @"164",@"165",@"166",@"167",@"168",@"169",@"170",@"171",@"172", | |
| 19 | @"173",@"174",@"175",@"176",@"177",@"178",@"179",@"180",@"181", | |
| 20 | @"182",@"183",@"184",@"185",@"186",@"187",@"188",@"189",@"190", | |
| 21 | @"191",@"192",@"193",@"194",@"195",@"196",@"197",@"198",@"199", | |
| 22 | @"200",@"201",@"202",@"203",@"204",@"205",@"206",@"207",@"208", | |
| 23 | @"209",@"210",@"211",@"212",@"213",@"214",@"215",@"216",@"217", | |
| 24 | @"218",@"219",@"220",@"221",@"222",@"223",@"224",@"225",@"226", | |
| 25 | @"227",@"228",@"229",@"230",@"231",@"232",@"233",@"234",@"235", | |
| 26 | @"236",@"237",@"238",@"239",@"240",@"241",@"242",@"243",@"244", | |
| 27 | @"245",@"246",@"247",@"248",@"249",@"250",@"251",@"252",@"253", | |
| 28 | @"254",@"255", @"256" | |
| 29 | }; | |
| 30 | pub const S = extern struct { | |
| 31 | e: E, | |
| 32 | }; | |
| 33 | export fn entry() void { | |
| 34 | const s: S = undefined; | |
| 35 | _ = s; | |
| 36 | } | |
| 37 | ||
| 38 | // error | |
| 39 | // backend=stage2 | |
| 40 | // target=native | |
| 41 | // | |
| 42 | // :33:8: error: extern structs cannot contain fields of type 'tmp.E' | |
| 43 | // :33:8: note: enum tag type 'u9' is not extern compatible | |
| 44 | // :33:8: note: only integers with power of two bits are extern compatible | |
| 45 | // :1:15: note: enum declared here |
test/cases/compile_errors/extern_struct_with_non-extern-compatible_integer_tag_type.zig created+17| ... | ... | @@ -0,0 +1,17 @@ |
| 1 | pub const E = enum(u31) { A, B, C }; | |
| 2 | pub const S = extern struct { | |
| 3 | e: E, | |
| 4 | }; | |
| 5 | export fn entry() void { | |
| 6 | const s: S = undefined; | |
| 7 | _ = s; | |
| 8 | } | |
| 9 | ||
| 10 | // error | |
| 11 | // backend=stage2 | |
| 12 | // target=native | |
| 13 | // | |
| 14 | // :5:8: error: extern structs cannot contain fields of type 'tmp.E' | |
| 15 | // :5:8: note: enum tag type 'u31' is not extern compatible | |
| 16 | // :5:8: note: only integers with power of two bits are extern compatible | |
| 17 | // :1:15: note: enum declared here |
test/cases/compile_errors/invalid_optional_type_in_extern_struct.zig created+11| ... | ... | @@ -0,0 +1,11 @@ |
| 1 | const stroo = extern struct { | |
| 2 | moo: ?[*c]u8, | |
| 3 | }; | |
| 4 | export fn testf(fluff: *stroo) void { _ = fluff; } | |
| 5 | ||
| 6 | // error | |
| 7 | // backend=stage2 | |
| 8 | // target=native | |
| 9 | // | |
| 10 | // :4:8: error: extern structs cannot contain fields of type '?[*c]u8' | |
| 11 | // :4:8: note: only pointer like optionals are extern compatible |
test/cases/compile_errors/non-const_variables_of_things_that_require_const_variables.zig+1| ... | ... | @@ -40,5 +40,6 @@ const Opaque = opaque {}; |
| 40 | 40 | // :14:8: note: to modify this variable at runtime, it must be given an explicit fixed-size number type |
| 41 | 41 | // :18:8: error: variable of type '@TypeOf(null)' must be const or comptime |
| 42 | 42 | // :22:19: error: values of type 'tmp.Opaque' must be comptime known, but operand value is runtime known |
| 43 | // :22:19: note: opaque type 'tmp.Opaque' has undefined size | |
| 43 | 44 | // :26:8: error: variable of type 'type' must be const or comptime |
| 44 | 45 | // :26:8: note: types are not available at runtime |
test/cases/compile_errors/stage1/obj/exported_enum_without_explicit_integer_tag_type.zig deleted-15| ... | ... | @@ -1,15 +0,0 @@ |
| 1 | const E = enum { one, two }; | |
| 2 | comptime { | |
| 3 | @export(E, .{ .name = "E" }); | |
| 4 | } | |
| 5 | const e: E = .two; | |
| 6 | comptime { | |
| 7 | @export(e, .{ .name = "e" }); | |
| 8 | } | |
| 9 | ||
| 10 | // error | |
| 11 | // backend=stage1 | |
| 12 | // target=native | |
| 13 | // | |
| 14 | // tmp.zig:3:13: error: exported enum without explicit integer tag type | |
| 15 | // tmp.zig:7:13: error: exported enum value without explicit integer tag type |
test/cases/compile_errors/stage1/obj/extern_struct_with_extern-compatible_but_inferred_integer_tag_type.zig deleted-43| ... | ... | @@ -1,43 +0,0 @@ |
| 1 | pub const E = enum { | |
| 2 | @"0",@"1",@"2",@"3",@"4",@"5",@"6",@"7",@"8",@"9",@"10",@"11",@"12", | |
| 3 | @"13",@"14",@"15",@"16",@"17",@"18",@"19",@"20",@"21",@"22",@"23", | |
| 4 | @"24",@"25",@"26",@"27",@"28",@"29",@"30",@"31",@"32",@"33",@"34", | |
| 5 | @"35",@"36",@"37",@"38",@"39",@"40",@"41",@"42",@"43",@"44",@"45", | |
| 6 | @"46",@"47",@"48",@"49",@"50",@"51",@"52",@"53",@"54",@"55",@"56", | |
| 7 | @"57",@"58",@"59",@"60",@"61",@"62",@"63",@"64",@"65",@"66",@"67", | |
| 8 | @"68",@"69",@"70",@"71",@"72",@"73",@"74",@"75",@"76",@"77",@"78", | |
| 9 | @"79",@"80",@"81",@"82",@"83",@"84",@"85",@"86",@"87",@"88",@"89", | |
| 10 | @"90",@"91",@"92",@"93",@"94",@"95",@"96",@"97",@"98",@"99",@"100", | |
| 11 | @"101",@"102",@"103",@"104",@"105",@"106",@"107",@"108",@"109", | |
| 12 | @"110",@"111",@"112",@"113",@"114",@"115",@"116",@"117",@"118", | |
| 13 | @"119",@"120",@"121",@"122",@"123",@"124",@"125",@"126",@"127", | |
| 14 | @"128",@"129",@"130",@"131",@"132",@"133",@"134",@"135",@"136", | |
| 15 | @"137",@"138",@"139",@"140",@"141",@"142",@"143",@"144",@"145", | |
| 16 | @"146",@"147",@"148",@"149",@"150",@"151",@"152",@"153",@"154", | |
| 17 | @"155",@"156",@"157",@"158",@"159",@"160",@"161",@"162",@"163", | |
| 18 | @"164",@"165",@"166",@"167",@"168",@"169",@"170",@"171",@"172", | |
| 19 | @"173",@"174",@"175",@"176",@"177",@"178",@"179",@"180",@"181", | |
| 20 | @"182",@"183",@"184",@"185",@"186",@"187",@"188",@"189",@"190", | |
| 21 | @"191",@"192",@"193",@"194",@"195",@"196",@"197",@"198",@"199", | |
| 22 | @"200",@"201",@"202",@"203",@"204",@"205",@"206",@"207",@"208", | |
| 23 | @"209",@"210",@"211",@"212",@"213",@"214",@"215",@"216",@"217", | |
| 24 | @"218",@"219",@"220",@"221",@"222",@"223",@"224",@"225",@"226", | |
| 25 | @"227",@"228",@"229",@"230",@"231",@"232",@"233",@"234",@"235", | |
| 26 | @"236",@"237",@"238",@"239",@"240",@"241",@"242",@"243",@"244", | |
| 27 | @"245",@"246",@"247",@"248",@"249",@"250",@"251",@"252",@"253", | |
| 28 | @"254",@"255" | |
| 29 | }; | |
| 30 | pub const S = extern struct { | |
| 31 | e: E, | |
| 32 | }; | |
| 33 | export fn entry() void { | |
| 34 | if (@typeInfo(E).Enum.tag_type != u8) @compileError("did not infer u8 tag type"); | |
| 35 | const s: S = undefined; | |
| 36 | _ = s; | |
| 37 | } | |
| 38 | ||
| 39 | // error | |
| 40 | // backend=stage1 | |
| 41 | // target=native | |
| 42 | // | |
| 43 | // tmp.zig:31:5: error: extern structs cannot contain fields of type 'E' |
test/cases/compile_errors/stage1/obj/extern_struct_with_non-extern-compatible_integer_tag_type.zig deleted-14| ... | ... | @@ -1,14 +0,0 @@ |
| 1 | pub const E = enum(u31) { A, B, C }; | |
| 2 | pub const S = extern struct { | |
| 3 | e: E, | |
| 4 | }; | |
| 5 | export fn entry() void { | |
| 6 | const s: S = undefined; | |
| 7 | _ = s; | |
| 8 | } | |
| 9 | ||
| 10 | // error | |
| 11 | // backend=stage1 | |
| 12 | // target=native | |
| 13 | // | |
| 14 | // tmp.zig:3:5: error: extern structs cannot contain fields of type 'E' |
test/cases/compile_errors/stage1/obj/invalid_optional_type_in_extern_struct.zig deleted-10| ... | ... | @@ -1,10 +0,0 @@ |
| 1 | const stroo = extern struct { | |
| 2 | moo: ?[*c]u8, | |
| 3 | }; | |
| 4 | export fn testf(fluff: *stroo) void { _ = fluff; } | |
| 5 | ||
| 6 | // error | |
| 7 | // backend=stage1 | |
| 8 | // target=native | |
| 9 | // | |
| 10 | // tmp.zig:2:5: error: extern structs cannot contain fields of type '?[*c]u8' |
test/cases/compile_errors/stage1/obj/optional_pointer_to_void_in_extern_struct.zig deleted-14| ... | ... | @@ -1,14 +0,0 @@ |
| 1 | const Foo = extern struct { | |
| 2 | x: ?*const void, | |
| 3 | }; | |
| 4 | const Bar = extern struct { | |
| 5 | foo: Foo, | |
| 6 | y: i32, | |
| 7 | }; | |
| 8 | export fn entry(bar: *Bar) void {_ = bar;} | |
| 9 | ||
| 10 | // error | |
| 11 | // backend=stage1 | |
| 12 | // target=native | |
| 13 | // | |
| 14 | // tmp.zig:2:5: error: extern structs cannot contain fields of type '?*const void' |
test/cases/compile_errors/stage1/optional_pointer_to_void_in_extern_struct.zig created+14| ... | ... | @@ -0,0 +1,14 @@ |
| 1 | const Foo = extern struct { | |
| 2 | x: ?*const void, | |
| 3 | }; | |
| 4 | const Bar = extern struct { | |
| 5 | foo: Foo, | |
| 6 | y: i32, | |
| 7 | }; | |
| 8 | export fn entry(bar: *Bar) void {_ = bar;} | |
| 9 | ||
| 10 | // error | |
| 11 | // backend=stage1 | |
| 12 | // target=native | |
| 13 | // | |
| 14 | // tmp.zig:2:5: error: extern structs cannot contain fields of type '?*const void' |