| author | |
| committer | |
| log | 17622b9db14cb1d8dd600b21f60c8a1041e5b0e1 |
| tree | 52f10980d6ac1bce333079f4f92fb7aa789ca874 |
| parent | f43ea43ac920d3fbd629175e4e7fbe4309c6eab5 |
Closes #1228030 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 |
| 15759 | 15759 | const tag_ty = type_info_ty.unionTagType().?; |
| 15760 | 15760 | const target = mod.getTarget(); |
| 15761 | 15761 | const tag_index = tag_ty.enumTagFieldIndex(union_val.tag, mod).?; |
| 15762 | if (union_val.val.anyUndef()) return sema.failWithUseOfUndef(block, src); | |
| 15762 | 15763 | switch (@intToEnum(std.builtin.TypeId, tag_index)) { |
| 15763 | 15764 | .Type => return Air.Inst.Ref.type_type, |
| 15764 | 15765 | .Void => return Air.Inst.Ref.void_type, |
| ... | ... | @@ -15828,7 +15829,10 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I |
| 15828 | 15829 | const is_allowzero_val = struct_val[6]; |
| 15829 | 15830 | const sentinel_val = struct_val[7]; |
| 15830 | 15831 | |
| 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)); | |
| 15832 | 15836 | |
| 15833 | 15837 | var buffer: Value.ToTypeBuffer = undefined; |
| 15834 | 15838 | 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 |
| 15855 | 15859 | actual_sentinel = (try sema.pointerDeref(block, src, sentinel_ptr_val, ptr_ty)).?; |
| 15856 | 15860 | } |
| 15857 | 15861 | |
| 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 | ||
| 15858 | 15895 | const ty = try Type.ptr(sema.arena, mod, .{ |
| 15859 | 15896 | .size = ptr_size, |
| 15860 | 15897 | .mutable = !is_const_val.toBool(), |
| ... | ... | @@ -15915,6 +15952,10 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I |
| 15915 | 15952 | const error_set_ty = try error_set_val.toType(&buffer).copy(sema.arena); |
| 15916 | 15953 | const payload_ty = try payload_val.toType(&buffer).copy(sema.arena); |
| 15917 | 15954 | |
| 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 | ||
| 15918 | 15959 | const ty = try Type.Tag.error_union.create(sema.arena, .{ |
| 15919 | 15960 | .error_set = error_set_ty, |
| 15920 | 15961 | .payload = payload_ty, |
| ... | ... | @@ -15928,7 +15969,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I |
| 15928 | 15969 | const decl_index = slice_val.ptr.pointerDecl().?; |
| 15929 | 15970 | try sema.ensureDeclAnalyzed(decl_index); |
| 15930 | 15971 | 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 &.{}; | |
| 15932 | 15973 | |
| 15933 | 15974 | var names: Module.ErrorSet.NameMap = .{}; |
| 15934 | 15975 | 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 |
| 15940 | 15981 | const name_str = try name_val.toAllocatedBytes(Type.initTag(.const_slice_u8), sema.arena, sema.mod); |
| 15941 | 15982 | |
| 15942 | 15983 | 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 | } | |
| 15944 | 15988 | } |
| 15945 | 15989 | |
| 15946 | 15990 | // names must be sorted |
| ... | ... | @@ -16022,13 +16066,9 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I |
| 16022 | 16066 | new_decl.owns_tv = true; |
| 16023 | 16067 | errdefer mod.abortAnonDecl(new_decl_index); |
| 16024 | 16068 | |
| 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 | ||
| 16029 | 16069 | enum_obj.* = .{ |
| 16030 | 16070 | .owner_decl = new_decl_index, |
| 16031 | .tag_ty = int_tag_ty, | |
| 16071 | .tag_ty = Type.@"null", | |
| 16032 | 16072 | .tag_ty_inferred = false, |
| 16033 | 16073 | .fields = .{}, |
| 16034 | 16074 | .values = .{}, |
| ... | ... | @@ -16040,6 +16080,15 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I |
| 16040 | 16080 | }, |
| 16041 | 16081 | }; |
| 16042 | 16082 | |
| 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 | ||
| 16043 | 16092 | // Fields |
| 16044 | 16093 | const fields_len = try sema.usizeCast(block, src, fields_val.sliceLen(mod)); |
| 16045 | 16094 | if (fields_len > 0) { |
| ... | ... | @@ -16077,6 +16126,8 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I |
| 16077 | 16126 | .mod = mod, |
| 16078 | 16127 | }); |
| 16079 | 16128 | } |
| 16129 | } else { | |
| 16130 | return sema.fail(block, src, "enums must have at least one field", .{}); | |
| 16080 | 16131 | } |
| 16081 | 16132 | |
| 16082 | 16133 | try new_decl.finalizeNewArena(&new_decl_arena); |
| ... | ... | @@ -16186,11 +16237,17 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I |
| 16186 | 16237 | }; |
| 16187 | 16238 | |
| 16188 | 16239 | // Tag type |
| 16240 | var tag_ty_field_names: ?Module.EnumFull.NameMap = null; | |
| 16189 | 16241 | var enum_field_names: ?*Module.EnumNumbered.NameMap = null; |
| 16190 | 16242 | const fields_len = try sema.usizeCast(block, src, fields_val.sliceLen(mod)); |
| 16191 | 16243 | if (tag_type_val.optionalValue()) |payload_val| { |
| 16192 | 16244 | var buffer: Value.ToTypeBuffer = undefined; |
| 16193 | 16245 | 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); | |
| 16194 | 16251 | } else { |
| 16195 | 16252 | union_obj.tag_ty = try sema.generateUnionTagTypeSimple(block, fields_len, null); |
| 16196 | 16253 | 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 |
| 16222 | 16279 | set.putAssumeCapacity(field_name, {}); |
| 16223 | 16280 | } |
| 16224 | 16281 | |
| 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 | ||
| 16225 | 16295 | const gop = union_obj.fields.getOrPutAssumeCapacity(field_name); |
| 16226 | 16296 | if (gop.found_existing) { |
| 16227 | 16297 | // TODO: better source location |
| ... | ... | @@ -16234,12 +16304,108 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I |
| 16234 | 16304 | .abi_align = @intCast(u32, alignment_val.toUnsignedInt(target)), |
| 16235 | 16305 | }; |
| 16236 | 16306 | } |
| 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 | } | |
| 16237 | 16327 | } |
| 16238 | 16328 | |
| 16239 | 16329 | try new_decl.finalizeNewArena(&new_decl_arena); |
| 16240 | 16330 | return sema.analyzeDeclVal(block, src, new_decl_index); |
| 16241 | 16331 | }, |
| 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 | }, | |
| 16243 | 16409 | .BoundFn => @panic("TODO delete BoundFn from the language"), |
| 16244 | 16410 | .Frame => @panic("TODO implement https://github.com/ziglang/zig/issues/10710"), |
| 16245 | 16411 | } |
| ... | ... | @@ -16382,6 +16548,11 @@ fn reifyStruct( |
| 16382 | 16548 | // alignment: comptime_int, |
| 16383 | 16549 | const alignment_val = field_struct_val[4]; |
| 16384 | 16550 | |
| 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 | ||
| 16385 | 16556 | const field_name = try name_val.toAllocatedBytes( |
| 16386 | 16557 | Type.initTag(.const_slice_u8), |
| 16387 | 16558 | new_decl_arena_allocator, |
| ... | ... | @@ -16405,7 +16576,7 @@ fn reifyStruct( |
| 16405 | 16576 | var buffer: Value.ToTypeBuffer = undefined; |
| 16406 | 16577 | gop.value_ptr.* = .{ |
| 16407 | 16578 | .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, | |
| 16409 | 16580 | .default_val = default_val, |
| 16410 | 16581 | .is_comptime = is_comptime_val.toBool(), |
| 16411 | 16582 | .offset = undefined, |
| ... | ... | @@ -27314,7 +27485,8 @@ fn enumFieldSrcLoc( |
| 27314 | 27485 | .container_decl_arg_trailing, |
| 27315 | 27486 | => tree.containerDeclArg(enum_node), |
| 27316 | 27487 | |
| 27317 | else => unreachable, | |
| 27488 | // Container was constructed with `@Type`. | |
| 27489 | else => return LazySrcLoc.nodeOffset(node_offset), | |
| 27318 | 27490 | }; |
| 27319 | 27491 | var it_index: usize = 0; |
| 27320 | 27492 | for (container_decl.ast.members) |member_node| { |
src/value.zig+13| ... | ... | @@ -2766,6 +2766,19 @@ pub const Value = extern union { |
| 2766 | 2766 | return self.isUndef(); |
| 2767 | 2767 | } |
| 2768 | 2768 | |
| 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 | ||
| 2769 | 2782 | /// Asserts the value is not undefined and not unreachable. |
| 2770 | 2783 | /// Integer value 0 is considered null because of C pointers. |
| 2771 | 2784 | pub fn isNull(self: Value) bool { |
test/cases/compile_errors/reify_type.Fn_with_is_generic_true.zig created+17| ... | ... | @@ -0,0 +1,17 @@ |
| 1 | const 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 | }); | |
| 11 | comptime { _ = 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 @@ |
| 1 | const 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 | }); | |
| 11 | comptime { _ = 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 @@ |
| 1 | const 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 | }); | |
| 11 | comptime { _ = 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 @@ |
| 1 | const Tag = @Type(.{ | |
| 2 | .Enum = .{ | |
| 3 | .layout = .Auto, | |
| 4 | .tag_type = bool, | |
| 5 | .fields = &.{}, | |
| 6 | .decls = &.{}, | |
| 7 | .is_exhaustive = false, | |
| 8 | }, | |
| 9 | }); | |
| 10 | export 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 @@ |
| 1 | const Tag = @Type(.{ | |
| 2 | .Enum = .{ | |
| 3 | .layout = .Auto, | |
| 4 | .tag_type = undefined, | |
| 5 | .fields = &.{}, | |
| 6 | .decls = &.{}, | |
| 7 | .is_exhaustive = false, | |
| 8 | }, | |
| 9 | }); | |
| 10 | export 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 @@ |
| 1 | const Tag = @Type(.{ | |
| 2 | .Enum = .{ | |
| 3 | .layout = .Auto, | |
| 4 | .tag_type = u1, | |
| 5 | .fields = &.{}, | |
| 6 | .decls = &.{}, | |
| 7 | .is_exhaustive = true, | |
| 8 | }, | |
| 9 | }); | |
| 10 | export 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 @@ |
| 1 | const 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 | }); | |
| 14 | const 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 | }); | |
| 25 | export 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 @@ |
| 1 | const 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 | }); | |
| 13 | const 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 | }); | |
| 25 | export 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 @@ |
| 1 | const Untagged = @Type(.{ | |
| 2 | .Union = .{ | |
| 3 | .layout = .Auto, | |
| 4 | .tag_type = null, | |
| 5 | .fields = &.{}, | |
| 6 | .decls = &.{}, | |
| 7 | }, | |
| 8 | }); | |
| 9 | export 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 @@ |
| 1 | const Foo = @Type(.{ | |
| 2 | .Struct = undefined, | |
| 3 | }); | |
| 4 | comptime { _ = 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 @@ |
| 1 | const builtin = @import("std").builtin; | |
| 2 | export 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 @@ |
| 1 | comptime { | |
| 2 | _ = @Type(.{ .Array = .{ .len = 0, .child = u8, .sentinel = undefined } }); | |
| 3 | } | |
| 4 | comptime { | |
| 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 @@ |
| 1 | const 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 | }); | |
| 11 | comptime { _ = 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 @@ |
| 1 | const 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 | }); | |
| 11 | comptime { _ = 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 @@ |
| 1 | const 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 | }); | |
| 11 | comptime { _ = 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 @@ |
| 1 | export 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 @@ |
| 1 | const Tag = @Type(.{ | |
| 2 | .Enum = .{ | |
| 3 | .layout = .Auto, | |
| 4 | .tag_type = bool, | |
| 5 | .fields = &.{}, | |
| 6 | .decls = &.{}, | |
| 7 | .is_exhaustive = false, | |
| 8 | }, | |
| 9 | }); | |
| 10 | export 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 @@ |
| 1 | const Tag = @Type(.{ | |
| 2 | .Enum = .{ | |
| 3 | .layout = .Auto, | |
| 4 | .tag_type = undefined, | |
| 5 | .fields = &.{}, | |
| 6 | .decls = &.{}, | |
| 7 | .is_exhaustive = false, | |
| 8 | }, | |
| 9 | }); | |
| 10 | export 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 @@ |
| 1 | const Tag = @Type(.{ | |
| 2 | .Enum = .{ | |
| 3 | .layout = .Auto, | |
| 4 | .tag_type = u1, | |
| 5 | .fields = &.{}, | |
| 6 | .decls = &.{}, | |
| 7 | .is_exhaustive = true, | |
| 8 | }, | |
| 9 | }); | |
| 10 | export 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 @@ |
| 1 | const 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 | }); | |
| 14 | const 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 | }); | |
| 25 | export 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 @@ |
| 1 | const 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 | }); | |
| 13 | const 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 | }); | |
| 25 | export 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 @@ |
| 1 | const Untagged = @Type(.{ | |
| 2 | .Union = .{ | |
| 3 | .layout = .Auto, | |
| 4 | .tag_type = null, | |
| 5 | .fields = &.{}, | |
| 6 | .decls = &.{}, | |
| 7 | }, | |
| 8 | }); | |
| 9 | export 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 @@ |
| 1 | const Foo = @Type(.{ | |
| 2 | .Struct = undefined, | |
| 3 | }); | |
| 4 | comptime { _ = 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 @@ |
| 1 | const builtin = @import("std").builtin; | |
| 2 | export 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 @@ |
| 1 | const builtin = @import("std").builtin; | |
| 2 | var globalTypeInfo : builtin.Type = undefined; | |
| 3 | export 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 @@ |
| 1 | comptime { | |
| 2 | _ = @Type(.{ .Array = .{ .len = 0, .child = u8, .sentinel = undefined } }); | |
| 3 | } | |
| 4 | comptime { | |
| 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 @@ |
| 1 | export 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 @@ |
| 1 | const builtin = @import("std").builtin; | |
| 2 | var globalTypeInfo : builtin.Type = undefined; | |
| 3 | export 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 |