| author | |
| committer | |
| log | 1ab15b6c9c529c9acc85f4b0bf3fcaea97a5a48e |
| tree | f4c713785c0fa760ab8da49fcea5a90a841111dc |
| parent | b35490c21732d74232680d2de2deb89f97356c0d |
| parent | 02dc0732604236a57b43b9612d9b0571f06f905a |
| signature |
Stage2: reify functions + fixes47 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 | } |
| 5120 | 5120 | ||
| 5121 | test "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 | |||
| 5121 | test "zig fmt: error for invalid bit range" { | 5129 | test "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]; |
| 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 | 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 | } |
| 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 | 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); |
| 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 | 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 &.{}; |
| 15932 | 15973 | ||
| 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); |
| 15941 | 15982 | ||
| 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 | } |
| 15945 | 15989 | ||
| 15946 | // names must be sorted | 15990 | // 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); |
| 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 | 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 | }; |
| 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 | // Fields | 16092 | // 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 | } |
| 16081 | 16132 | ||
| 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 | }; |
| 16187 | 16238 | ||
| 16188 | // Tag type | 16239 | // 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 | } |
| 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 | 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 location | 16297 | // 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 | } |
| 16238 | 16328 | ||
| 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]; |
| 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 | 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); |
| 24358 | 24529 | ||
| 24359 | if (struct_ty.isTupleOrAnonStruct()) { | 24530 | if (struct_ty.isTupleOrAnonStruct()) { |
| 24360 | // NOTE remember to handle comptime fields | 24531 | 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 | } |
| 24363 | 24533 | ||
| 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 | } |
| 24443 | 24613 | ||
| 24614 | fn 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 | |||
| 24444 | fn analyzeDeclVal( | 24718 | fn 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 | }; |
| 24940 | 25217 | ||
| 24941 | // requirement: start <= end | 25218 | // 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 | } |
| 24957 | 25273 | ||
| ... | @@ -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), |
| 27316 | 27632 | ||
| 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. |
| 27592 | fn pointerDeref(sema: *Sema, block: *Block, src: LazySrcLoc, ptr_val: Value, ptr_ty: Type) CompileError!?Value { | 27909 | fn 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 | |||
| 27930 | const DerefResult = union(enum) { | ||
| 27931 | runtime_load, | ||
| 27932 | val: Value, | ||
| 27933 | needed_well_defined: Type, | ||
| 27934 | out_of_bounds: Type, | ||
| 27935 | }; | ||
| 27936 | |||
| 27937 | fn 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 | }; |
| 27599 | 27943 | ||
| ... | @@ -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 with | 27952 | // The decl whose value we are obtaining here may be overwritten with |
| 27609 | // a different value upon further semantic analysis, which would | 27953 | // 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 | } |
| 27616 | 27960 | ||
| 27617 | // The type is not in-memory coercible or the direct dereference failed, so it must | 27961 | // 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 | } | ||
| 27621 | 27966 | ||
| 27622 | const load_sz = try sema.typeAbiSize(block, src, load_ty); | 27967 | const load_sz = try sema.typeAbiSize(block, src, load_ty); |
| 27623 | 27968 | ||
| 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) }; |
| 27627 | 27972 | ||
| 27628 | // If that fails, try to bit-cast from the largest parent value with a well-defined layout | 27973 | // 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) }; |
| 27631 | 27976 | ||
| 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 problem | 27978 | // 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 just | 27982 | // 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 | } |
| 27642 | 27987 |
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 | } |
| 2800 | 2788 | ||
| 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 | |||
| 259 | test "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 | |||
| 279 | test "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 @@ | ||
| 1 | export 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 | } | ||
| 8 | export 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 | } | ||
| 16 | export 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 | } | ||
| 24 | export 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 | } | ||
| 32 | export 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 | } | ||
| 40 | export 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 | } | ||
| 48 | export 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 @@ | ||
| 1 | export 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 | } | ||
| 8 | export 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 | } | ||
| 16 | export 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 | } | ||
| 24 | export 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 | } | ||
| 32 | export 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 | } | ||
| 40 | export 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 | } | ||
| 48 | export 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 @@ | ||
| 1 | export 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 | } | ||
| 8 | export 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 | } | ||
| 16 | export 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 | } | ||
| 24 | export 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 | } | ||
| 32 | export 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 | } | ||
| 40 | export 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 | } | ||
| 48 | export 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 @@ | ||
| 1 | export 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 | } | ||
| 8 | export 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 | } | ||
| 16 | export 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 | } | ||
| 24 | export 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 | } | ||
| 32 | export 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 | } | ||
| 40 | export 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 | } | ||
| 48 | export 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 @@ | ||
| 1 | export 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 | } | ||
| 8 | export 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 | } | ||
| 16 | export 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 | } | ||
| 24 | export 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 | } | ||
| 32 | export 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 | } | ||
| 40 | export 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 | } | ||
| 48 | export 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 @@ | ||
| 1 | comptime { | ||
| 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 @@ | ||
| 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/comptime_slice-sentinel_does_not_match_memory_at_target_index_terminated.zig deleted-67| ... | @@ -1,67 +0,0 @@ | ||
| 1 | export 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 | } | ||
| 8 | export 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 | } | ||
| 16 | export 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 | } | ||
| 24 | export 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 | } | ||
| 32 | export 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 | } | ||
| 40 | export 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 | } | ||
| 48 | export 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 @@ | ||
| 1 | export 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 | } | ||
| 8 | export 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 | } | ||
| 16 | export 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 | } | ||
| 24 | export 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 | } | ||
| 32 | export 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 | } | ||
| 40 | export 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 | } | ||
| 48 | export 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 @@ | ||
| 1 | export 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 | } | ||
| 8 | export 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 | } | ||
| 16 | export 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 | } | ||
| 24 | export 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 | } | ||
| 32 | export 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 | } | ||
| 40 | export 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 | } | ||
| 48 | export 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 @@ | ||
| 1 | export 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 | } | ||
| 8 | export 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 | } | ||
| 16 | export 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 | } | ||
| 24 | export 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 | } | ||
| 32 | export 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 | } | ||
| 40 | export 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 | } | ||
| 48 | export 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 @@ | ||
| 1 | export 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 | } | ||
| 8 | export 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 | } | ||
| 16 | export 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 | } | ||
| 24 | export 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 | } | ||
| 32 | export 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 | } | ||
| 40 | export 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 | } | ||
| 48 | export 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 @@ | ||
| 1 | comptime { | ||
| 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 @@ | ||
| 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 | ||
test/cases/compile_errors/stage1/test/type_mismatch_with_tuple_concatenation.zig deleted-11| ... | @@ -1,11 +0,0 @@ | ||
| 1 | export 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 @@ | ||
| 1 | export 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(.{})' | ||