authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-07-31 12:57:53-07:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2022-07-31 12:57:53-07:00
log1ab15b6c9c529c9acc85f4b0bf3fcaea97a5a48e
treef4c713785c0fa760ab8da49fcea5a90a841111dc
parentb35490c21732d74232680d2de2deb89f97356c0d
parent02dc0732604236a57b43b9612d9b0571f06f905a
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #12289 from Vexu/stage2

Stage2: reify functions + fixes

47 files changed, 1075 insertions(+), 662 deletions(-)

lib/std/zig/parse.zig+1-1
...@@ -3257,7 +3257,7 @@ const Parser = struct {...@@ -3257,7 +3257,7 @@ const Parser = struct {
3257 if (p.eatToken(.ellipsis2)) |_| {3257 if (p.eatToken(.ellipsis2)) |_| {
3258 const end_expr = try p.parseExpr();3258 const end_expr = try p.parseExpr();
3259 if (p.eatToken(.colon)) |_| {3259 if (p.eatToken(.colon)) |_| {
3260 const sentinel = try p.parseExpr();3260 const sentinel = try p.expectExpr();
3261 _ = try p.expectToken(.r_bracket);3261 _ = try p.expectToken(.r_bracket);
3262 return p.addNode(.{3262 return p.addNode(.{
3263 .tag = .slice_sentinel,3263 .tag = .slice_sentinel,
lib/std/zig/parser_test.zig+8
...@@ -5118,6 +5118,14 @@ test "zig fmt: while continue expr" {...@@ -5118,6 +5118,14 @@ test "zig fmt: while continue expr" {
5118 });5118 });
5119}5119}
51205120
5121test "zig fmt: error for missing sentinel value in sentinel slice" {
5122 try testError(
5123 \\const foo = foo[0..:];
5124 , &[_]Error{
5125 .expected_expr,
5126 });
5127}
5128
5121test "zig fmt: error for invalid bit range" {5129test "zig fmt: error for invalid bit range" {
5122 try testError(5130 try testError(
5123 \\var x: []align(0:0:0)u8 = bar;5131 \\var x: []align(0:0:0)u8 = bar;
src/Sema.zig+371-26
...@@ -15759,6 +15759,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I...@@ -15759,6 +15759,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
15759 const tag_ty = type_info_ty.unionTagType().?;15759 const tag_ty = type_info_ty.unionTagType().?;
15760 const target = mod.getTarget();15760 const target = mod.getTarget();
15761 const tag_index = tag_ty.enumTagFieldIndex(union_val.tag, mod).?;15761 const tag_index = tag_ty.enumTagFieldIndex(union_val.tag, mod).?;
15762 if (union_val.val.anyUndef()) return sema.failWithUseOfUndef(block, src);
15762 switch (@intToEnum(std.builtin.TypeId, tag_index)) {15763 switch (@intToEnum(std.builtin.TypeId, tag_index)) {
15763 .Type => return Air.Inst.Ref.type_type,15764 .Type => return Air.Inst.Ref.type_type,
15764 .Void => return Air.Inst.Ref.void_type,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,7 +15829,10 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
15828 const is_allowzero_val = struct_val[6];15829 const is_allowzero_val = struct_val[6];
15829 const sentinel_val = struct_val[7];15830 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
15833 var buffer: Value.ToTypeBuffer = undefined;15837 var buffer: Value.ToTypeBuffer = undefined;
15834 const unresolved_elem_ty = child_val.toType(&buffer);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,6 +15859,39 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
15855 actual_sentinel = (try sema.pointerDeref(block, src, sentinel_ptr_val, ptr_ty)).?;15859 actual_sentinel = (try sema.pointerDeref(block, src, sentinel_ptr_val, ptr_ty)).?;
15856 }15860 }
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
15858 const ty = try Type.ptr(sema.arena, mod, .{15895 const ty = try Type.ptr(sema.arena, mod, .{
15859 .size = ptr_size,15896 .size = ptr_size,
15860 .mutable = !is_const_val.toBool(),15897 .mutable = !is_const_val.toBool(),
...@@ -15915,6 +15952,10 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I...@@ -15915,6 +15952,10 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
15915 const error_set_ty = try error_set_val.toType(&buffer).copy(sema.arena);15952 const error_set_ty = try error_set_val.toType(&buffer).copy(sema.arena);
15916 const payload_ty = try payload_val.toType(&buffer).copy(sema.arena);15953 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
15918 const ty = try Type.Tag.error_union.create(sema.arena, .{15959 const ty = try Type.Tag.error_union.create(sema.arena, .{
15919 .error_set = error_set_ty,15960 .error_set = error_set_ty,
15920 .payload = payload_ty,15961 .payload = payload_ty,
...@@ -15928,7 +15969,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I...@@ -15928,7 +15969,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
15928 const decl_index = slice_val.ptr.pointerDecl().?;15969 const decl_index = slice_val.ptr.pointerDecl().?;
15929 try sema.ensureDeclAnalyzed(decl_index);15970 try sema.ensureDeclAnalyzed(decl_index);
15930 const decl = mod.declPtr(decl_index);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 &.{};
1593215973
15933 var names: Module.ErrorSet.NameMap = .{};15974 var names: Module.ErrorSet.NameMap = .{};
15934 try names.ensureUnusedCapacity(sema.arena, array_val.len);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,7 +15981,10 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
15940 const name_str = try name_val.toAllocatedBytes(Type.initTag(.const_slice_u8), sema.arena, sema.mod);15981 const name_str = try name_val.toAllocatedBytes(Type.initTag(.const_slice_u8), sema.arena, sema.mod);
1594115982
15942 const kv = try mod.getErrorValue(name_str);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 }
1594515989
15946 // names must be sorted15990 // names must be sorted
...@@ -16022,13 +16066,9 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I...@@ -16022,13 +16066,9 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
16022 new_decl.owns_tv = true;16066 new_decl.owns_tv = true;
16023 errdefer mod.abortAnonDecl(new_decl_index);16067 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
16029 enum_obj.* = .{16069 enum_obj.* = .{
16030 .owner_decl = new_decl_index,16070 .owner_decl = new_decl_index,
16031 .tag_ty = int_tag_ty,16071 .tag_ty = Type.@"null",
16032 .tag_ty_inferred = false,16072 .tag_ty_inferred = false,
16033 .fields = .{},16073 .fields = .{},
16034 .values = .{},16074 .values = .{},
...@@ -16040,6 +16080,15 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I...@@ -16040,6 +16080,15 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
16040 },16080 },
16041 };16081 };
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
16043 // Fields16092 // Fields
16044 const fields_len = try sema.usizeCast(block, src, fields_val.sliceLen(mod));16093 const fields_len = try sema.usizeCast(block, src, fields_val.sliceLen(mod));
16045 if (fields_len > 0) {16094 if (fields_len > 0) {
...@@ -16077,6 +16126,8 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I...@@ -16077,6 +16126,8 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
16077 .mod = mod,16126 .mod = mod,
16078 });16127 });
16079 }16128 }
16129 } else {
16130 return sema.fail(block, src, "enums must have at least one field", .{});
16080 }16131 }
1608116132
16082 try new_decl.finalizeNewArena(&new_decl_arena);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,11 +16237,17 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
16186 };16237 };
1618716238
16188 // Tag type16239 // Tag type
16240 var tag_ty_field_names: ?Module.EnumFull.NameMap = null;
16189 var enum_field_names: ?*Module.EnumNumbered.NameMap = null;16241 var enum_field_names: ?*Module.EnumNumbered.NameMap = null;
16190 const fields_len = try sema.usizeCast(block, src, fields_val.sliceLen(mod));16242 const fields_len = try sema.usizeCast(block, src, fields_val.sliceLen(mod));
16191 if (tag_type_val.optionalValue()) |payload_val| {16243 if (tag_type_val.optionalValue()) |payload_val| {
16192 var buffer: Value.ToTypeBuffer = undefined;16244 var buffer: Value.ToTypeBuffer = undefined;
16193 union_obj.tag_ty = try payload_val.toType(&buffer).copy(new_decl_arena_allocator);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 } else {16251 } else {
16195 union_obj.tag_ty = try sema.generateUnionTagTypeSimple(block, fields_len, null);16252 union_obj.tag_ty = try sema.generateUnionTagTypeSimple(block, fields_len, null);
16196 enum_field_names = &union_obj.tag_ty.castTag(.enum_simple).?.data.fields;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,6 +16279,19 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
16222 set.putAssumeCapacity(field_name, {});16279 set.putAssumeCapacity(field_name, {});
16223 }16280 }
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
16225 const gop = union_obj.fields.getOrPutAssumeCapacity(field_name);16295 const gop = union_obj.fields.getOrPutAssumeCapacity(field_name);
16226 if (gop.found_existing) {16296 if (gop.found_existing) {
16227 // TODO: better source location16297 // TODO: better source location
...@@ -16234,12 +16304,108 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I...@@ -16234,12 +16304,108 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
16234 .abi_align = @intCast(u32, alignment_val.toUnsignedInt(target)),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 }
1623816328
16239 try new_decl.finalizeNewArena(&new_decl_arena);16329 try new_decl.finalizeNewArena(&new_decl_arena);
16240 return sema.analyzeDeclVal(block, src, new_decl_index);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 .BoundFn => @panic("TODO delete BoundFn from the language"),16409 .BoundFn => @panic("TODO delete BoundFn from the language"),
16244 .Frame => @panic("TODO implement https://github.com/ziglang/zig/issues/10710"),16410 .Frame => @panic("TODO implement https://github.com/ziglang/zig/issues/10710"),
16245 }16411 }
...@@ -16382,6 +16548,11 @@ fn reifyStruct(...@@ -16382,6 +16548,11 @@ fn reifyStruct(
16382 // alignment: comptime_int,16548 // alignment: comptime_int,
16383 const alignment_val = field_struct_val[4];16549 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
16385 const field_name = try name_val.toAllocatedBytes(16556 const field_name = try name_val.toAllocatedBytes(
16386 Type.initTag(.const_slice_u8),16557 Type.initTag(.const_slice_u8),
16387 new_decl_arena_allocator,16558 new_decl_arena_allocator,
...@@ -16405,7 +16576,7 @@ fn reifyStruct(...@@ -16405,7 +16576,7 @@ fn reifyStruct(
16405 var buffer: Value.ToTypeBuffer = undefined;16576 var buffer: Value.ToTypeBuffer = undefined;
16406 gop.value_ptr.* = .{16577 gop.value_ptr.* = .{
16407 .ty = try field_type_val.toType(&buffer).copy(new_decl_arena_allocator),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 .default_val = default_val,16580 .default_val = default_val,
16410 .is_comptime = is_comptime_val.toBool(),16581 .is_comptime = is_comptime_val.toBool(),
16411 .offset = undefined,16582 .offset = undefined,
...@@ -24357,8 +24528,7 @@ fn coerceTupleToStruct(...@@ -24357,8 +24528,7 @@ fn coerceTupleToStruct(
24357 const struct_ty = try sema.resolveTypeFields(block, dest_ty_src, dest_ty);24528 const struct_ty = try sema.resolveTypeFields(block, dest_ty_src, dest_ty);
2435824529
24359 if (struct_ty.isTupleOrAnonStruct()) {24530 if (struct_ty.isTupleOrAnonStruct()) {
24360 // NOTE remember to handle comptime fields24531 return sema.coerceTupleToTuple(block, struct_ty, inst, inst_src);
24361 return sema.fail(block, dest_ty_src, "TODO: implement coercion from tuples to tuples", .{});
24362 }24532 }
2436324533
24364 const fields = struct_ty.structFields();24534 const fields = struct_ty.structFields();
...@@ -24441,6 +24611,110 @@ fn coerceTupleToStruct(...@@ -24441,6 +24611,110 @@ fn coerceTupleToStruct(
24441 );24611 );
24442}24612}
2444324613
24614fn coerceTupleToTuple(
24615 sema: *Sema,
24616 block: *Block,
24617 tuple_ty: Type,
24618 inst: Air.Inst.Ref,
24619 inst_src: LazySrcLoc,
24620) !Air.Inst.Ref {
24621 const field_count = tuple_ty.structFieldCount();
24622 const field_vals = try sema.arena.alloc(Value, field_count);
24623 const field_refs = try sema.arena.alloc(Air.Inst.Ref, field_vals.len);
24624 mem.set(Air.Inst.Ref, field_refs, .none);
24625
24626 const inst_ty = sema.typeOf(inst);
24627 const tuple = inst_ty.tupleFields();
24628 var runtime_src: ?LazySrcLoc = null;
24629 for (tuple.types) |_, i_usize| {
24630 const i = @intCast(u32, i_usize);
24631 const field_src = inst_src; // TODO better source location
24632 const field_name = if (inst_ty.castTag(.anon_struct)) |payload|
24633 payload.data.names[i]
24634 else
24635 try std.fmt.allocPrint(sema.arena, "{d}", .{i});
24636
24637 if (mem.eql(u8, field_name, "len")) {
24638 return sema.fail(block, field_src, "cannot assign to 'len' field of tuple", .{});
24639 }
24640
24641 const field_index = try sema.tupleFieldIndex(block, tuple_ty, field_name, field_src);
24642
24643 const field_ty = tuple_ty.structFieldType(i);
24644 const default_val = tuple_ty.structFieldDefaultValue(i);
24645 const elem_ref = try tupleField(sema, block, inst_src, inst, field_src, i);
24646 const coerced = try sema.coerce(block, field_ty, elem_ref, field_src);
24647 field_refs[field_index] = coerced;
24648 if (default_val.tag() != .unreachable_value) {
24649 const init_val = (try sema.resolveMaybeUndefVal(block, field_src, coerced)) orelse {
24650 return sema.failWithNeededComptime(block, field_src, "value stored in comptime field must be comptime known");
24651 };
24652
24653 if (!init_val.eql(default_val, field_ty, sema.mod)) {
24654 return sema.failWithInvalidComptimeFieldStore(block, field_src, inst_ty, i);
24655 }
24656 }
24657 if (runtime_src == null) {
24658 if (try sema.resolveMaybeUndefVal(block, field_src, coerced)) |field_val| {
24659 field_vals[field_index] = field_val;
24660 } else {
24661 runtime_src = field_src;
24662 }
24663 }
24664 }
24665
24666 // Populate default field values and report errors for missing fields.
24667 var root_msg: ?*Module.ErrorMsg = null;
24668
24669 for (field_refs) |*field_ref, i| {
24670 if (field_ref.* != .none) continue;
24671
24672 const default_val = tuple_ty.structFieldDefaultValue(i);
24673 const field_ty = tuple_ty.structFieldType(i);
24674
24675 const field_src = inst_src; // TODO better source location
24676 if (default_val.tag() == .unreachable_value) {
24677 if (tuple_ty.isTuple()) {
24678 const template = "missing tuple field: {d}";
24679 if (root_msg) |msg| {
24680 try sema.errNote(block, field_src, msg, template, .{i});
24681 } else {
24682 root_msg = try sema.errMsg(block, field_src, template, .{i});
24683 }
24684 continue;
24685 }
24686 const template = "missing struct field: {s}";
24687 const args = .{tuple_ty.structFieldName(i)};
24688 if (root_msg) |msg| {
24689 try sema.errNote(block, field_src, msg, template, args);
24690 } else {
24691 root_msg = try sema.errMsg(block, field_src, template, args);
24692 }
24693 continue;
24694 }
24695 if (runtime_src == null) {
24696 field_vals[i] = default_val;
24697 } else {
24698 field_ref.* = try sema.addConstant(field_ty, default_val);
24699 }
24700 }
24701
24702 if (root_msg) |msg| {
24703 try sema.addDeclaredHereNote(msg, tuple_ty);
24704 return sema.failWithOwnedErrorMsg(block, msg);
24705 }
24706
24707 if (runtime_src) |rs| {
24708 try sema.requireRuntimeBlock(block, inst_src, rs);
24709 return block.addAggregateInit(tuple_ty, field_refs);
24710 }
24711
24712 return sema.addConstant(
24713 tuple_ty,
24714 try Value.Tag.aggregate.create(sema.arena, field_vals),
24715 );
24716}
24717
24444fn analyzeDeclVal(24718fn analyzeDeclVal(
24445 sema: *Sema,24719 sema: *Sema,
24446 block: *Block,24720 block: *Block,
...@@ -24876,7 +25150,10 @@ fn analyzeSlice(...@@ -24876,7 +25150,10 @@ fn analyzeSlice(
24876 if (!end_is_len) {25150 if (!end_is_len) {
24877 const end = try sema.coerce(block, Type.usize, uncasted_end_opt, end_src);25151 const end = try sema.coerce(block, Type.usize, uncasted_end_opt, end_src);
24878 if (try sema.resolveDefinedValue(block, end_src, end)) |end_val| {25152 if (try sema.resolveDefinedValue(block, end_src, end)) |end_val| {
24879 if (try sema.resolveDefinedValue(block, src, ptr_or_slice)) |slice_val| {25153 if (try sema.resolveMaybeUndefVal(block, src, ptr_or_slice)) |slice_val| {
25154 if (slice_val.isUndef()) {
25155 return sema.fail(block, src, "slice of undefined", .{});
25156 }
24880 const has_sentinel = slice_ty.sentinel() != null;25157 const has_sentinel = slice_ty.sentinel() != null;
24881 var int_payload: Value.Payload.U64 = .{25158 var int_payload: Value.Payload.U64 = .{
24882 .base = .{ .tag = .int_u64 },25159 .base = .{ .tag = .int_u64 },
...@@ -24939,8 +25216,8 @@ fn analyzeSlice(...@@ -24939,8 +25216,8 @@ fn analyzeSlice(
24939 };25216 };
2494025217
24941 // requirement: start <= end25218 // requirement: start <= end
24942 if (try sema.resolveDefinedValue(block, src, end)) |end_val| {25219 if (try sema.resolveDefinedValue(block, end_src, end)) |end_val| {
24943 if (try sema.resolveDefinedValue(block, src, start)) |start_val| {25220 if (try sema.resolveDefinedValue(block, start_src, start)) |start_val| {
24944 if (try sema.compare(block, src, start_val, .gt, end_val, Type.usize)) {25221 if (try sema.compare(block, src, start_val, .gt, end_val, Type.usize)) {
24945 return sema.fail(25222 return sema.fail(
24946 block,25223 block,
...@@ -24952,6 +25229,45 @@ fn analyzeSlice(...@@ -24952,6 +25229,45 @@ fn analyzeSlice(
24952 },25229 },
24953 );25230 );
24954 }25231 }
25232 if (try sema.resolveMaybeUndefVal(block, ptr_src, new_ptr)) |ptr_val| sentinel_check: {
25233 const expected_sentinel = sentinel orelse break :sentinel_check;
25234 const start_int = start_val.getUnsignedInt(sema.mod.getTarget()).?;
25235 const end_int = end_val.getUnsignedInt(sema.mod.getTarget()).?;
25236 const sentinel_index = try sema.usizeCast(block, end_src, end_int - start_int);
25237
25238 const elem_ptr = try ptr_val.elemPtr(sema.typeOf(new_ptr), sema.arena, sentinel_index, sema.mod);
25239 const res = try sema.pointerDerefExtra(block, src, elem_ptr, elem_ty, false);
25240 const actual_sentinel = switch (res) {
25241 .runtime_load => break :sentinel_check,
25242 .val => |v| v,
25243 .needed_well_defined => |ty| return sema.fail(
25244 block,
25245 src,
25246 "comptime dereference requires '{}' to have a well-defined layout, but it does not.",
25247 .{ty.fmt(sema.mod)},
25248 ),
25249 .out_of_bounds => |ty| return sema.fail(
25250 block,
25251 end_src,
25252 "slice end index {d} exceeds bounds of containing decl of type '{}'",
25253 .{ end_int, ty.fmt(sema.mod) },
25254 ),
25255 };
25256
25257 if (!actual_sentinel.eql(expected_sentinel, elem_ty, sema.mod)) {
25258 const msg = msg: {
25259 const msg = try sema.errMsg(block, src, "value in memory does not match slice sentinel", .{});
25260 errdefer msg.destroy(sema.gpa);
25261 try sema.errNote(block, src, msg, "expected '{}', found '{}'", .{
25262 expected_sentinel.fmtValue(elem_ty, sema.mod),
25263 actual_sentinel.fmtValue(elem_ty, sema.mod),
25264 });
25265
25266 break :msg msg;
25267 };
25268 return sema.failWithOwnedErrorMsg(block, msg);
25269 }
25270 }
24955 }25271 }
24956 }25272 }
2495725273
...@@ -27314,7 +27630,8 @@ fn enumFieldSrcLoc(...@@ -27314,7 +27630,8 @@ fn enumFieldSrcLoc(
27314 .container_decl_arg_trailing,27630 .container_decl_arg_trailing,
27315 => tree.containerDeclArg(enum_node),27631 => tree.containerDeclArg(enum_node),
2731627632
27317 else => unreachable,27633 // Container was constructed with `@Type`.
27634 else => return LazySrcLoc.nodeOffset(node_offset),
27318 };27635 };
27319 var it_index: usize = 0;27636 var it_index: usize = 0;
27320 for (container_decl.ast.members) |member_node| {27637 for (container_decl.ast.members) |member_node| {
...@@ -27591,9 +27908,36 @@ pub fn analyzeAddrspace(...@@ -27591,9 +27908,36 @@ pub fn analyzeAddrspace(
27591/// Returns `null` if the pointer contents cannot be loaded at comptime.27908/// Returns `null` if the pointer contents cannot be loaded at comptime.
27592fn pointerDeref(sema: *Sema, block: *Block, src: LazySrcLoc, ptr_val: Value, ptr_ty: Type) CompileError!?Value {27909fn pointerDeref(sema: *Sema, block: *Block, src: LazySrcLoc, ptr_val: Value, ptr_ty: Type) CompileError!?Value {
27593 const load_ty = ptr_ty.childType();27910 const load_ty = ptr_ty.childType();
27911 const res = try sema.pointerDerefExtra(block, src, ptr_val, load_ty, true);
27912 switch (res) {
27913 .runtime_load => return null,
27914 .val => |v| return v,
27915 .needed_well_defined => |ty| return sema.fail(
27916 block,
27917 src,
27918 "comptime dereference requires '{}' to have a well-defined layout, but it does not.",
27919 .{ty.fmt(sema.mod)},
27920 ),
27921 .out_of_bounds => |ty| return sema.fail(
27922 block,
27923 src,
27924 "dereference of '{}' exceeds bounds of containing decl of type '{}'",
27925 .{ ptr_ty.fmt(sema.mod), ty.fmt(sema.mod) },
27926 ),
27927 }
27928}
27929
27930const DerefResult = union(enum) {
27931 runtime_load,
27932 val: Value,
27933 needed_well_defined: Type,
27934 out_of_bounds: Type,
27935};
27936
27937fn pointerDerefExtra(sema: *Sema, block: *Block, src: LazySrcLoc, ptr_val: Value, load_ty: Type, want_mutable: bool) CompileError!DerefResult {
27594 const target = sema.mod.getTarget();27938 const target = sema.mod.getTarget();
27595 const deref = sema.beginComptimePtrLoad(block, src, ptr_val, load_ty) catch |err| switch (err) {27939 const deref = sema.beginComptimePtrLoad(block, src, ptr_val, load_ty) catch |err| switch (err) {
27596 error.RuntimeLoad => return null,27940 error.RuntimeLoad => return DerefResult{ .runtime_load = {} },
27597 else => |e| return e,27941 else => |e| return e,
27598 };27942 };
2759927943
...@@ -27604,39 +27948,40 @@ fn pointerDeref(sema: *Sema, block: *Block, src: LazySrcLoc, ptr_val: Value, ptr...@@ -27604,39 +27948,40 @@ fn pointerDeref(sema: *Sema, block: *Block, src: LazySrcLoc, ptr_val: Value, ptr
27604 if (coerce_in_mem_ok) {27948 if (coerce_in_mem_ok) {
27605 // We have a Value that lines up in virtual memory exactly with what we want to load,27949 // We have a Value that lines up in virtual memory exactly with what we want to load,
27606 // and it is in-memory coercible to load_ty. It may be returned without modifications.27950 // and it is in-memory coercible to load_ty. It may be returned without modifications.
27607 if (deref.is_mutable) {27951 if (deref.is_mutable and want_mutable) {
27608 // The decl whose value we are obtaining here may be overwritten with27952 // The decl whose value we are obtaining here may be overwritten with
27609 // a different value upon further semantic analysis, which would27953 // a different value upon further semantic analysis, which would
27610 // invalidate this memory. So we must copy here.27954 // invalidate this memory. So we must copy here.
27611 return try tv.val.copy(sema.arena);27955 return DerefResult{ .val = try tv.val.copy(sema.arena) };
27612 }27956 }
27613 return tv.val;27957 return DerefResult{ .val = tv.val };
27614 }27958 }
27615 }27959 }
2761627960
27617 // The type is not in-memory coercible or the direct dereference failed, so it must27961 // The type is not in-memory coercible or the direct dereference failed, so it must
27618 // be bitcast according to the pointer type we are performing the load through.27962 // be bitcast according to the pointer type we are performing the load through.
27619 if (!load_ty.hasWellDefinedLayout())27963 if (!load_ty.hasWellDefinedLayout()) {
27620 return sema.fail(block, src, "comptime dereference requires '{}' to have a well-defined layout, but it does not.", .{load_ty.fmt(sema.mod)});27964 return DerefResult{ .needed_well_defined = load_ty };
27965 }
2762127966
27622 const load_sz = try sema.typeAbiSize(block, src, load_ty);27967 const load_sz = try sema.typeAbiSize(block, src, load_ty);
2762327968
27624 // Try the smaller bit-cast first, since that's more efficient than using the larger `parent`27969 // Try the smaller bit-cast first, since that's more efficient than using the larger `parent`
27625 if (deref.pointee) |tv| if (load_sz <= try sema.typeAbiSize(block, src, tv.ty))27970 if (deref.pointee) |tv| if (load_sz <= try sema.typeAbiSize(block, src, tv.ty))
27626 return try sema.bitCastVal(block, src, tv.val, tv.ty, load_ty, 0);27971 return DerefResult{ .val = try sema.bitCastVal(block, src, tv.val, tv.ty, load_ty, 0) };
2762727972
27628 // If that fails, try to bit-cast from the largest parent value with a well-defined layout27973 // If that fails, try to bit-cast from the largest parent value with a well-defined layout
27629 if (deref.parent) |parent| if (load_sz + parent.byte_offset <= try sema.typeAbiSize(block, src, parent.tv.ty))27974 if (deref.parent) |parent| if (load_sz + parent.byte_offset <= try sema.typeAbiSize(block, src, parent.tv.ty))
27630 return try sema.bitCastVal(block, src, parent.tv.val, parent.tv.ty, load_ty, parent.byte_offset);27975 return DerefResult{ .val = try sema.bitCastVal(block, src, parent.tv.val, parent.tv.ty, load_ty, parent.byte_offset) };
2763127976
27632 if (deref.ty_without_well_defined_layout) |bad_ty| {27977 if (deref.ty_without_well_defined_layout) |bad_ty| {
27633 // We got no parent for bit-casting, or the parent we got was too small. Either way, the problem27978 // We got no parent for bit-casting, or the parent we got was too small. Either way, the problem
27634 // is that some type we encountered when de-referencing does not have a well-defined layout.27979 // is that some type we encountered when de-referencing does not have a well-defined layout.
27635 return sema.fail(block, src, "comptime dereference requires '{}' to have a well-defined layout, but it does not.", .{bad_ty.fmt(sema.mod)});27980 return DerefResult{ .needed_well_defined = bad_ty };
27636 } else {27981 } else {
27637 // If all encountered types had well-defined layouts, the parent is the root decl and it just27982 // If all encountered types had well-defined layouts, the parent is the root decl and it just
27638 // wasn't big enough for the load.27983 // wasn't big enough for the load.
27639 return sema.fail(block, src, "dereference of '{}' exceeds bounds of containing decl of type '{}'", .{ ptr_ty.fmt(sema.mod), deref.parent.?.tv.ty.fmt(sema.mod) });27984 return DerefResult{ .out_of_bounds = deref.parent.?.tv.ty };
27640 }27985 }
27641}27986}
2764227987
src/value.zig+16-15
...@@ -2292,25 +2292,13 @@ pub const Value = extern union {...@@ -2292,25 +2292,13 @@ pub const Value = extern union {
2292 }2292 }
2293 },2293 },
2294 .Struct => {2294 .Struct => {
2295 if (ty.isTupleOrAnonStruct()) {
2296 const fields = ty.tupleFields();
2297 for (fields.values) |field_val, i| {
2298 field_val.hash(fields.types[i], hasher, mod);
2299 }
2300 return;
2301 }
2302 const fields = ty.structFields().values();
2303 if (fields.len == 0) return;
2304 switch (val.tag()) {2295 switch (val.tag()) {
2305 .empty_struct_value => {2296 .empty_struct_value => {},
2306 for (fields) |field| {
2307 field.default_val.hash(field.ty, hasher, mod);
2308 }
2309 },
2310 .aggregate => {2297 .aggregate => {
2311 const field_values = val.castTag(.aggregate).?.data;2298 const field_values = val.castTag(.aggregate).?.data;
2312 for (field_values) |field_val, i| {2299 for (field_values) |field_val, i| {
2313 field_val.hash(fields[i].ty, hasher, mod);2300 const field_ty = ty.structFieldType(i);
2301 field_val.hash(field_ty, hasher, mod);
2314 }2302 }
2315 },2303 },
2316 else => unreachable,2304 else => unreachable,
...@@ -2798,6 +2786,19 @@ pub const Value = extern union {...@@ -2798,6 +2786,19 @@ pub const Value = extern union {
2798 return self.isUndef();2786 return self.isUndef();
2799 }2787 }
28002788
2789 /// Returns true if any value contained in `self` is undefined.
2790 /// TODO: check for cases such as array that is not marked undef but all the element
2791 /// values are marked undef, or struct that is not marked undef but all fields are marked
2792 /// undef, etc.
2793 pub fn anyUndef(self: Value) bool {
2794 if (self.castTag(.aggregate)) |aggregate| {
2795 for (aggregate.data) |val| {
2796 if (val.anyUndef()) return true;
2797 }
2798 }
2799 return self.isUndef();
2800 }
2801
2801 /// Asserts the value is not undefined and not unreachable.2802 /// Asserts the value is not undefined and not unreachable.
2802 /// Integer value 0 is considered null because of C pointers.2803 /// Integer value 0 is considered null because of C pointers.
2803 pub fn isNull(self: Value) bool {2804 pub fn isNull(self: Value) bool {
test/behavior/tuple.zig+35
...@@ -255,3 +255,38 @@ test "initializing anon struct with mixed comptime-runtime fields" {...@@ -255,3 +255,38 @@ test "initializing anon struct with mixed comptime-runtime fields" {
255 var a: T = .{ .foo = -1234, .bar = x + 1 };255 var a: T = .{ .foo = -1234, .bar = x + 1 };
256 _ = a;256 _ = a;
257}257}
258
259test "tuple in tuple passed to generic function" {
260 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
261 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
262 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
263 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
264
265 const S = struct {
266 fn pair(x: f32, y: f32) std.meta.Tuple(&.{ f32, f32 }) {
267 return .{ x, y };
268 }
269
270 fn foo(x: anytype) !void {
271 try expect(x[0][0] == 1.5);
272 try expect(x[0][1] == 2.5);
273 }
274 };
275 const x = comptime S.pair(1.5, 2.5);
276 try S.foo(.{x});
277}
278
279test "coerce tuple to tuple" {
280 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
281 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
282 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
283 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
284
285 const T = std.meta.Tuple(&.{u8});
286 const S = struct {
287 fn foo(x: T) !void {
288 try expect(x[0] == 123);
289 }
290 };
291 try S.foo(.{123});
292}
test/cases/compile_errors/comptime_slice-sentinel_does_not_match_memory_at_target_index_terminated.zig created+74
...@@ -0,0 +1,74 @@
1export fn foo_array() void {
2 comptime {
3 var target = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
4 const slice = target[0..3 :0];
5 _ = slice;
6 }
7}
8export fn foo_ptr_array() void {
9 comptime {
10 var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
11 var target = &buf;
12 const slice = target[0..3 :0];
13 _ = slice;
14 }
15}
16export fn foo_vector_ConstPtrSpecialBaseArray() void {
17 comptime {
18 var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
19 var target: [*]u8 = &buf;
20 const slice = target[0..3 :0];
21 _ = slice;
22 }
23}
24export fn foo_vector_ConstPtrSpecialRef() void {
25 comptime {
26 var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
27 var target: [*]u8 = @ptrCast([*]u8, &buf);
28 const slice = target[0..3 :0];
29 _ = slice;
30 }
31}
32export fn foo_cvector_ConstPtrSpecialBaseArray() void {
33 comptime {
34 var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
35 var target: [*c]u8 = &buf;
36 const slice = target[0..3 :0];
37 _ = slice;
38 }
39}
40export fn foo_cvector_ConstPtrSpecialRef() void {
41 comptime {
42 var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
43 var target: [*c]u8 = @ptrCast([*c]u8, &buf);
44 const slice = target[0..3 :0];
45 _ = slice;
46 }
47}
48export fn foo_slice() void {
49 comptime {
50 var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
51 var target: []u8 = &buf;
52 const slice = target[0..3 :0];
53 _ = slice;
54 }
55}
56
57// error
58// backend=stage2
59// target=native
60//
61// :4:29: error: value in memory does not match slice sentinel
62// :4:29: note: expected '0', found '100'
63// :12:29: error: value in memory does not match slice sentinel
64// :12:29: note: expected '0', found '100'
65// :20:29: error: value in memory does not match slice sentinel
66// :20:29: note: expected '0', found '100'
67// :28:29: error: value in memory does not match slice sentinel
68// :28:29: note: expected '0', found '100'
69// :36:29: error: value in memory does not match slice sentinel
70// :36:29: note: expected '0', found '100'
71// :44:29: error: value in memory does not match slice sentinel
72// :44:29: note: expected '0', found '100'
73// :52:29: error: value in memory does not match slice sentinel
74// :52:29: note: expected '0', found '100'
test/cases/compile_errors/comptime_slice-sentinel_does_not_match_memory_at_target_index_unterminated.zig created+74
...@@ -0,0 +1,74 @@
1export fn foo_array() void {
2 comptime {
3 var target = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
4 const slice = target[0..3 :0];
5 _ = slice;
6 }
7}
8export fn foo_ptr_array() void {
9 comptime {
10 var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
11 var target = &buf;
12 const slice = target[0..3 :0];
13 _ = slice;
14 }
15}
16export fn foo_vector_ConstPtrSpecialBaseArray() void {
17 comptime {
18 var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
19 var target: [*]u8 = &buf;
20 const slice = target[0..3 :0];
21 _ = slice;
22 }
23}
24export fn foo_vector_ConstPtrSpecialRef() void {
25 comptime {
26 var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
27 var target: [*]u8 = @ptrCast([*]u8, &buf);
28 const slice = target[0..3 :0];
29 _ = slice;
30 }
31}
32export fn foo_cvector_ConstPtrSpecialBaseArray() void {
33 comptime {
34 var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
35 var target: [*c]u8 = &buf;
36 const slice = target[0..3 :0];
37 _ = slice;
38 }
39}
40export fn foo_cvector_ConstPtrSpecialRef() void {
41 comptime {
42 var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
43 var target: [*c]u8 = @ptrCast([*c]u8, &buf);
44 const slice = target[0..3 :0];
45 _ = slice;
46 }
47}
48export fn foo_slice() void {
49 comptime {
50 var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
51 var target: []u8 = &buf;
52 const slice = target[0..3 :0];
53 _ = slice;
54 }
55}
56
57// error
58// backend=stage2
59// target=native
60//
61// :4:29: error: value in memory does not match slice sentinel
62// :4:29: note: expected '0', found '100'
63// :12:29: error: value in memory does not match slice sentinel
64// :12:29: note: expected '0', found '100'
65// :20:29: error: value in memory does not match slice sentinel
66// :20:29: note: expected '0', found '100'
67// :28:29: error: value in memory does not match slice sentinel
68// :28:29: note: expected '0', found '100'
69// :36:29: error: value in memory does not match slice sentinel
70// :36:29: note: expected '0', found '100'
71// :44:29: error: value in memory does not match slice sentinel
72// :44:29: note: expected '0', found '100'
73// :52:29: error: value in memory does not match slice sentinel
74// :52:29: note: expected '0', found '100'
test/cases/compile_errors/comptime_slice-sentinel_does_not_match_target-sentinel.zig created+74
...@@ -0,0 +1,74 @@
1export fn foo_array() void {
2 comptime {
3 var target = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
4 const slice = target[0..14 :255];
5 _ = slice;
6 }
7}
8export fn foo_ptr_array() void {
9 comptime {
10 var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
11 var target = &buf;
12 const slice = target[0..14 :255];
13 _ = slice;
14 }
15}
16export fn foo_vector_ConstPtrSpecialBaseArray() void {
17 comptime {
18 var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
19 var target: [*]u8 = &buf;
20 const slice = target[0..14 :255];
21 _ = slice;
22 }
23}
24export fn foo_vector_ConstPtrSpecialRef() void {
25 comptime {
26 var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
27 var target: [*]u8 = @ptrCast([*]u8, &buf);
28 const slice = target[0..14 :255];
29 _ = slice;
30 }
31}
32export fn foo_cvector_ConstPtrSpecialBaseArray() void {
33 comptime {
34 var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
35 var target: [*c]u8 = &buf;
36 const slice = target[0..14 :255];
37 _ = slice;
38 }
39}
40export fn foo_cvector_ConstPtrSpecialRef() void {
41 comptime {
42 var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
43 var target: [*c]u8 = @ptrCast([*c]u8, &buf);
44 const slice = target[0..14 :255];
45 _ = slice;
46 }
47}
48export fn foo_slice() void {
49 comptime {
50 var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
51 var target: []u8 = &buf;
52 const slice = target[0..14 :255];
53 _ = slice;
54 }
55}
56
57// error
58// backend=stage2
59// target=native
60//
61// :4:29: error: value in memory does not match slice sentinel
62// :4:29: note: expected '255', found '0'
63// :12:29: error: value in memory does not match slice sentinel
64// :12:29: note: expected '255', found '0'
65// :20:29: error: value in memory does not match slice sentinel
66// :20:29: note: expected '255', found '0'
67// :28:29: error: value in memory does not match slice sentinel
68// :28:29: note: expected '255', found '0'
69// :36:29: error: value in memory does not match slice sentinel
70// :36:29: note: expected '255', found '0'
71// :44:29: error: value in memory does not match slice sentinel
72// :44:29: note: expected '255', found '0'
73// :52:29: error: value in memory does not match slice sentinel
74// :52:29: note: expected '255', found '0'
test/cases/compile_errors/comptime_slice-sentinel_is_out_of_bounds_terminated.zig created+67
...@@ -0,0 +1,67 @@
1export fn foo_array() void {
2 comptime {
3 var target = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
4 const slice = target[0..15 :1];
5 _ = slice;
6 }
7}
8export fn foo_ptr_array() void {
9 comptime {
10 var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
11 var target = &buf;
12 const slice = target[0..15 :0];
13 _ = slice;
14 }
15}
16export fn foo_vector_ConstPtrSpecialBaseArray() void {
17 comptime {
18 var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
19 var target: [*]u8 = &buf;
20 const slice = target[0..15 :0];
21 _ = slice;
22 }
23}
24export fn foo_vector_ConstPtrSpecialRef() void {
25 comptime {
26 var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
27 var target: [*]u8 = @ptrCast([*]u8, &buf);
28 const slice = target[0..15 :0];
29 _ = slice;
30 }
31}
32export fn foo_cvector_ConstPtrSpecialBaseArray() void {
33 comptime {
34 var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
35 var target: [*c]u8 = &buf;
36 const slice = target[0..15 :0];
37 _ = slice;
38 }
39}
40export fn foo_cvector_ConstPtrSpecialRef() void {
41 comptime {
42 var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
43 var target: [*c]u8 = @ptrCast([*c]u8, &buf);
44 const slice = target[0..15 :0];
45 _ = slice;
46 }
47}
48export fn foo_slice() void {
49 comptime {
50 var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
51 var target: []u8 = &buf;
52 const slice = target[0..15 :0];
53 _ = slice;
54 }
55}
56
57// error
58// backend=stage2
59// target=native
60//
61// :4:33: error: slice end index 15 exceeds bounds of containing decl of type '[14:0]u8'
62// :12:33: error: slice end index 15 exceeds bounds of containing decl of type '[14:0]u8'
63// :20:33: error: slice end index 15 exceeds bounds of containing decl of type '[14:0]u8'
64// :28:33: error: slice end index 15 exceeds bounds of containing decl of type '[14:0]u8'
65// :36:33: error: slice end index 15 exceeds bounds of containing decl of type '[14:0]u8'
66// :44:33: error: slice end index 15 exceeds bounds of containing decl of type '[14:0]u8'
67// :52:33: error: end index 15 out of bounds for slice of length 14
test/cases/compile_errors/comptime_slice-sentinel_is_out_of_bounds_unterminated.zig created+67
...@@ -0,0 +1,67 @@
1export fn foo_array() void {
2 comptime {
3 var target = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
4 const slice = target[0..14 :0];
5 _ = slice;
6 }
7}
8export fn foo_ptr_array() void {
9 comptime {
10 var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
11 var target = &buf;
12 const slice = target[0..14 :0];
13 _ = slice;
14 }
15}
16export fn foo_vector_ConstPtrSpecialBaseArray() void {
17 comptime {
18 var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
19 var target: [*]u8 = &buf;
20 const slice = target[0..14 :0];
21 _ = slice;
22 }
23}
24export fn foo_vector_ConstPtrSpecialRef() void {
25 comptime {
26 var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
27 var target: [*]u8 = @ptrCast([*]u8, &buf);
28 const slice = target[0..14 :0];
29 _ = slice;
30 }
31}
32export fn foo_cvector_ConstPtrSpecialBaseArray() void {
33 comptime {
34 var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
35 var target: [*c]u8 = &buf;
36 const slice = target[0..14 :0];
37 _ = slice;
38 }
39}
40export fn foo_cvector_ConstPtrSpecialRef() void {
41 comptime {
42 var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
43 var target: [*c]u8 = @ptrCast([*c]u8, &buf);
44 const slice = target[0..14 :0];
45 _ = slice;
46 }
47}
48export fn foo_slice() void {
49 comptime {
50 var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
51 var target: []u8 = &buf;
52 const slice = target[0..14 :0];
53 _ = slice;
54 }
55}
56
57// error
58// backend=stage2
59// target=native
60//
61// :4:33: error: slice end index 14 exceeds bounds of containing decl of type '[14]u8'
62// :12:33: error: slice end index 14 exceeds bounds of containing decl of type '[14]u8'
63// :20:33: error: slice end index 14 exceeds bounds of containing decl of type '[14]u8'
64// :28:33: error: slice end index 14 exceeds bounds of containing decl of type '[14]u8'
65// :36:33: error: slice end index 14 exceeds bounds of containing decl of type '[14]u8'
66// :44:33: error: slice end index 14 exceeds bounds of containing decl of type '[14]u8'
67// :52:33: error: slice end index 14 exceeds bounds of containing decl of type '[14]u8'
test/cases/compile_errors/comptime_slice_of_an_undefined_slice.zig created+11
...@@ -0,0 +1,11 @@
1comptime {
2 var a: []u8 = undefined;
3 var b = a[0..10];
4 _ = b;
5}
6
7// error
8// backend=stage2
9// target=native
10//
11// :3:14: error: slice of undefined
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/comptime_slice-sentinel_does_not_match_memory_at_target_index_terminated.zig deleted-67
...@@ -1,67 +0,0 @@
1export fn foo_array() void {
2 comptime {
3 var target = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
4 const slice = target[0..3 :0];
5 _ = slice;
6 }
7}
8export fn foo_ptr_array() void {
9 comptime {
10 var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
11 var target = &buf;
12 const slice = target[0..3 :0];
13 _ = slice;
14 }
15}
16export fn foo_vector_ConstPtrSpecialBaseArray() void {
17 comptime {
18 var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
19 var target: [*]u8 = &buf;
20 const slice = target[0..3 :0];
21 _ = slice;
22 }
23}
24export fn foo_vector_ConstPtrSpecialRef() void {
25 comptime {
26 var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
27 var target: [*]u8 = @ptrCast([*]u8, &buf);
28 const slice = target[0..3 :0];
29 _ = slice;
30 }
31}
32export fn foo_cvector_ConstPtrSpecialBaseArray() void {
33 comptime {
34 var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
35 var target: [*c]u8 = &buf;
36 const slice = target[0..3 :0];
37 _ = slice;
38 }
39}
40export fn foo_cvector_ConstPtrSpecialRef() void {
41 comptime {
42 var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
43 var target: [*c]u8 = @ptrCast([*c]u8, &buf);
44 const slice = target[0..3 :0];
45 _ = slice;
46 }
47}
48export fn foo_slice() void {
49 comptime {
50 var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
51 var target: []u8 = &buf;
52 const slice = target[0..3 :0];
53 _ = slice;
54 }
55}
56
57// error
58// backend=stage1
59// target=native
60//
61// :4:29: error: slice-sentinel does not match memory at target index
62// :12:29: error: slice-sentinel does not match memory at target index
63// :20:29: error: slice-sentinel does not match memory at target index
64// :28:29: error: slice-sentinel does not match memory at target index
65// :36:29: error: slice-sentinel does not match memory at target index
66// :44:29: error: slice-sentinel does not match memory at target index
67// :52:29: error: slice-sentinel does not match memory at target index
test/cases/compile_errors/stage1/obj/comptime_slice-sentinel_does_not_match_memory_at_target_index_unterminated.zig deleted-67
...@@ -1,67 +0,0 @@
1export fn foo_array() void {
2 comptime {
3 var target = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
4 const slice = target[0..3 :0];
5 _ = slice;
6 }
7}
8export fn foo_ptr_array() void {
9 comptime {
10 var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
11 var target = &buf;
12 const slice = target[0..3 :0];
13 _ = slice;
14 }
15}
16export fn foo_vector_ConstPtrSpecialBaseArray() void {
17 comptime {
18 var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
19 var target: [*]u8 = &buf;
20 const slice = target[0..3 :0];
21 _ = slice;
22 }
23}
24export fn foo_vector_ConstPtrSpecialRef() void {
25 comptime {
26 var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
27 var target: [*]u8 = @ptrCast([*]u8, &buf);
28 const slice = target[0..3 :0];
29 _ = slice;
30 }
31}
32export fn foo_cvector_ConstPtrSpecialBaseArray() void {
33 comptime {
34 var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
35 var target: [*c]u8 = &buf;
36 const slice = target[0..3 :0];
37 _ = slice;
38 }
39}
40export fn foo_cvector_ConstPtrSpecialRef() void {
41 comptime {
42 var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
43 var target: [*c]u8 = @ptrCast([*c]u8, &buf);
44 const slice = target[0..3 :0];
45 _ = slice;
46 }
47}
48export fn foo_slice() void {
49 comptime {
50 var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
51 var target: []u8 = &buf;
52 const slice = target[0..3 :0];
53 _ = slice;
54 }
55}
56
57// error
58// backend=stage1
59// target=native
60//
61// :4:29: error: slice-sentinel does not match memory at target index
62// :12:29: error: slice-sentinel does not match memory at target index
63// :20:29: error: slice-sentinel does not match memory at target index
64// :28:29: error: slice-sentinel does not match memory at target index
65// :36:29: error: slice-sentinel does not match memory at target index
66// :44:29: error: slice-sentinel does not match memory at target index
67// :52:29: error: slice-sentinel does not match memory at target index
test/cases/compile_errors/stage1/obj/comptime_slice-sentinel_does_not_match_target-sentinel.zig deleted-67
...@@ -1,67 +0,0 @@
1export fn foo_array() void {
2 comptime {
3 var target = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
4 const slice = target[0..14 :255];
5 _ = slice;
6 }
7}
8export fn foo_ptr_array() void {
9 comptime {
10 var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
11 var target = &buf;
12 const slice = target[0..14 :255];
13 _ = slice;
14 }
15}
16export fn foo_vector_ConstPtrSpecialBaseArray() void {
17 comptime {
18 var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
19 var target: [*]u8 = &buf;
20 const slice = target[0..14 :255];
21 _ = slice;
22 }
23}
24export fn foo_vector_ConstPtrSpecialRef() void {
25 comptime {
26 var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
27 var target: [*]u8 = @ptrCast([*]u8, &buf);
28 const slice = target[0..14 :255];
29 _ = slice;
30 }
31}
32export fn foo_cvector_ConstPtrSpecialBaseArray() void {
33 comptime {
34 var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
35 var target: [*c]u8 = &buf;
36 const slice = target[0..14 :255];
37 _ = slice;
38 }
39}
40export fn foo_cvector_ConstPtrSpecialRef() void {
41 comptime {
42 var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
43 var target: [*c]u8 = @ptrCast([*c]u8, &buf);
44 const slice = target[0..14 :255];
45 _ = slice;
46 }
47}
48export fn foo_slice() void {
49 comptime {
50 var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
51 var target: []u8 = &buf;
52 const slice = target[0..14 :255];
53 _ = slice;
54 }
55}
56
57// error
58// backend=stage1
59// target=native
60//
61// :4:29: error: slice-sentinel does not match target-sentinel
62// :12:29: error: slice-sentinel does not match target-sentinel
63// :20:29: error: slice-sentinel does not match target-sentinel
64// :28:29: error: slice-sentinel does not match target-sentinel
65// :36:29: error: slice-sentinel does not match target-sentinel
66// :44:29: error: slice-sentinel does not match target-sentinel
67// :52:29: error: slice-sentinel does not match target-sentinel
test/cases/compile_errors/stage1/obj/comptime_slice-sentinel_is_out_of_bounds_terminated.zig deleted-67
...@@ -1,67 +0,0 @@
1export fn foo_array() void {
2 comptime {
3 var target = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
4 const slice = target[0..15 :1];
5 _ = slice;
6 }
7}
8export fn foo_ptr_array() void {
9 comptime {
10 var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
11 var target = &buf;
12 const slice = target[0..15 :0];
13 _ = slice;
14 }
15}
16export fn foo_vector_ConstPtrSpecialBaseArray() void {
17 comptime {
18 var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
19 var target: [*]u8 = &buf;
20 const slice = target[0..15 :0];
21 _ = slice;
22 }
23}
24export fn foo_vector_ConstPtrSpecialRef() void {
25 comptime {
26 var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
27 var target: [*]u8 = @ptrCast([*]u8, &buf);
28 const slice = target[0..15 :0];
29 _ = slice;
30 }
31}
32export fn foo_cvector_ConstPtrSpecialBaseArray() void {
33 comptime {
34 var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
35 var target: [*c]u8 = &buf;
36 const slice = target[0..15 :0];
37 _ = slice;
38 }
39}
40export fn foo_cvector_ConstPtrSpecialRef() void {
41 comptime {
42 var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
43 var target: [*c]u8 = @ptrCast([*c]u8, &buf);
44 const slice = target[0..15 :0];
45 _ = slice;
46 }
47}
48export fn foo_slice() void {
49 comptime {
50 var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
51 var target: []u8 = &buf;
52 const slice = target[0..15 :0];
53 _ = slice;
54 }
55}
56
57// error
58// backend=stage1
59// target=native
60//
61// :4:29: error: out of bounds slice
62// :12:29: error: out of bounds slice
63// :20:29: error: out of bounds slice
64// :28:29: error: out of bounds slice
65// :36:29: error: out of bounds slice
66// :44:29: error: out of bounds slice
67// :52:29: error: out of bounds slice
test/cases/compile_errors/stage1/obj/comptime_slice-sentinel_is_out_of_bounds_unterminated.zig deleted-67
...@@ -1,67 +0,0 @@
1export fn foo_array() void {
2 comptime {
3 var target = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
4 const slice = target[0..14 :0];
5 _ = slice;
6 }
7}
8export fn foo_ptr_array() void {
9 comptime {
10 var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
11 var target = &buf;
12 const slice = target[0..14 :0];
13 _ = slice;
14 }
15}
16export fn foo_vector_ConstPtrSpecialBaseArray() void {
17 comptime {
18 var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
19 var target: [*]u8 = &buf;
20 const slice = target[0..14 :0];
21 _ = slice;
22 }
23}
24export fn foo_vector_ConstPtrSpecialRef() void {
25 comptime {
26 var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
27 var target: [*]u8 = @ptrCast([*]u8, &buf);
28 const slice = target[0..14 :0];
29 _ = slice;
30 }
31}
32export fn foo_cvector_ConstPtrSpecialBaseArray() void {
33 comptime {
34 var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
35 var target: [*c]u8 = &buf;
36 const slice = target[0..14 :0];
37 _ = slice;
38 }
39}
40export fn foo_cvector_ConstPtrSpecialRef() void {
41 comptime {
42 var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
43 var target: [*c]u8 = @ptrCast([*c]u8, &buf);
44 const slice = target[0..14 :0];
45 _ = slice;
46 }
47}
48export fn foo_slice() void {
49 comptime {
50 var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
51 var target: []u8 = &buf;
52 const slice = target[0..14 :0];
53 _ = slice;
54 }
55}
56
57// error
58// backend=stage1
59// target=native
60//
61// :4:29: error: slice-sentinel is out of bounds
62// :12:29: error: slice-sentinel is out of bounds
63// :20:29: error: slice-sentinel is out of bounds
64// :28:29: error: slice-sentinel is out of bounds
65// :36:29: error: slice-sentinel is out of bounds
66// :44:29: error: slice-sentinel is out of bounds
67// :52:29: error: slice-sentinel is out of bounds
test/cases/compile_errors/stage1/obj/comptime_slice_of_an_undefined_slice.zig deleted-11
...@@ -1,11 +0,0 @@
1comptime {
2 var a: []u8 = undefined;
3 var b = a[0..10];
4 _ = b;
5}
6
7// error
8// backend=stage1
9// target=native
10//
11// tmp.zig:3:14: error: slice of undefined
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
test/cases/compile_errors/stage1/test/type_mismatch_with_tuple_concatenation.zig deleted-11
...@@ -1,11 +0,0 @@
1export fn entry() void {
2 var x = .{};
3 x = x ++ .{ 1, 2, 3 };
4}
5
6// error
7// backend=stage1
8// target=native
9// is_test=1
10//
11// tmp.zig:3:11: error: expected type 'struct:2:14', found 'struct:3:11'
test/cases/compile_errors/type_mismatch_with_tuple_concatenation.zig created+10
...@@ -0,0 +1,10 @@
1export fn entry() void {
2 var x = .{};
3 x = x ++ .{ 1, 2, 3 };
4}
5
6// error
7// backend=stage2
8// target=native
9//
10// :3:11: error: index '0' out of bounds of tuple '@TypeOf(.{})'