authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-07-11 20:25:35-04:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2022-07-11 20:25:35-04:00
logdc815e5e8f194a03988624a6bf7e739ddfe0d3b4
treeb464bf4b82f344c7b20cf9af212b95c0a42bc893
parent8b3f15f21824e77e776336d8be5832502946621b
parent122c76a1670e4b925ccdabaa771f59e5df6d43aa
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #12075 from Vexu/stage2-validate-extern

Stage2 validate extern types

19 files changed, 313 insertions(+), 116 deletions(-)

lib/compiler_rt/multi3.zig+2-2
...@@ -59,12 +59,12 @@ const twords = extern union {...@@ -59,12 +59,12 @@ const twords = extern union {
59 s: S,59 s: S,
6060
61 const S = if (native_endian == .Little)61 const S = if (native_endian == .Little)
62 struct {62 extern struct {
63 low: u64,63 low: u64,
64 high: u64,64 high: u64,
65 }65 }
66 else66 else
67 struct {67 extern struct {
68 high: u64,68 high: u64,
69 low: u64,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,9 +31,9 @@ fn Dwords(comptime T: type, comptime signed_half: bool) type {
3131
32 all: T,32 all: T,
33 s: if (native_endian == .Little)33 s: if (native_endian == .Little)
34 struct { low: HalfT, high: HalfT }34 extern struct { low: HalfT, high: HalfT }
35 else35 else
36 struct { high: HalfT, low: HalfT },36 extern struct { high: HalfT, low: HalfT },
37 };37 };
38}38}
3939
lib/std/c/haiku.zig+2-2
...@@ -30,8 +30,8 @@ pub extern "c" fn _kern_get_current_team() i32;...@@ -30,8 +30,8 @@ pub extern "c" fn _kern_get_current_team() i32;
30pub const sem_t = extern struct {30pub const sem_t = extern struct {
31 type: i32,31 type: i32,
32 u: extern union {32 u: extern union {
33 named_sem_id: ?i32,33 named_sem_id: i32,
34 unnamed_sem: ?i32,34 unnamed_sem: i32,
35 },35 },
36 padding: [2]i32,36 padding: [2]i32,
37};37};
lib/std/start.zig+1-1
...@@ -108,7 +108,7 @@ fn callMain2() noreturn {...@@ -108,7 +108,7 @@ fn callMain2() noreturn {
108 exit2(0);108 exit2(0);
109}109}
110110
111fn wasiMain2() noreturn {111fn wasiMain2() callconv(.C) noreturn {
112 switch (@typeInfo(@typeInfo(@TypeOf(root.main)).Fn.return_type.?)) {112 switch (@typeInfo(@typeInfo(@TypeOf(root.main)).Fn.return_type.?)) {
113 .Void => {113 .Void => {
114 root.main();114 root.main();
src/Sema.zig+177-9
...@@ -4740,12 +4740,19 @@ pub fn analyzeExport(...@@ -4740,12 +4740,19 @@ pub fn analyzeExport(
47404740
4741 try mod.ensureDeclAnalyzed(exported_decl_index);4741 try mod.ensureDeclAnalyzed(exported_decl_index);
4742 const exported_decl = mod.declPtr(exported_decl_index);4742 const exported_decl = mod.declPtr(exported_decl_index);
4743 // TODO run the same checks as we do for C ABI struct fields4743
4744 switch (exported_decl.ty.zigTypeTag()) {4744 if (!(try sema.validateExternType(exported_decl.ty, .other))) {
4745 .Fn, .Int, .Enum, .Struct, .Union, .Array, .Float, .Pointer, .Optional => {},4745 const msg = msg: {
4746 else => return sema.fail(block, src, "unable to export type '{}'", .{4746 const msg = try sema.errMsg(block, src, "unable to export type '{}'", .{exported_decl.ty.fmt(sema.mod)});
4747 exported_decl.ty.fmt(sema.mod),4747 errdefer msg.destroy(sema.gpa);
4748 }),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 }
47504757
4751 const gpa = mod.gpa;4758 const gpa = mod.gpa;
...@@ -13799,7 +13806,20 @@ fn validatePtrTy(sema: *Sema, block: *Block, elem_src: LazySrcLoc, ty: Type) Com...@@ -13799,7 +13806,20 @@ fn validatePtrTy(sema: *Sema, block: *Block, elem_src: LazySrcLoc, ty: Type) Com
13799 } else if (ptr_info.size == .Many and pointee_tag == .Opaque) {13806 } else if (ptr_info.size == .Many and pointee_tag == .Opaque) {
13800 return sema.fail(block, elem_src, "unknown-length pointer to opaque not allowed", .{});13807 return sema.fail(block, elem_src, "unknown-length pointer to opaque not allowed", .{});
13801 } else if (ptr_info.size == .C) {13808 } else if (ptr_info.size == .C) {
13802 // TODO check extern type13809 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 if (pointee_tag == .Opaque) {13823 if (pointee_tag == .Opaque) {
13804 return sema.fail(block, elem_src, "C pointers cannot point to opaque types", .{});13824 return sema.fail(block, elem_src, "C pointers cannot point to opaque types", .{});
13805 }13825 }
...@@ -18098,10 +18118,12 @@ fn explainWhyTypeIsComptime(...@@ -18098,10 +18118,12 @@ fn explainWhyTypeIsComptime(
18098 .NoReturn,18118 .NoReturn,
18099 .Undefined,18119 .Undefined,
18100 .Null,18120 .Null,
18101 .Opaque,
18102 .Optional,
18103 => return,18121 => return,
1810418122
18123 .Opaque => {
18124 try mod.errNoteNonLazy(src_loc, msg, "opaque type '{}' has undefined size", .{ty.fmt(sema.mod)});
18125 },
18126
18105 .Array, .Vector => {18127 .Array, .Vector => {
18106 try sema.explainWhyTypeIsComptime(block, src, msg, src_loc, ty.elemType());18128 try sema.explainWhyTypeIsComptime(block, src, msg, src_loc, ty.elemType());
18107 },18129 },
...@@ -18124,6 +18146,10 @@ fn explainWhyTypeIsComptime(...@@ -18124,6 +18146,10 @@ fn explainWhyTypeIsComptime(
18124 try sema.explainWhyTypeIsComptime(block, src, msg, src_loc, ty.elemType());18146 try sema.explainWhyTypeIsComptime(block, src, msg, src_loc, ty.elemType());
18125 },18147 },
1812618148
18149 .Optional => {
18150 var buf: Type.Payload.ElemType = undefined;
18151 try sema.explainWhyTypeIsComptime(block, src, msg, src_loc, ty.optionalChild(&buf));
18152 },
18127 .ErrorUnion => {18153 .ErrorUnion => {
18128 try sema.explainWhyTypeIsComptime(block, src, msg, src_loc, ty.errorUnionPayload());18154 try sema.explainWhyTypeIsComptime(block, src, msg, src_loc, ty.errorUnionPayload());
18129 },18155 },
...@@ -18163,6 +18189,120 @@ fn explainWhyTypeIsComptime(...@@ -18163,6 +18189,120 @@ fn explainWhyTypeIsComptime(
18163 }18189 }
18164}18190}
1816518191
18192const ExternPosition = enum {
18193 ret_ty,
18194 param_ty,
18195 union_field,
18196 other,
18197};
18198
18199fn 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
18242fn 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
18166pub const PanicId = enum {18306pub const PanicId = enum {
18167 unreach,18307 unreach,
18168 unwrap_null,18308 unwrap_null,
...@@ -24006,6 +24146,20 @@ fn resolveStructFully(...@@ -24006,6 +24146,20 @@ fn resolveStructFully(
24006 struct_obj.status = .fully_resolved_wip;24146 struct_obj.status = .fully_resolved_wip;
24007 for (struct_obj.fields.values()) |field| {24147 for (struct_obj.fields.values()) |field| {
24008 try sema.resolveTypeFully(block, src, field.ty);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 struct_obj.status = .fully_resolved;24164 struct_obj.status = .fully_resolved;
24011 }24165 }
...@@ -24039,6 +24193,20 @@ fn resolveUnionFully(...@@ -24039,6 +24193,20 @@ fn resolveUnionFully(
24039 union_obj.status = .fully_resolved_wip;24193 union_obj.status = .fully_resolved_wip;
24040 for (union_obj.fields.values()) |field| {24194 for (union_obj.fields.values()) |field| {
24041 try sema.resolveTypeFully(block, src, field.ty);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 union_obj.status = .fully_resolved;24211 union_obj.status = .fully_resolved;
24044 }24212 }
src/type.zig+8-1
...@@ -3935,7 +3935,6 @@ pub const Type = extern union {...@@ -3935,7 +3935,6 @@ pub const Type = extern union {
39353935
3936 /// Returns true if the type is optional and would be lowered to a single pointer3936 /// Returns true if the type is optional and would be lowered to a single pointer
3937 /// address value, using 0 for null. Note that this returns true for C pointers.3937 /// address value, using 0 for null. Note that this returns true for C pointers.
3938 /// See also `hasOptionalRepr`.
3939 pub fn isPtrLikeOptional(self: Type) bool {3938 pub fn isPtrLikeOptional(self: Type) bool {
3940 switch (self.tag()) {3939 switch (self.tag()) {
3941 .optional_single_const_pointer,3940 .optional_single_const_pointer,
...@@ -4630,6 +4629,14 @@ pub const Type = extern union {...@@ -4630,6 +4629,14 @@ pub const Type = extern union {
4630 };4629 };
4631 }4630 }
46324631
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 /// Asserts the type is a function.4640 /// Asserts the type is a function.
4634 pub fn fnIsVarArgs(self: Type) bool {4641 pub fn fnIsVarArgs(self: Type) bool {
4635 return switch (self.tag()) {4642 return switch (self.tag()) {
test/behavior/union.zig+4-3
...@@ -84,18 +84,19 @@ test "comptime union field access" {...@@ -84,18 +84,19 @@ test "comptime union field access" {
8484
85const FooExtern = extern union {85const FooExtern = extern union {
86 int: i32,86 int: i32,
87 str: struct {87 str: extern struct {
88 slice: []const u8,88 slice: [*:0]const u8,
89 },89 },
90};90};
9191
92test "basic extern unions" {92test "basic extern unions" {
93 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
93 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;94 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
9495
95 var foo = FooExtern{ .int = 1 };96 var foo = FooExtern{ .int = 1 };
96 try expect(foo.int == 1);97 try expect(foo.int == 1);
97 foo.str.slice = "Well";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}
100101
101const ExternPtrOrInt = extern union {102const ExternPtrOrInt = extern union {
test/cases/compile_errors/c_pointer_to_void.zig created+11
...@@ -0,0 +1,11 @@
1export 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 @@
1const E = enum { one, two };
2comptime {
3 @export(E, .{ .name = "E" });
4}
5const e: E = .two;
6comptime {
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 @@
1pub 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};
30pub const S = extern struct {
31 e: E,
32};
33export 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 @@
1pub const E = enum(u31) { A, B, C };
2pub const S = extern struct {
3 e: E,
4};
5export 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 @@
1const stroo = extern struct {
2 moo: ?[*c]u8,
3};
4export 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,5 +40,6 @@ const Opaque = opaque {};
40// :14:8: note: to modify this variable at runtime, it must be given an explicit fixed-size number type40// :14:8: note: to modify this variable at runtime, it must be given an explicit fixed-size number type
41// :18:8: error: variable of type '@TypeOf(null)' must be const or comptime41// :18:8: error: variable of type '@TypeOf(null)' must be const or comptime
42// :22:19: error: values of type 'tmp.Opaque' must be comptime known, but operand value is runtime known42// :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// :26:8: error: variable of type 'type' must be const or comptime44// :26:8: error: variable of type 'type' must be const or comptime
44// :26:8: note: types are not available at runtime45// :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 @@
1const E = enum { one, two };
2comptime {
3 @export(E, .{ .name = "E" });
4}
5const e: E = .two;
6comptime {
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 @@
1pub 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};
30pub const S = extern struct {
31 e: E,
32};
33export 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 @@
1pub const E = enum(u31) { A, B, C };
2pub const S = extern struct {
3 e: E,
4};
5export 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 @@
1const stroo = extern struct {
2 moo: ?[*c]u8,
3};
4export 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 @@
1const Foo = extern struct {
2 x: ?*const void,
3};
4const Bar = extern struct {
5 foo: Foo,
6 y: i32,
7};
8export 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 @@
1const Foo = extern struct {
2 x: ?*const void,
3};
4const Bar = extern struct {
5 foo: Foo,
6 y: i32,
7};
8export 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'