authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-07-29 11:55:53+03:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-07-30 00:18:08+03:00
log17622b9db14cb1d8dd600b21f60c8a1041e5b0e1
tree52f10980d6ac1bce333079f4f92fb7aa789ca874
parentf43ea43ac920d3fbd629175e4e7fbe4309c6eab5

Sema: implement `@Type` for functions

Closes #12280

30 files changed, 463 insertions(+), 274 deletions(-)

src/Sema.zig+183-11
......@@ -15759,6 +15759,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
1575915759 const tag_ty = type_info_ty.unionTagType().?;
1576015760 const target = mod.getTarget();
1576115761 const tag_index = tag_ty.enumTagFieldIndex(union_val.tag, mod).?;
15762 if (union_val.val.anyUndef()) return sema.failWithUseOfUndef(block, src);
1576215763 switch (@intToEnum(std.builtin.TypeId, tag_index)) {
1576315764 .Type => return Air.Inst.Ref.type_type,
1576415765 .Void => return Air.Inst.Ref.void_type,
......@@ -15828,7 +15829,10 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
1582815829 const is_allowzero_val = struct_val[6];
1582915830 const sentinel_val = struct_val[7];
1583015831
15831 const abi_align = @intCast(u29, alignment_val.toUnsignedInt(target)); // TODO: Validate this value.
15832 if (!try sema.intFitsInType(block, src, alignment_val, Type.u32, null)) {
15833 return sema.fail(block, src, "alignment must fit in 'u32'", .{});
15834 }
15835 const abi_align = @intCast(u29, alignment_val.toUnsignedInt(target));
1583215836
1583315837 var buffer: Value.ToTypeBuffer = undefined;
1583415838 const unresolved_elem_ty = child_val.toType(&buffer);
......@@ -15855,6 +15859,39 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
1585515859 actual_sentinel = (try sema.pointerDeref(block, src, sentinel_ptr_val, ptr_ty)).?;
1585615860 }
1585715861
15862 if (elem_ty.zigTypeTag() == .NoReturn) {
15863 return sema.fail(block, src, "pointer to noreturn not allowed", .{});
15864 } else if (elem_ty.zigTypeTag() == .Fn) {
15865 if (ptr_size != .One) {
15866 return sema.fail(block, src, "function pointers must be single pointers", .{});
15867 }
15868 const fn_align = elem_ty.fnInfo().alignment;
15869 if (abi_align != 0 and fn_align != 0 and
15870 abi_align != fn_align)
15871 {
15872 return sema.fail(block, src, "function pointer alignment disagrees with function alignment", .{});
15873 }
15874 } else if (ptr_size == .Many and elem_ty.zigTypeTag() == .Opaque) {
15875 return sema.fail(block, src, "unknown-length pointer to opaque not allowed", .{});
15876 } else if (ptr_size == .C) {
15877 if (!(try sema.validateExternType(elem_ty, .other))) {
15878 const msg = msg: {
15879 const msg = try sema.errMsg(block, src, "C pointers cannot point to non-C-ABI-compatible type '{}'", .{elem_ty.fmt(sema.mod)});
15880 errdefer msg.destroy(sema.gpa);
15881
15882 const src_decl = sema.mod.declPtr(block.src_decl);
15883 try sema.explainWhyTypeIsNotExtern(block, src, msg, src.toSrcLoc(src_decl), elem_ty, .other);
15884
15885 try sema.addDeclaredHereNote(msg, elem_ty);
15886 break :msg msg;
15887 };
15888 return sema.failWithOwnedErrorMsg(block, msg);
15889 }
15890 if (elem_ty.zigTypeTag() == .Opaque) {
15891 return sema.fail(block, src, "C pointers cannot point to opaque types", .{});
15892 }
15893 }
15894
1585815895 const ty = try Type.ptr(sema.arena, mod, .{
1585915896 .size = ptr_size,
1586015897 .mutable = !is_const_val.toBool(),
......@@ -15915,6 +15952,10 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
1591515952 const error_set_ty = try error_set_val.toType(&buffer).copy(sema.arena);
1591615953 const payload_ty = try payload_val.toType(&buffer).copy(sema.arena);
1591715954
15955 if (error_set_ty.zigTypeTag() != .ErrorSet) {
15956 return sema.fail(block, src, "Type.ErrorUnion.error_set must be an error set type", .{});
15957 }
15958
1591815959 const ty = try Type.Tag.error_union.create(sema.arena, .{
1591915960 .error_set = error_set_ty,
1592015961 .payload = payload_ty,
......@@ -15928,7 +15969,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
1592815969 const decl_index = slice_val.ptr.pointerDecl().?;
1592915970 try sema.ensureDeclAnalyzed(decl_index);
1593015971 const decl = mod.declPtr(decl_index);
15931 const array_val = decl.val.castTag(.aggregate).?.data;
15972 const array_val: []Value = if (decl.val.castTag(.aggregate)) |some| some.data else &.{};
1593215973
1593315974 var names: Module.ErrorSet.NameMap = .{};
1593415975 try names.ensureUnusedCapacity(sema.arena, array_val.len);
......@@ -15940,7 +15981,10 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
1594015981 const name_str = try name_val.toAllocatedBytes(Type.initTag(.const_slice_u8), sema.arena, sema.mod);
1594115982
1594215983 const kv = try mod.getErrorValue(name_str);
15943 names.putAssumeCapacityNoClobber(kv.key, {});
15984 const gop = names.getOrPutAssumeCapacity(kv.key);
15985 if (gop.found_existing) {
15986 return sema.fail(block, src, "duplicate error '{s}'", .{name_str});
15987 }
1594415988 }
1594515989
1594615990 // names must be sorted
......@@ -16022,13 +16066,9 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
1602216066 new_decl.owns_tv = true;
1602316067 errdefer mod.abortAnonDecl(new_decl_index);
1602416068
16025 // Enum tag type
16026 var buffer: Value.ToTypeBuffer = undefined;
16027 const int_tag_ty = try tag_type_val.toType(&buffer).copy(new_decl_arena_allocator);
16028
1602916069 enum_obj.* = .{
1603016070 .owner_decl = new_decl_index,
16031 .tag_ty = int_tag_ty,
16071 .tag_ty = Type.@"null",
1603216072 .tag_ty_inferred = false,
1603316073 .fields = .{},
1603416074 .values = .{},
......@@ -16040,6 +16080,15 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
1604016080 },
1604116081 };
1604216082
16083 // Enum tag type
16084 var buffer: Value.ToTypeBuffer = undefined;
16085 const int_tag_ty = try tag_type_val.toType(&buffer).copy(new_decl_arena_allocator);
16086
16087 if (int_tag_ty.zigTypeTag() != .Int) {
16088 return sema.fail(block, src, "Type.Enum.tag_type must be an integer type", .{});
16089 }
16090 enum_obj.tag_ty = int_tag_ty;
16091
1604316092 // Fields
1604416093 const fields_len = try sema.usizeCast(block, src, fields_val.sliceLen(mod));
1604516094 if (fields_len > 0) {
......@@ -16077,6 +16126,8 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
1607716126 .mod = mod,
1607816127 });
1607916128 }
16129 } else {
16130 return sema.fail(block, src, "enums must have at least one field", .{});
1608016131 }
1608116132
1608216133 try new_decl.finalizeNewArena(&new_decl_arena);
......@@ -16186,11 +16237,17 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
1618616237 };
1618716238
1618816239 // Tag type
16240 var tag_ty_field_names: ?Module.EnumFull.NameMap = null;
1618916241 var enum_field_names: ?*Module.EnumNumbered.NameMap = null;
1619016242 const fields_len = try sema.usizeCast(block, src, fields_val.sliceLen(mod));
1619116243 if (tag_type_val.optionalValue()) |payload_val| {
1619216244 var buffer: Value.ToTypeBuffer = undefined;
1619316245 union_obj.tag_ty = try payload_val.toType(&buffer).copy(new_decl_arena_allocator);
16246
16247 if (union_obj.tag_ty.zigTypeTag() != .Enum) {
16248 return sema.fail(block, src, "Type.Union.tag_type must be an enum type", .{});
16249 }
16250 tag_ty_field_names = try union_obj.tag_ty.enumFields().clone(sema.arena);
1619416251 } else {
1619516252 union_obj.tag_ty = try sema.generateUnionTagTypeSimple(block, fields_len, null);
1619616253 enum_field_names = &union_obj.tag_ty.castTag(.enum_simple).?.data.fields;
......@@ -16222,6 +16279,19 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
1622216279 set.putAssumeCapacity(field_name, {});
1622316280 }
1622416281
16282 if (tag_ty_field_names) |*names| {
16283 const enum_has_field = names.orderedRemove(field_name);
16284 if (!enum_has_field) {
16285 const msg = msg: {
16286 const msg = try sema.errMsg(block, src, "no field named '{s}' in enum '{}'", .{ field_name, union_obj.tag_ty.fmt(sema.mod) });
16287 errdefer msg.destroy(sema.gpa);
16288 try sema.addDeclaredHereNote(msg, union_obj.tag_ty);
16289 break :msg msg;
16290 };
16291 return sema.failWithOwnedErrorMsg(block, msg);
16292 }
16293 }
16294
1622516295 const gop = union_obj.fields.getOrPutAssumeCapacity(field_name);
1622616296 if (gop.found_existing) {
1622716297 // TODO: better source location
......@@ -16234,12 +16304,108 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
1623416304 .abi_align = @intCast(u32, alignment_val.toUnsignedInt(target)),
1623516305 };
1623616306 }
16307 } else {
16308 return sema.fail(block, src, "unions must have at least one field", .{});
16309 }
16310
16311 if (tag_ty_field_names) |names| {
16312 if (names.count() > 0) {
16313 const msg = msg: {
16314 const msg = try sema.errMsg(block, src, "enum field(s) missing in union", .{});
16315 errdefer msg.destroy(sema.gpa);
16316
16317 const enum_ty = union_obj.tag_ty;
16318 for (names.keys()) |field_name| {
16319 const field_index = enum_ty.enumFieldIndex(field_name).?;
16320 try sema.addFieldErrNote(block, enum_ty, field_index, msg, "field '{s}' missing, declared here", .{field_name});
16321 }
16322 try sema.addDeclaredHereNote(msg, union_obj.tag_ty);
16323 break :msg msg;
16324 };
16325 return sema.failWithOwnedErrorMsg(block, msg);
16326 }
1623716327 }
1623816328
1623916329 try new_decl.finalizeNewArena(&new_decl_arena);
1624016330 return sema.analyzeDeclVal(block, src, new_decl_index);
1624116331 },
16242 .Fn => return sema.fail(block, src, "TODO: Sema.zirReify for Fn", .{}),
16332 .Fn => {
16333 const struct_val = union_val.val.castTag(.aggregate).?.data;
16334 // TODO use reflection instead of magic numbers here
16335 // calling_convention: CallingConvention,
16336 const cc = struct_val[0].toEnum(std.builtin.CallingConvention);
16337 // alignment: comptime_int,
16338 const alignment_val = struct_val[1];
16339 // is_generic: bool,
16340 const is_generic = struct_val[2].toBool();
16341 // is_var_args: bool,
16342 const is_var_args = struct_val[3].toBool();
16343 // return_type: ?type,
16344 const return_type_val = struct_val[4];
16345 // args: []const Param,
16346 const args_val = struct_val[5];
16347
16348 if (is_generic) {
16349 return sema.fail(block, src, "Type.Fn.is_generic must be false for @Type", .{});
16350 }
16351
16352 if (is_var_args and cc != .C) {
16353 return sema.fail(block, src, "varargs functions must have C calling convention", .{});
16354 }
16355
16356 const alignment = @intCast(u29, alignment_val.toUnsignedInt(target)); // TODO: Validate this value.
16357 var buf: Value.ToTypeBuffer = undefined;
16358
16359 const args: []Value = if (args_val.castTag(.aggregate)) |some| some.data else &.{};
16360 var param_types = try sema.arena.alloc(Type, args.len);
16361 var comptime_params = try sema.arena.alloc(bool, args.len);
16362 var noalias_bits: u32 = 0;
16363 for (args) |arg, i| {
16364 const arg_val = arg.castTag(.aggregate).?.data;
16365 // TODO use reflection instead of magic numbers here
16366 // is_generic: bool,
16367 const arg_is_generic = arg_val[0].toBool();
16368 // is_noalias: bool,
16369 const arg_is_noalias = arg_val[1].toBool();
16370 // arg_type: ?type,
16371 const param_type_val = arg_val[2];
16372
16373 if (arg_is_generic) {
16374 return sema.fail(block, src, "Type.Fn.Param.is_generic must be false for @Type", .{});
16375 }
16376
16377 if (arg_is_noalias) {
16378 noalias_bits = @as(u32, 1) << (std.math.cast(u5, i) orelse
16379 return sema.fail(block, src, "this compiler implementation only supports 'noalias' on the first 32 parameters", .{}));
16380 }
16381
16382 const param_type = param_type_val.optionalValue() orelse
16383 return sema.fail(block, src, "Type.Fn.Param.arg_type must be non-null for @Type", .{});
16384
16385 param_types[i] = try param_type.toType(&buf).copy(sema.arena);
16386 }
16387
16388 const return_type = return_type_val.optionalValue() orelse
16389 return sema.fail(block, src, "Type.Fn.return_type must be non-null for @Type", .{});
16390
16391 var fn_info = Type.Payload.Function.Data{
16392 .param_types = param_types,
16393 .comptime_params = comptime_params.ptr,
16394 .noalias_bits = noalias_bits,
16395 .return_type = try return_type.toType(&buf).copy(sema.arena),
16396 .alignment = alignment,
16397 .cc = cc,
16398 .is_var_args = is_var_args,
16399 .is_generic = false,
16400 .align_is_generic = false,
16401 .cc_is_generic = false,
16402 .section_is_generic = false,
16403 .addrspace_is_generic = false,
16404 };
16405
16406 const ty = try Type.Tag.function.create(sema.arena, fn_info);
16407 return sema.addType(ty);
16408 },
1624316409 .BoundFn => @panic("TODO delete BoundFn from the language"),
1624416410 .Frame => @panic("TODO implement https://github.com/ziglang/zig/issues/10710"),
1624516411 }
......@@ -16382,6 +16548,11 @@ fn reifyStruct(
1638216548 // alignment: comptime_int,
1638316549 const alignment_val = field_struct_val[4];
1638416550
16551 if (!try sema.intFitsInType(block, src, alignment_val, Type.u32, null)) {
16552 return sema.fail(block, src, "alignment must fit in 'u32'", .{});
16553 }
16554 const abi_align = @intCast(u29, alignment_val.toUnsignedInt(target));
16555
1638516556 const field_name = try name_val.toAllocatedBytes(
1638616557 Type.initTag(.const_slice_u8),
1638716558 new_decl_arena_allocator,
......@@ -16405,7 +16576,7 @@ fn reifyStruct(
1640516576 var buffer: Value.ToTypeBuffer = undefined;
1640616577 gop.value_ptr.* = .{
1640716578 .ty = try field_type_val.toType(&buffer).copy(new_decl_arena_allocator),
16408 .abi_align = @intCast(u32, alignment_val.toUnsignedInt(target)),
16579 .abi_align = abi_align,
1640916580 .default_val = default_val,
1641016581 .is_comptime = is_comptime_val.toBool(),
1641116582 .offset = undefined,
......@@ -27314,7 +27485,8 @@ fn enumFieldSrcLoc(
2731427485 .container_decl_arg_trailing,
2731527486 => tree.containerDeclArg(enum_node),
2731627487
27317 else => unreachable,
27488 // Container was constructed with `@Type`.
27489 else => return LazySrcLoc.nodeOffset(node_offset),
2731827490 };
2731927491 var it_index: usize = 0;
2732027492 for (container_decl.ast.members) |member_node| {
src/value.zig+13
......@@ -2766,6 +2766,19 @@ pub const Value = extern union {
27662766 return self.isUndef();
27672767 }
27682768
2769 /// Returns true if any value contained in `self` is undefined.
2770 /// TODO: check for cases such as array that is not marked undef but all the element
2771 /// values are marked undef, or struct that is not marked undef but all fields are marked
2772 /// undef, etc.
2773 pub fn anyUndef(self: Value) bool {
2774 if (self.castTag(.aggregate)) |aggregate| {
2775 for (aggregate.data) |val| {
2776 if (val.anyUndef()) return true;
2777 }
2778 }
2779 return self.isUndef();
2780 }
2781
27692782 /// Asserts the value is not undefined and not unreachable.
27702783 /// Integer value 0 is considered null because of C pointers.
27712784 pub fn isNull(self: Value) bool {
test/cases/compile_errors/reify_type.Fn_with_is_generic_true.zig created+17
......@@ -0,0 +1,17 @@
1const Foo = @Type(.{
2 .Fn = .{
3 .calling_convention = .Unspecified,
4 .alignment = 0,
5 .is_generic = true,
6 .is_var_args = false,
7 .return_type = u0,
8 .args = &.{},
9 },
10});
11comptime { _ = Foo; }
12
13// error
14// backend=stage2
15// target=native
16//
17// :1:13: error: Type.Fn.is_generic must be false for @Type
test/cases/compile_errors/reify_type.Fn_with_is_var_args_true_and_non-C_callconv.zig created+17
......@@ -0,0 +1,17 @@
1const Foo = @Type(.{
2 .Fn = .{
3 .calling_convention = .Unspecified,
4 .alignment = 0,
5 .is_generic = false,
6 .is_var_args = true,
7 .return_type = u0,
8 .args = &.{},
9 },
10});
11comptime { _ = Foo; }
12
13// error
14// backend=stage2
15// target=native
16//
17// :1:13: error: varargs functions must have C calling convention
test/cases/compile_errors/reify_type.Fn_with_return_type_null.zig created+17
......@@ -0,0 +1,17 @@
1const Foo = @Type(.{
2 .Fn = .{
3 .calling_convention = .Unspecified,
4 .alignment = 0,
5 .is_generic = false,
6 .is_var_args = false,
7 .return_type = null,
8 .args = &.{},
9 },
10});
11comptime { _ = Foo; }
12
13// error
14// backend=stage2
15// target=native
16//
17// :1:13: error: Type.Fn.return_type must be non-null for @Type
test/cases/compile_errors/reify_type_for_exhaustive_enum_with_non-integer_tag_type.zig created+18
......@@ -0,0 +1,18 @@
1const Tag = @Type(.{
2 .Enum = .{
3 .layout = .Auto,
4 .tag_type = bool,
5 .fields = &.{},
6 .decls = &.{},
7 .is_exhaustive = false,
8 },
9});
10export fn entry() void {
11 _ = @intToEnum(Tag, 0);
12}
13
14// error
15// backend=stage2
16// target=native
17//
18// :1:13: error: Type.Enum.tag_type must be an integer type
test/cases/compile_errors/reify_type_for_exhaustive_enum_with_undefined_tag_type.zig created+18
......@@ -0,0 +1,18 @@
1const Tag = @Type(.{
2 .Enum = .{
3 .layout = .Auto,
4 .tag_type = undefined,
5 .fields = &.{},
6 .decls = &.{},
7 .is_exhaustive = false,
8 },
9});
10export fn entry() void {
11 _ = @intToEnum(Tag, 0);
12}
13
14// error
15// backend=stage2
16// target=native
17//
18// :1:13: error: use of undefined value here causes undefined behavior
test/cases/compile_errors/reify_type_for_exhaustive_enum_with_zero_fields.zig created+18
......@@ -0,0 +1,18 @@
1const Tag = @Type(.{
2 .Enum = .{
3 .layout = .Auto,
4 .tag_type = u1,
5 .fields = &.{},
6 .decls = &.{},
7 .is_exhaustive = true,
8 },
9});
10export fn entry() void {
11 _ = @intToEnum(Tag, 0);
12}
13
14// error
15// backend=stage2
16// target=native
17//
18// :1:13: error: enums must have at least one field
test/cases/compile_errors/reify_type_for_tagged_union_with_extra_enum_field.zig created+36
......@@ -0,0 +1,36 @@
1const Tag = @Type(.{
2 .Enum = .{
3 .layout = .Auto,
4 .tag_type = u2,
5 .fields = &.{
6 .{ .name = "signed", .value = 0 },
7 .{ .name = "unsigned", .value = 1 },
8 .{ .name = "arst", .value = 2 },
9 },
10 .decls = &.{},
11 .is_exhaustive = true,
12 },
13});
14const Tagged = @Type(.{
15 .Union = .{
16 .layout = .Auto,
17 .tag_type = Tag,
18 .fields = &.{
19 .{ .name = "signed", .field_type = i32, .alignment = @alignOf(i32) },
20 .{ .name = "unsigned", .field_type = u32, .alignment = @alignOf(u32) },
21 },
22 .decls = &.{},
23 },
24});
25export fn entry() void {
26 var tagged = Tagged{ .signed = -1 };
27 tagged = .{ .unsigned = 1 };
28}
29
30// error
31// backend=stage2
32// target=native
33//
34// :14:16: error: enum field(s) missing in union
35// :1:13: note: field 'arst' missing, declared here
36// :1:13: note: enum declared here
test/cases/compile_errors/reify_type_for_tagged_union_with_extra_union_field.zig created+35
......@@ -0,0 +1,35 @@
1const Tag = @Type(.{
2 .Enum = .{
3 .layout = .Auto,
4 .tag_type = u1,
5 .fields = &.{
6 .{ .name = "signed", .value = 0 },
7 .{ .name = "unsigned", .value = 1 },
8 },
9 .decls = &.{},
10 .is_exhaustive = true,
11 },
12});
13const Tagged = @Type(.{
14 .Union = .{
15 .layout = .Auto,
16 .tag_type = Tag,
17 .fields = &.{
18 .{ .name = "signed", .field_type = i32, .alignment = @alignOf(i32) },
19 .{ .name = "unsigned", .field_type = u32, .alignment = @alignOf(u32) },
20 .{ .name = "arst", .field_type = f32, .alignment = @alignOf(f32) },
21 },
22 .decls = &.{},
23 },
24});
25export fn entry() void {
26 var tagged = Tagged{ .signed = -1 };
27 tagged = .{ .unsigned = 1 };
28}
29
30// error
31// backend=stage2
32// target=native
33//
34// :13:16: error: no field named 'arst' in enum 'tmp.Tag__enum_264'
35// :1:13: note: enum declared here
test/cases/compile_errors/reify_type_for_union_with_zero_fields.zig created+17
......@@ -0,0 +1,17 @@
1const Untagged = @Type(.{
2 .Union = .{
3 .layout = .Auto,
4 .tag_type = null,
5 .fields = &.{},
6 .decls = &.{},
7 },
8});
9export fn entry() void {
10 _ = Untagged{};
11}
12
13// error
14// backend=stage2
15// target=native
16//
17// :1:18: error: unions must have at least one field
test/cases/compile_errors/reify_type_union_payload_is_undefined.zig created+10
......@@ -0,0 +1,10 @@
1const Foo = @Type(.{
2 .Struct = undefined,
3});
4comptime { _ = Foo; }
5
6// error
7// backend=stage2
8// target=native
9//
10// :1:13: error: use of undefined value here causes undefined behavior
test/cases/compile_errors/reify_type_with_Type.Int.zig created+15
......@@ -0,0 +1,15 @@
1const builtin = @import("std").builtin;
2export fn entry() void {
3 _ = @Type(builtin.Type.Int{
4 .signedness = .signed,
5 .bits = 8,
6 });
7}
8
9// error
10// backend=stage2
11// target=native
12//
13// :3:31: error: expected type 'builtin.Type', found 'builtin.Type.Int'
14// :?:?: note: struct declared here
15// :?:?: note: union declared here
test/cases/compile_errors/reify_type_with_undefined.zig created+20
......@@ -0,0 +1,20 @@
1comptime {
2 _ = @Type(.{ .Array = .{ .len = 0, .child = u8, .sentinel = undefined } });
3}
4comptime {
5 _ = @Type(.{
6 .Struct = .{
7 .fields = undefined,
8 .decls = undefined,
9 .is_tuple = false,
10 .layout = .Auto,
11 },
12 });
13}
14
15// error
16// backend=stage2
17// target=native
18//
19// :2:9: error: use of undefined value here causes undefined behavior
20// :5:9: error: use of undefined value here causes undefined behavior
test/cases/compile_errors/stage1/obj/reify_type.Fn_with_is_generic_true.zig deleted-17
......@@ -1,17 +0,0 @@
1const Foo = @Type(.{
2 .Fn = .{
3 .calling_convention = .Unspecified,
4 .alignment = 0,
5 .is_generic = true,
6 .is_var_args = false,
7 .return_type = u0,
8 .args = &.{},
9 },
10});
11comptime { _ = Foo; }
12
13// error
14// backend=stage1
15// target=native
16//
17// tmp.zig:1:20: error: Type.Fn.is_generic must be false for @Type
test/cases/compile_errors/stage1/obj/reify_type.Fn_with_is_var_args_true_and_non-C_callconv.zig deleted-17
......@@ -1,17 +0,0 @@
1const Foo = @Type(.{
2 .Fn = .{
3 .calling_convention = .Unspecified,
4 .alignment = 0,
5 .is_generic = false,
6 .is_var_args = true,
7 .return_type = u0,
8 .args = &.{},
9 },
10});
11comptime { _ = Foo; }
12
13// error
14// backend=stage1
15// target=native
16//
17// tmp.zig:1:20: error: varargs functions must have C calling convention
test/cases/compile_errors/stage1/obj/reify_type.Fn_with_return_type_null.zig deleted-17
......@@ -1,17 +0,0 @@
1const Foo = @Type(.{
2 .Fn = .{
3 .calling_convention = .Unspecified,
4 .alignment = 0,
5 .is_generic = false,
6 .is_var_args = false,
7 .return_type = null,
8 .args = &.{},
9 },
10});
11comptime { _ = Foo; }
12
13// error
14// backend=stage1
15// target=native
16//
17// tmp.zig:1:20: error: Type.Fn.return_type must be non-null for @Type
test/cases/compile_errors/stage1/obj/reify_type.Pointer_with_invalid_address_space.zig deleted-18
......@@ -1,18 +0,0 @@
1export fn entry() void {
2 _ = @Type(.{ .Pointer = .{
3 .size = .One,
4 .is_const = false,
5 .is_volatile = false,
6 .alignment = 1,
7 .address_space = .gs,
8 .child = u8,
9 .is_allowzero = false,
10 .sentinel = null,
11 }});
12}
13
14// error
15// backend=stage1
16// target=native
17//
18// tmp.zig:2:16: error: address space 'gs' not available in stage 1 compiler, must be .generic
test/cases/compile_errors/stage1/obj/reify_type_for_exhaustive_enum_with_non-integer_tag_type.zig deleted-18
......@@ -1,18 +0,0 @@
1const Tag = @Type(.{
2 .Enum = .{
3 .layout = .Auto,
4 .tag_type = bool,
5 .fields = &.{},
6 .decls = &.{},
7 .is_exhaustive = false,
8 },
9});
10export fn entry() void {
11 _ = @intToEnum(Tag, 0);
12}
13
14// error
15// backend=stage1
16// target=native
17//
18// tmp.zig:1:20: error: Type.Enum.tag_type must be an integer type, not 'bool'
test/cases/compile_errors/stage1/obj/reify_type_for_exhaustive_enum_with_undefined_tag_type.zig deleted-18
......@@ -1,18 +0,0 @@
1const Tag = @Type(.{
2 .Enum = .{
3 .layout = .Auto,
4 .tag_type = undefined,
5 .fields = &.{},
6 .decls = &.{},
7 .is_exhaustive = false,
8 },
9});
10export fn entry() void {
11 _ = @intToEnum(Tag, 0);
12}
13
14// error
15// backend=stage1
16// target=native
17//
18// tmp.zig:1:20: error: use of undefined value here causes undefined behavior
test/cases/compile_errors/stage1/obj/reify_type_for_exhaustive_enum_with_zero_fields.zig deleted-18
......@@ -1,18 +0,0 @@
1const Tag = @Type(.{
2 .Enum = .{
3 .layout = .Auto,
4 .tag_type = u1,
5 .fields = &.{},
6 .decls = &.{},
7 .is_exhaustive = true,
8 },
9});
10export fn entry() void {
11 _ = @intToEnum(Tag, 0);
12}
13
14// error
15// backend=stage1
16// target=native
17//
18// tmp.zig:1:20: error: enums must have 1 or more fields
test/cases/compile_errors/stage1/obj/reify_type_for_tagged_union_with_extra_enum_field.zig deleted-34
......@@ -1,34 +0,0 @@
1const Tag = @Type(.{
2 .Enum = .{
3 .layout = .Auto,
4 .tag_type = u2,
5 .fields = &.{
6 .{ .name = "signed", .value = 0 },
7 .{ .name = "unsigned", .value = 1 },
8 .{ .name = "arst", .value = 2 },
9 },
10 .decls = &.{},
11 .is_exhaustive = true,
12 },
13});
14const Tagged = @Type(.{
15 .Union = .{
16 .layout = .Auto,
17 .tag_type = Tag,
18 .fields = &.{
19 .{ .name = "signed", .field_type = i32, .alignment = @alignOf(i32) },
20 .{ .name = "unsigned", .field_type = u32, .alignment = @alignOf(u32) },
21 },
22 .decls = &.{},
23 },
24});
25export fn entry() void {
26 var tagged = Tagged{ .signed = -1 };
27 tagged = .{ .unsigned = 1 };
28}
29
30// error
31// backend=stage1
32// target=native
33//
34// tmp.zig:14:23: error: enum field missing: 'arst'
test/cases/compile_errors/stage1/obj/reify_type_for_tagged_union_with_extra_union_field.zig deleted-35
......@@ -1,35 +0,0 @@
1const Tag = @Type(.{
2 .Enum = .{
3 .layout = .Auto,
4 .tag_type = u1,
5 .fields = &.{
6 .{ .name = "signed", .value = 0 },
7 .{ .name = "unsigned", .value = 1 },
8 },
9 .decls = &.{},
10 .is_exhaustive = true,
11 },
12});
13const Tagged = @Type(.{
14 .Union = .{
15 .layout = .Auto,
16 .tag_type = Tag,
17 .fields = &.{
18 .{ .name = "signed", .field_type = i32, .alignment = @alignOf(i32) },
19 .{ .name = "unsigned", .field_type = u32, .alignment = @alignOf(u32) },
20 .{ .name = "arst", .field_type = f32, .alignment = @alignOf(f32) },
21 },
22 .decls = &.{},
23 },
24});
25export fn entry() void {
26 var tagged = Tagged{ .signed = -1 };
27 tagged = .{ .unsigned = 1 };
28}
29
30// error
31// backend=stage1
32// target=native
33//
34// tmp.zig:13:23: error: enum field not found: 'arst'
35// tmp.zig:1:20: note: enum declared here
test/cases/compile_errors/stage1/obj/reify_type_for_union_with_zero_fields.zig deleted-17
......@@ -1,17 +0,0 @@
1const Untagged = @Type(.{
2 .Union = .{
3 .layout = .Auto,
4 .tag_type = null,
5 .fields = &.{},
6 .decls = &.{},
7 },
8});
9export fn entry() void {
10 _ = Untagged{};
11}
12
13// error
14// backend=stage1
15// target=native
16//
17// tmp.zig:1:25: error: unions must have 1 or more fields
test/cases/compile_errors/stage1/obj/reify_type_union_payload_is_undefined.zig deleted-10
......@@ -1,10 +0,0 @@
1const Foo = @Type(.{
2 .Struct = undefined,
3});
4comptime { _ = Foo; }
5
6// error
7// backend=stage1
8// target=native
9//
10// tmp.zig:1:20: error: use of undefined value here causes undefined behavior
test/cases/compile_errors/stage1/obj/reify_type_with_Type.Int.zig deleted-13
......@@ -1,13 +0,0 @@
1const builtin = @import("std").builtin;
2export fn entry() void {
3 _ = @Type(builtin.Type.Int{
4 .signedness = .signed,
5 .bits = 8,
6 });
7}
8
9// error
10// backend=stage1
11// target=native
12//
13// tmp.zig:3:31: error: expected type 'std.builtin.Type', found 'std.builtin.Type.Int'
test/cases/compile_errors/stage1/obj/reify_type_with_non-constant_expression.zig deleted-11
......@@ -1,11 +0,0 @@
1const builtin = @import("std").builtin;
2var globalTypeInfo : builtin.Type = undefined;
3export fn entry() void {
4 _ = @Type(globalTypeInfo);
5}
6
7// error
8// backend=stage1
9// target=native
10//
11// tmp.zig:4:15: error: unable to evaluate constant expression
test/cases/compile_errors/stage1/obj/reify_type_with_undefined.zig deleted-20
......@@ -1,20 +0,0 @@
1comptime {
2 _ = @Type(.{ .Array = .{ .len = 0, .child = u8, .sentinel = undefined } });
3}
4comptime {
5 _ = @Type(.{
6 .Struct = .{
7 .fields = undefined,
8 .decls = undefined,
9 .is_tuple = false,
10 .layout = .Auto,
11 },
12 });
13}
14
15// error
16// backend=stage1
17// target=native
18//
19// tmp.zig:2:16: error: use of undefined value here causes undefined behavior
20// tmp.zig:5:16: error: use of undefined value here causes undefined behavior
test/cases/compile_errors/stage1/reify_type.Pointer_with_invalid_address_space.zig created+18
......@@ -0,0 +1,18 @@
1export fn entry() void {
2 _ = @Type(.{ .Pointer = .{
3 .size = .One,
4 .is_const = false,
5 .is_volatile = false,
6 .alignment = 1,
7 .address_space = .gs,
8 .child = u8,
9 .is_allowzero = false,
10 .sentinel = null,
11 }});
12}
13
14// error
15// backend=stage1
16// target=native
17//
18// tmp.zig:2:16: error: address space 'gs' not available in stage 1 compiler, must be .generic
test/cases/compile_errors/stage1/reify_type_with_non-constant_expression.zig created+11
......@@ -0,0 +1,11 @@
1const builtin = @import("std").builtin;
2var globalTypeInfo : builtin.Type = undefined;
3export fn entry() void {
4 _ = @Type(globalTypeInfo);
5}
6
7// error
8// backend=stage1
9// target=native
10//
11// tmp.zig:4:15: error: unable to evaluate constant expression