zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

commit 7e2eb1326ba267012d47aa2eda539f01963d4d6b (tree)
parent b79884eaf003ad32e800213c20da5c6b8935af34
Author: Andrew Kelley <andrew@ziglang.org>
Date:   Fri,  1 Jul 2022 17:29:18 -0400

Merge pull request #11973 from Vexu/stage2-compile-errors

more stage2 compile error fixes
Diffstat:
Mlib/c.zig | 2+-
Mlib/std/os.zig | 2+-
Mlib/std/process.zig | 2+-
Msrc/AstGen.zig | 27+++++++++++++++------------
Msrc/Sema.zig | 186++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------------
Msrc/Zir.zig | 25+++++++++++++++----------
Msrc/print_zir.zig | 5+++--
Msrc/type.zig | 2+-
Atest/cases/compile_errors/assign_to_invalid_dereference.zig | 9+++++++++
Atest/cases/compile_errors/bitCast_to_enum_type.zig | 12++++++++++++
Atest/cases/compile_errors/bogus_compile_var.zig | 8++++++++
Atest/cases/compile_errors/callconv_apcs_aapcs_aapcsvfp_on_unsupported_platform.zig | 11+++++++++++
Atest/cases/compile_errors/callconv_interrupt_on_unsupported_platform.zig | 7+++++++
Atest/cases/compile_errors/callconv_signal_on_unsupported_platform.zig | 7+++++++
Atest/cases/compile_errors/callconv_stdcall_fastcall_thiscall_on_unsupported_platform.zig | 23+++++++++++++++++++++++
Atest/cases/compile_errors/callconv_vectorcall_on_unsupported_platform.zig | 7+++++++
Atest/cases/compile_errors/compile-time_division_by_zero.zig | 12++++++++++++
Atest/cases/compile_errors/compile-time_remainder_division_by_zero.zig | 12++++++++++++
Atest/cases/compile_errors/compileLog_of_tagged_enum_doesnt_crash_the_compiler.zig | 17+++++++++++++++++
Atest/cases/compile_errors/compile_log.zig | 14++++++++++++++
Atest/cases/compile_errors/compile_log_statement_inside_function_which_must_be_comptime_evaluated.zig | 14++++++++++++++
Atest/cases/compile_errors/compile_time_division_by_zero.zig | 13+++++++++++++
Atest/cases/compile_errors/deref_on_undefined_value.zig | 10++++++++++
Atest/cases/compile_errors/deref_slice_and_get_len_field.zig | 10++++++++++
Atest/cases/compile_errors/dereference_an_array.zig | 14++++++++++++++
Atest/cases/compile_errors/dereference_slice.zig | 12++++++++++++
Atest/cases/compile_errors/dereference_unknown_length_pointer.zig | 9+++++++++
Atest/cases/compile_errors/discarding_error_value.zig | 12++++++++++++
Atest/cases/compile_errors/division_by_zero.zig | 17+++++++++++++++++
Atest/cases/compile_errors/duplicate_enum_field.zig | 16++++++++++++++++
Atest/cases/compile_errors/duplicate_error_in_switch.zig | 22++++++++++++++++++++++
Atest/cases/compile_errors/error_not_handled_in_switch.zig | 21+++++++++++++++++++++
Atest/cases/compile_errors/explicitly_casting_non_tag_type_to_enum.zig | 18++++++++++++++++++
Atest/cases/compile_errors/fieldParentPtr-comptime_field_ptr_not_based_on_struct.zig | 17+++++++++++++++++
Atest/cases/compile_errors/fieldParentPtr-comptime_wrong_field_index.zig | 17+++++++++++++++++
Atest/cases/compile_errors/fieldParentPtr-field_pointer_is_not_pointer.zig | 12++++++++++++
Atest/cases/compile_errors/field_access_of_opaque_type.zig | 16++++++++++++++++
Atest/cases/compile_errors/field_access_of_slices.zig | 12++++++++++++
Atest/cases/compile_errors/field_access_of_unknown_length_pointer.zig | 13+++++++++++++
Atest/cases/compile_errors/ignored_deferred_function_call.zig | 10++++++++++
Atest/cases/compile_errors/ignored_expression_in_while_continuation.zig | 22++++++++++++++++++++++
Atest/cases/compile_errors/illegal_comparison_of_types.zig | 20++++++++++++++++++++
Atest/cases/compile_errors/implicitly_casting_enum_to_tag_type.zig | 17+++++++++++++++++
Atest/cases/compile_errors/incorrect_return_type.zig | 21+++++++++++++++++++++
Atest/cases/compile_errors/indexing_an_array_of_size_zero.zig | 11+++++++++++
Atest/cases/compile_errors/indexing_an_array_of_size_zero_with_runtime_index.zig | 12++++++++++++
Atest/cases/compile_errors/indexing_single-item_pointer.zig | 9+++++++++
Atest/cases/compile_errors/invalid_cast_from_integral_type_to_enum.zig | 17+++++++++++++++++
Atest/cases/compile_errors/invalid_deref_on_switch_target.zig | 17+++++++++++++++++
Atest/cases/compile_errors/invalid_multiple_dereferences.zig | 19+++++++++++++++++++
Mtest/cases/compile_errors/runtime_indexing_comptime_array.zig | 12++++++------
Rtest/cases/compile_errors/stage1/obj/comptime_ptrcast_of_zero-sized_type.zig -> test/cases/compile_errors/stage1/comptime_ptrcast_of_zero-sized_type.zig | 0
Dtest/cases/compile_errors/stage1/deref_on_undefined_value.zig | 10----------
Rtest/cases/compile_errors/stage1/obj/error_equality_but_sets_have_no_common_members.zig -> test/cases/compile_errors/stage1/error_equality_but_sets_have_no_common_members.zig | 0
Rtest/cases/compile_errors/stage1/obj/implicit_cast_from_f64_to_f32.zig -> test/cases/compile_errors/stage1/implicit_cast_from_f64_to_f32.zig | 0
Rtest/cases/compile_errors/stage1/obj/int_to_ptr_of_0_bits.zig -> test/cases/compile_errors/stage1/int_to_ptr_of_0_bits.zig | 0
Dtest/cases/compile_errors/stage1/obj/assign_to_invalid_dereference.zig | 9---------
Dtest/cases/compile_errors/stage1/obj/bitCast_to_enum_type.zig | 10----------
Dtest/cases/compile_errors/stage1/obj/bogus_compile_var.zig | 8--------
Dtest/cases/compile_errors/stage1/obj/callconv_apcs_aapcs_aapcsvfp_on_unsupported_platform.zig | 11-----------
Dtest/cases/compile_errors/stage1/obj/callconv_interrupt_on_unsupported_platform.zig | 7-------
Dtest/cases/compile_errors/stage1/obj/callconv_signal_on_unsupported_platform.zig | 7-------
Dtest/cases/compile_errors/stage1/obj/callconv_stdcall_fastcall_thiscall_on_unsupported_platform-0.zig | 23-----------------------
Dtest/cases/compile_errors/stage1/obj/callconv_stdcall_fastcall_thiscall_on_unsupported_platform-1.zig | 11-----------
Dtest/cases/compile_errors/stage1/obj/callconv_vectorcall_on_unsupported_platform.zig | 7-------
Dtest/cases/compile_errors/stage1/obj/compile-time_division_by_zero.zig | 12------------
Dtest/cases/compile_errors/stage1/obj/compile-time_remainder_division_by_zero.zig | 12------------
Dtest/cases/compile_errors/stage1/obj/compileLog_of_tagged_enum_doesnt_crash_the_compiler.zig | 17-----------------
Dtest/cases/compile_errors/stage1/obj/compile_log.zig | 16----------------
Dtest/cases/compile_errors/stage1/obj/compile_log_statement_inside_function_which_must_be_comptime_evaluated.zig | 14--------------
Dtest/cases/compile_errors/stage1/obj/compile_time_division_by_zero.zig | 12------------
Dtest/cases/compile_errors/stage1/obj/deref_slice_and_get_len_field.zig | 10----------
Dtest/cases/compile_errors/stage1/obj/dereference_an_array.zig | 14--------------
Dtest/cases/compile_errors/stage1/obj/dereference_unknown_length_pointer.zig | 9---------
Dtest/cases/compile_errors/stage1/obj/discarding_error_value.zig | 12------------
Dtest/cases/compile_errors/stage1/obj/division_by_zero.zig | 18------------------
Dtest/cases/compile_errors/stage1/obj/duplicate_enum_field.zig | 16----------------
Dtest/cases/compile_errors/stage1/obj/duplicate_error_in_switch.zig | 22----------------------
Dtest/cases/compile_errors/stage1/obj/error_not_handled_in_switch.zig | 20--------------------
Dtest/cases/compile_errors/stage1/obj/explicitly_casting_non_tag_type_to_enum.zig | 18------------------
Dtest/cases/compile_errors/stage1/obj/fieldParentPtr-comptime_field_ptr_not_based_on_struct.zig | 17-----------------
Dtest/cases/compile_errors/stage1/obj/fieldParentPtr-comptime_wrong_field_index.zig | 16----------------
Dtest/cases/compile_errors/stage1/obj/fieldParentPtr-field_pointer_is_not_pointer.zig | 12------------
Dtest/cases/compile_errors/stage1/obj/field_access_of_opaque_type.zig | 16----------------
Dtest/cases/compile_errors/stage1/obj/field_access_of_slices.zig | 11-----------
Dtest/cases/compile_errors/stage1/obj/field_access_of_unknown_length_pointer.zig | 13-------------
Dtest/cases/compile_errors/stage1/obj/ignored_deferred_function_call.zig | 10----------
Dtest/cases/compile_errors/stage1/obj/ignored_expression_in_while_continuation.zig | 22----------------------
Dtest/cases/compile_errors/stage1/obj/illegal_comparison_of_types.zig | 20--------------------
Dtest/cases/compile_errors/stage1/obj/implicitly_casting_enum_to_tag_type.zig | 17-----------------
Dtest/cases/compile_errors/stage1/obj/incorrect_return_type.zig | 21---------------------
Dtest/cases/compile_errors/stage1/obj/indexing_an_array_of_size_zero.zig | 11-----------
Dtest/cases/compile_errors/stage1/obj/indexing_an_array_of_size_zero_with_runtime_index.zig | 12------------
Dtest/cases/compile_errors/stage1/obj/indexing_single-item_pointer.zig | 9---------
Dtest/cases/compile_errors/stage1/obj/invalid_cast_from_integral_type_to_enum.zig | 17-----------------
Dtest/cases/compile_errors/stage1/obj/invalid_deref_on_switch_target.zig | 17-----------------
Dtest/cases/compile_errors/stage1/obj/invalid_multiple_dereferences.zig | 19-------------------
Dtest/cases/compile_errors/stage1/obj/take_slice_of_invalid_dereference.zig | 10----------
Atest/cases/compile_errors/take_slice_of_invalid_dereference.zig | 10++++++++++
Mtest/stage2/cbe.zig | 4++--
100 files changed, 791 insertions(+), 670 deletions(-)

diff --git a/lib/c.zig b/lib/c.zig @@ -82,7 +82,7 @@ fn memset(dest: ?[*]u8, c: u8, len: usize) callconv(.C) ?[*]u8 { var d = dest.?; var n = len; while (true) { - d.* = c; + d[0] = c; n -= 1; if (n == 0) break; d += 1; diff --git a/lib/std/os.zig b/lib/std/os.zig @@ -1868,7 +1868,7 @@ pub fn getenv(key: []const u8) ?[]const u8 { } // Search the entire `environ` because we don't have a null terminated pointer. var ptr = std.c.environ; - while (ptr.*) |line| : (ptr += 1) { + while (ptr[0]) |line| : (ptr += 1) { var line_i: usize = 0; while (line[line_i] != 0 and line[line_i] != '=') : (line_i += 1) {} const this_key = line[0..line_i]; diff --git a/lib/std/process.zig b/lib/std/process.zig @@ -313,7 +313,7 @@ pub fn getEnvMap(allocator: Allocator) !EnvMap { return result; } else if (builtin.link_libc) { var ptr = std.c.environ; - while (ptr.*) |line| : (ptr += 1) { + while (ptr[0]) |line| : (ptr += 1) { var line_i: usize = 0; while (line[line_i] != 0 and line[line_i] != '=') : (line_i += 1) {} const key = line[0..line_i]; diff --git a/src/AstGen.zig b/src/AstGen.zig @@ -812,6 +812,7 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: Ast.Node.Index) InnerEr .deref => { const lhs = try expr(gz, scope, .none, node_datas[node].lhs); + _ = try gz.addUnTok(.validate_deref, lhs, main_tokens[node]); switch (rl) { .ref => return lhs, else => { @@ -2500,6 +2501,7 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: Ast.Node.Index) Inner .memset, .validate_array_init_ty, .validate_struct_init_ty, + .validate_deref, => break :b true, } } else switch (maybe_unused_result) { @@ -5152,16 +5154,14 @@ fn arrayAccess( const tree = astgen.tree; const node_datas = tree.nodes.items(.data); switch (rl) { - .ref => return gz.addBin( - .elem_ptr, - try expr(gz, scope, .ref, node_datas[node].lhs), - try expr(gz, scope, .{ .ty = .usize_type }, node_datas[node].rhs), - ), - else => return rvalue(gz, rl, try gz.addBin( - .elem_val, - try expr(gz, scope, .none, node_datas[node].lhs), - try expr(gz, scope, .{ .coerced_ty = .usize_type }, node_datas[node].rhs), - ), node), + .ref => return gz.addPlNode(.elem_ptr_node, node, Zir.Inst.Bin{ + .lhs = try expr(gz, scope, .ref, node_datas[node].lhs), + .rhs = try expr(gz, scope, .{ .ty = .usize_type }, node_datas[node].rhs), + }), + else => return rvalue(gz, rl, try gz.addPlNode(.elem_val_node, node, Zir.Inst.Bin{ + .lhs = try expr(gz, scope, .none, node_datas[node].lhs), + .rhs = try expr(gz, scope, .{ .ty = .usize_type }, node_datas[node].rhs), + }), node), } } @@ -5683,7 +5683,7 @@ fn whileExpr( try then_scope.addDbgVar(.dbg_var_val, some, dbg_var_inst); } if (while_full.ast.cont_expr != 0) { - _ = try expr(&loop_scope, then_sub_scope, .{ .ty = .void_type }, while_full.ast.cont_expr); + _ = try unusedResultExpr(&loop_scope, then_sub_scope, while_full.ast.cont_expr); } try then_scope.addDbgBlockEnd(); const repeat_tag: Zir.Inst.Tag = if (is_inline) .repeat_inline else .repeat; @@ -5888,7 +5888,10 @@ fn forExpr( if (!mem.eql(u8, value_name, "_")) { const name_str_index = try astgen.identAsString(ident); const tag: Zir.Inst.Tag = if (is_ptr) .elem_ptr else .elem_val; - const payload_inst = try then_scope.addBin(tag, array_ptr, index); + const payload_inst = try then_scope.addPlNode(tag, for_full.ast.cond_expr, Zir.Inst.Bin{ + .lhs = array_ptr, + .rhs = index, + }); try astgen.detectLocalShadowing(&then_scope.base, name_str_index, ident, value_name); payload_val_scope = .{ .parent = &then_scope.base, diff --git a/src/Sema.zig b/src/Sema.zig @@ -1080,6 +1080,11 @@ fn analyzeBodyInner( i += 1; continue; }, + .validate_deref => { + try sema.zirValidateDeref(block, inst); + i += 1; + continue; + }, .@"export" => { try sema.zirExport(block, inst); i += 1; @@ -2434,9 +2439,9 @@ fn zirEnumDecl( const field_src = enumFieldSrcLoc(sema.mod.declPtr(block.src_decl), tree.*, src.node_offset.x, field_i); const other_tag_src = enumFieldSrcLoc(sema.mod.declPtr(block.src_decl), tree.*, src.node_offset.x, gop.index); const msg = msg: { - const msg = try sema.errMsg(block, field_src, "duplicate enum tag", .{}); + const msg = try sema.errMsg(block, field_src, "duplicate enum field '{s}'", .{field_name}); errdefer msg.destroy(gpa); - try sema.errNote(block, other_tag_src, msg, "other tag here", .{}); + try sema.errNote(block, other_tag_src, msg, "other field here", .{}); break :msg msg; }; return sema.failWithOwnedErrorMsg(block, msg); @@ -2733,6 +2738,7 @@ fn ensureResultUsed( const operand_ty = sema.typeOf(operand); switch (operand_ty.zigTypeTag()) { .Void, .NoReturn => return, + .ErrorSet, .ErrorUnion => return sema.fail(block, src, "error is ignored. consider using `try`, `catch`, or `if`", .{}), else => return sema.fail(block, src, "expression value is ignored", .{}), } } @@ -2746,7 +2752,7 @@ fn zirEnsureResultNonError(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com const src = inst_data.src(); const operand_ty = sema.typeOf(operand); switch (operand_ty.zigTypeTag()) { - .ErrorSet, .ErrorUnion => return sema.fail(block, src, "error is discarded", .{}), + .ErrorSet, .ErrorUnion => return sema.fail(block, src, "error is discarded. consider using `try`, `catch`, or `if`", .{}), else => return, } } @@ -3849,6 +3855,28 @@ fn zirValidateArrayInit( } } +fn zirValidateDeref(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void { + const inst_data = sema.code.instructions.items(.data)[inst].un_tok; + const src = inst_data.src(); + const operand_src: LazySrcLoc = .{ .token_offset = inst_data.src_tok + 1 }; + const operand = try sema.resolveInst(inst_data.operand); + const operand_ty = sema.typeOf(operand); + + if (operand_ty.zigTypeTag() != .Pointer) { + return sema.fail(block, src, "cannot dereference non-pointer type '{}'", .{operand_ty.fmt(sema.mod)}); + } else switch (operand_ty.ptrSize()) { + .One, .C => {}, + .Many => return sema.fail(block, src, "index syntax required for unknown-length pointer type '{}'", .{operand_ty.fmt(sema.mod)}), + .Slice => return sema.fail(block, src, "index syntax required for slice type '{}'", .{operand_ty.fmt(sema.mod)}), + } + + if (try sema.resolveMaybeUndefVal(block, operand_src, operand)) |val| { + if (val.isUndef()) { + return sema.fail(block, src, "cannot dereference undefined value", .{}); + } + } +} + fn failWithBadMemberAccess( sema: *Sema, block: *Block, @@ -4272,7 +4300,8 @@ fn zirCompileLog( } try writer.print("\n", .{}); - const gop = try sema.mod.compile_log_decls.getOrPut(sema.gpa, sema.owner_decl_index); + const decl_index = if (sema.func) |some| some.owner_decl else sema.owner_decl_index; + const gop = try sema.mod.compile_log_decls.getOrPut(sema.gpa, decl_index); if (!gop.found_existing) { gop.value_ptr.* = src_node; } @@ -6416,6 +6445,7 @@ fn zirIntToEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A if (dest_ty.zigTypeTag() != .Enum) { return sema.fail(block, dest_ty_src, "expected enum, found '{}'", .{dest_ty.fmt(sema.mod)}); } + _ = try sema.checkIntType(block, operand_src, sema.typeOf(operand)); if (try sema.resolveMaybeUndefVal(block, operand_src, operand)) |int_val| { if (dest_ty.isNonexhaustiveEnum()) { @@ -7007,6 +7037,7 @@ fn funcCommon( noalias_bits: u32, ) CompileError!Air.Inst.Ref { const ret_ty_src: LazySrcLoc = .{ .node_offset_fn_type_ret_ty = src_node_offset }; + const cc_src: LazySrcLoc = .{ .node_offset_fn_type_cc = src_node_offset }; var is_generic = bare_return_type.tag() == .generic_poison or alignment == null or @@ -7062,7 +7093,7 @@ fn funcCommon( const param_types = try sema.arena.alloc(Type, block.params.items.len); const comptime_params = try sema.arena.alloc(bool, block.params.items.len); for (block.params.items) |param, i| { - const param_src = LazySrcLoc.nodeOffset(src_node_offset); // TODO better src + const param_src = LazySrcLoc.nodeOffset(src_node_offset); // TODO better soruce location param_types[i] = param.ty; comptime_params[i] = param.is_comptime or try sema.typeRequiresComptime(block, param_src, param.ty); @@ -7109,6 +7140,45 @@ fn funcCommon( const cc_workaround = cc orelse .Unspecified; const align_workaround = alignment orelse 0; + const arch = sema.mod.getTarget().cpu.arch; + if (switch (cc_workaround) { + .Unspecified, .C, .Naked, .Async, .Inline => null, + .Interrupt => switch (arch) { + .i386, .x86_64, .avr, .msp430 => null, + else => @as([]const u8, "i386, x86_64, AVR, and MSP430"), + }, + .Signal => switch (arch) { + .avr => null, + else => @as([]const u8, "AVR"), + }, + .Stdcall, .Fastcall, .Thiscall => switch (arch) { + .i386 => null, + else => @as([]const u8, "i386"), + }, + .Vectorcall => switch (arch) { + .i386, .aarch64, .aarch64_be, .aarch64_32 => null, + else => @as([]const u8, "i386 and AArch64"), + }, + .APCS, .AAPCS, .AAPCSVFP => switch (arch) { + .arm, .armeb, .aarch64, .aarch64_be, .aarch64_32 => null, + else => @as([]const u8, "ARM"), + }, + .SysV, .Win64 => switch (arch) { + .x86_64 => null, + else => @as([]const u8, "x86_64"), + }, + .PtxKernel => switch (arch) { + .nvptx, .nvptx64 => null, + else => @as([]const u8, "nvptx and nvptx64"), + }, + }) |allowed_platform| { + return sema.fail(block, cc_src, "callconv '{s}' is only available on {s}, not {s}", .{ + @tagName(cc_workaround), + allowed_platform, + @tagName(arch), + }); + } + break :fn_ty try Type.Tag.function.create(sema.arena, .{ .param_types = param_types, .comptime_params = comptime_params.ptr, @@ -7617,11 +7687,11 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; const dest_ty = try sema.resolveType(block, dest_ty_src, extra.lhs); + const operand = try sema.resolveInst(extra.rhs); switch (dest_ty.zigTypeTag()) { .AnyFrame, .ComptimeFloat, .ComptimeInt, - .Enum, .EnumLiteral, .ErrorSet, .ErrorUnion, @@ -7634,7 +7704,21 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air .Type, .Undefined, .Void, - => return sema.fail(block, dest_ty_src, "invalid type '{}' for @bitCast", .{dest_ty.fmt(sema.mod)}), + => return sema.fail(block, dest_ty_src, "cannot @bitCast to '{}'", .{dest_ty.fmt(sema.mod)}), + + .Enum => { + const msg = msg: { + const msg = try sema.errMsg(block, dest_ty_src, "cannot @bitCast to '{}'", .{dest_ty.fmt(sema.mod)}); + errdefer msg.destroy(sema.gpa); + switch (sema.typeOf(operand).zigTypeTag()) { + .Int, .ComptimeInt => try sema.errNote(block, dest_ty_src, msg, "use @intToEnum for type coercion", .{}), + else => {}, + } + + break :msg msg; + }; + return sema.failWithOwnedErrorMsg(block, msg); + }, .Pointer => return sema.fail(block, dest_ty_src, "cannot @bitCast to '{}', use @ptrCast to cast to a pointer", .{ dest_ty.fmt(sema.mod), @@ -7658,8 +7742,6 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air .Vector, => {}, } - - const operand = try sema.resolveInst(extra.rhs); return sema.bitCast(block, dest_ty, operand, operand_src); } @@ -7717,12 +7799,12 @@ fn zirElemVal(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air const tracy = trace(@src()); defer tracy.end(); - const bin_inst = sema.code.instructions.items(.data)[inst].bin; - const src = sema.src; // TODO better source location - const elem_index_src = sema.src; // TODO better source location - const array = try sema.resolveInst(bin_inst.lhs); - const elem_index = try sema.resolveInst(bin_inst.rhs); - return sema.elemVal(block, src, array, elem_index, elem_index_src); + const inst_data = sema.code.instructions.items(.data)[inst].pl_node; + const src = inst_data.src(); + const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; + const array = try sema.resolveInst(extra.lhs); + const elem_index = try sema.resolveInst(extra.rhs); + return sema.elemVal(block, src, array, elem_index, src); } fn zirElemValNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { @@ -7742,10 +7824,12 @@ fn zirElemPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air const tracy = trace(@src()); defer tracy.end(); - const bin_inst = sema.code.instructions.items(.data)[inst].bin; - const array_ptr = try sema.resolveInst(bin_inst.lhs); - const elem_index = try sema.resolveInst(bin_inst.rhs); - return sema.elemPtr(block, sema.src, array_ptr, elem_index, sema.src, false); + const inst_data = sema.code.instructions.items(.data)[inst].pl_node; + const src = inst_data.src(); + const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; + const array_ptr = try sema.resolveInst(extra.lhs); + const elem_index = try sema.resolveInst(extra.rhs); + return sema.elemPtr(block, src, array_ptr, elem_index, src, false); } fn zirElemPtrNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { @@ -8297,19 +8381,15 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError block, src, msg, - "unhandled error value: error.{s}", + "unhandled error value: 'error.{s}'", .{error_name}, ); } } if (maybe_msg) |msg| { - try sema.mod.errNoteNonLazy( - operand_ty.declSrcLoc(sema.mod), - msg, - "error set '{}' declared here", - .{operand_ty.fmt(sema.mod)}, - ); + maybe_msg = null; + try sema.addDeclaredHereNote(msg, operand_ty); return sema.failWithOwnedErrorMsg(block, msg); } @@ -17062,9 +17142,7 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr const field_index = struct_obj.fields.getIndex(field_name) orelse return sema.failWithBadStructFieldAccess(block, struct_obj, name_src, field_name); - if (field_ptr_ty.zigTypeTag() != .Pointer) { - return sema.fail(block, ty_src, "expected pointer type, found '{}'", .{field_ptr_ty.fmt(sema.mod)}); - } + try sema.checkPtrOperand(block, ptr_src, field_ptr_ty); const field = struct_obj.fields.values()[field_index]; const field_ptr_ty_info = field_ptr_ty.ptrInfo().data; @@ -17087,8 +17165,29 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr const result_ptr = try Type.ptr(sema.arena, sema.mod, ptr_ty_data); if (try sema.resolveDefinedValue(block, src, casted_field_ptr)) |field_ptr_val| { - const payload = field_ptr_val.castTag(.field_ptr).?.data; - return sema.addConstant(result_ptr, payload.container_ptr); + const payload = field_ptr_val.castTag(.field_ptr) orelse { + return sema.fail(block, ptr_src, "pointer value not based on parent struct", .{}); + }; + if (payload.data.field_index != field_index) { + const msg = msg: { + const msg = try sema.errMsg( + block, + src, + "field '{s}' has index '{d}' but pointer value is index '{d}' of struct '{}'", + .{ + field_name, + field_index, + payload.data.field_index, + struct_ty.fmt(sema.mod), + }, + ); + errdefer msg.destroy(sema.gpa); + try sema.addDeclaredHereNote(msg, struct_ty); + break :msg msg; + }; + return sema.failWithOwnedErrorMsg(block, msg); + } + return sema.addConstant(result_ptr, payload.data.container_ptr); } try sema.requireRuntimeBlock(block, src); @@ -18434,7 +18533,16 @@ fn fieldVal( kw_name, child_type.fmt(sema.mod), field_name, }); }, - else => return sema.fail(block, src, "type '{}' has no members", .{child_type.fmt(sema.mod)}), + else => { + const msg = msg: { + const msg = try sema.errMsg(block, src, "type '{}' has no members", .{child_type.fmt(sema.mod)}); + errdefer msg.destroy(sema.gpa); + if (child_type.isSlice()) try sema.errNote(block, src, msg, "slice values have 'len' and 'ptr' members", .{}); + if (child_type.zigTypeTag() == .Array) try sema.errNote(block, src, msg, "array values have 'len' member", .{}); + break :msg msg; + }; + return sema.failWithOwnedErrorMsg(block, msg); + }, } }, .Struct => if (is_pointer_to) { @@ -18658,7 +18766,7 @@ fn fieldPtr( }, else => {}, } - return sema.fail(block, src, "type '{}' does not support field access (fieldPtr, {}.{s})", .{ object_ty.fmt(sema.mod), object_ptr_ty.fmt(sema.mod), field_name }); + return sema.fail(block, src, "type '{}' does not support field access", .{object_ty.fmt(sema.mod)}); } fn fieldCallBind( @@ -19349,7 +19457,7 @@ fn tupleFieldPtr( const tuple_fields = tuple_ty.tupleFields(); if (tuple_fields.types.len == 0) { - return sema.fail(block, field_index_src, "indexing into empty tuple", .{}); + return sema.fail(block, tuple_ptr_src, "indexing into empty tuple is not allowed", .{}); } if (field_index >= tuple_fields.types.len) { @@ -19392,7 +19500,7 @@ fn tupleField( const tuple_fields = tuple_ty.tupleFields(); if (tuple_fields.types.len == 0) { - return sema.fail(block, field_index_src, "indexing into empty tuple", .{}); + return sema.fail(block, tuple_src, "indexing into empty tuple is not allowed", .{}); } if (field_index >= tuple_fields.types.len) { @@ -19433,7 +19541,7 @@ fn elemValArray( const elem_ty = array_ty.childType(); if (array_len_s == 0) { - return sema.fail(block, elem_index_src, "indexing into empty array", .{}); + return sema.fail(block, array_src, "indexing into empty array is not allowed", .{}); } const maybe_undef_array_val = try sema.resolveMaybeUndefVal(block, array_src, array); @@ -19513,7 +19621,7 @@ fn elemPtrArray( const array_len_s = array_len + @boolToInt(array_sent); if (array_len_s == 0) { - return sema.fail(block, elem_index_src, "indexing into empty array", .{}); + return sema.fail(block, array_ptr_src, "indexing into empty array is not allowed", .{}); } const maybe_undef_array_ptr_val = try sema.resolveMaybeUndefVal(block, array_ptr_src, array_ptr); @@ -19595,7 +19703,7 @@ fn elemValSlice( const slice_len = slice_val.sliceLen(sema.mod); const slice_len_s = slice_len + @boolToInt(slice_sent); if (slice_len_s == 0) { - return sema.fail(block, elem_index_src, "indexing into empty slice", .{}); + return sema.fail(block, slice_src, "indexing into empty slice is not allowed", .{}); } if (maybe_index_val) |index_val| { const index = @intCast(usize, index_val.toUnsignedInt(target)); @@ -19652,7 +19760,7 @@ fn elemPtrSlice( const slice_len = slice_val.sliceLen(sema.mod); const slice_len_s = slice_len + @boolToInt(slice_sent); if (slice_len_s == 0) { - return sema.fail(block, elem_index_src, "indexing into empty slice", .{}); + return sema.fail(block, slice_src, "indexing into empty slice is not allowed", .{}); } if (offset) |index| { if (index >= slice_len_s) { diff --git a/src/Zir.zig b/src/Zir.zig @@ -370,24 +370,23 @@ pub const Inst = struct { /// Uses the `pl_node` union field. Payload is `Bin`. div, /// Given a pointer to an array, slice, or pointer, returns a pointer to the element at - /// the provided index. Uses the `bin` union field. Source location is implied - /// to be the same as the previous instruction. - elem_ptr, - /// Same as `elem_ptr` except also stores a source location node. + /// the provided index. /// Uses the `pl_node` union field. AST node is a[b] syntax. Payload is `Bin`. elem_ptr_node, + /// Same as `elem_ptr_node` but used only for for loop. + /// Uses the `pl_node` union field. AST node is the condition of a for loop. Payload is `Bin`. + elem_ptr, /// Same as `elem_ptr_node` except the index is stored immediately rather than /// as a reference to another ZIR instruction. /// Uses the `pl_node` union field. AST node is an element inside array initialization /// syntax. Payload is `ElemPtrImm`. elem_ptr_imm, /// Given an array, slice, or pointer, returns the element at the provided index. - /// Uses the `bin` union field. Source location is implied to be the same - /// as the previous instruction. - elem_val, - /// Same as `elem_val` except also stores a source location node. /// Uses the `pl_node` union field. AST node is a[b] syntax. Payload is `Bin`. elem_val_node, + /// Same as `elem_val_node` but used only for for loop. + /// Uses the `pl_node` union field. AST node is the condition of a for loop. Payload is `Bin`. + elem_val, /// Emits a compile error if the operand is not `void`. /// Uses the `un_node` field. ensure_result_used, @@ -729,6 +728,9 @@ pub const Inst = struct { /// Same as `validate_array_init` but additionally communicates that the /// resulting array initialization value is within a comptime scope. validate_array_init_comptime, + /// Check that operand type supports the dereference operand (.*). + /// Uses the `un_tok` field. + validate_deref, /// A struct literal with a specified type, with no fields. /// Uses the `un_node` field. struct_init_empty, @@ -1156,6 +1158,7 @@ pub const Inst = struct { .validate_struct_init_comptime, .validate_array_init, .validate_array_init_comptime, + .validate_deref, .struct_init_empty, .struct_init, .struct_init_ref, @@ -1309,6 +1312,7 @@ pub const Inst = struct { .validate_struct_init_comptime, .validate_array_init, .validate_array_init_comptime, + .validate_deref, .@"export", .export_value, .set_cold, @@ -1622,10 +1626,10 @@ pub const Inst = struct { .decl_val = .str_tok, .load = .un_node, .div = .pl_node, - .elem_ptr = .bin, + .elem_ptr = .pl_node, .elem_ptr_node = .pl_node, .elem_ptr_imm = .pl_node, - .elem_val = .bin, + .elem_val = .pl_node, .elem_val_node = .pl_node, .ensure_result_used = .un_node, .ensure_result_non_error = .un_node, @@ -1709,6 +1713,7 @@ pub const Inst = struct { .validate_struct_init_comptime = .pl_node, .validate_array_init = .pl_node, .validate_array_init_comptime = .pl_node, + .validate_deref = .un_tok, .struct_init_empty = .un_node, .field_type = .pl_node, .field_type_ref = .pl_node, diff --git a/src/print_zir.zig b/src/print_zir.zig @@ -144,8 +144,6 @@ const Writer = struct { switch (tag) { .array_type, .as, - .elem_ptr, - .elem_val, .store, .store_to_block_ptr, .store_to_inferred_ptr, @@ -242,6 +240,7 @@ const Writer = struct { .ret_tok, .ensure_err_payload_void, .closure_capture, + .validate_deref, => try self.writeUnTok(stream, inst), .bool_br_and, @@ -354,6 +353,8 @@ const Writer = struct { .minimum, .elem_ptr_node, .elem_val_node, + .elem_ptr, + .elem_val, .coerce_result_ptr, => try self.writePlNodeBin(stream, inst), diff --git a/src/type.zig b/src/type.zig @@ -189,7 +189,7 @@ pub const Type = extern union { .Frame, => false, - .Pointer => is_equality_cmp or ty.isCPtr(), + .Pointer => !ty.isSlice() and (is_equality_cmp or ty.isCPtr()), .Optional => { if (!is_equality_cmp) return false; var buf: Payload.ElemType = undefined; diff --git a/test/cases/compile_errors/assign_to_invalid_dereference.zig b/test/cases/compile_errors/assign_to_invalid_dereference.zig @@ -0,0 +1,9 @@ +export fn entry() void { + 'a'.* = 1; +} + +// error +// backend=stage2 +// target=native +// +// :2:8: error: cannot dereference non-pointer type 'comptime_int' diff --git a/test/cases/compile_errors/bitCast_to_enum_type.zig b/test/cases/compile_errors/bitCast_to_enum_type.zig @@ -0,0 +1,12 @@ +export fn entry() void { + const E = enum(u32) { a, b }; + const y = @bitCast(E, @as(u32, 3)); + _ = y; +} + +// error +// backend=stage2 +// target=native +// +// :3:24: error: cannot @bitCast to 'tmp.entry.E' +// :3:24: note: use @intToEnum for type coercion diff --git a/test/cases/compile_errors/bogus_compile_var.zig b/test/cases/compile_errors/bogus_compile_var.zig @@ -0,0 +1,8 @@ +const x = @import("builtin").bogus; +export fn entry() usize { return @sizeOf(@TypeOf(x)); } + +// error +// backend=stage2 +// target=native +// +// :1:29: error: struct 'builtin.builtin' has no member named 'bogus' diff --git a/test/cases/compile_errors/callconv_apcs_aapcs_aapcsvfp_on_unsupported_platform.zig b/test/cases/compile_errors/callconv_apcs_aapcs_aapcsvfp_on_unsupported_platform.zig @@ -0,0 +1,11 @@ +export fn entry1() callconv(.APCS) void {} +export fn entry2() callconv(.AAPCS) void {} +export fn entry3() callconv(.AAPCSVFP) void {} + +// error +// backend=stage2 +// target=x86_64-linux-none +// +// :1:30: error: callconv 'APCS' is only available on ARM, not x86_64 +// :2:30: error: callconv 'AAPCS' is only available on ARM, not x86_64 +// :3:30: error: callconv 'AAPCSVFP' is only available on ARM, not x86_64 diff --git a/test/cases/compile_errors/callconv_interrupt_on_unsupported_platform.zig b/test/cases/compile_errors/callconv_interrupt_on_unsupported_platform.zig @@ -0,0 +1,7 @@ +export fn entry() callconv(.Interrupt) void {} + +// error +// backend=stage2 +// target=aarch64-linux-none +// +// :1:29: error: callconv 'Interrupt' is only available on i386, x86_64, AVR, and MSP430, not aarch64 diff --git a/test/cases/compile_errors/callconv_signal_on_unsupported_platform.zig b/test/cases/compile_errors/callconv_signal_on_unsupported_platform.zig @@ -0,0 +1,7 @@ +export fn entry() callconv(.Signal) void {} + +// error +// backend=stage2 +// target=x86_64-linux-none +// +// :1:29: error: callconv 'Signal' is only available on AVR, not x86_64 diff --git a/test/cases/compile_errors/callconv_stdcall_fastcall_thiscall_on_unsupported_platform.zig b/test/cases/compile_errors/callconv_stdcall_fastcall_thiscall_on_unsupported_platform.zig @@ -0,0 +1,23 @@ +const F1 = fn () callconv(.Stdcall) void; +const F2 = fn () callconv(.Fastcall) void; +const F3 = fn () callconv(.Thiscall) void; +export fn entry1() void { + var a: F1 = undefined; + _ = a; +} +export fn entry2() void { + var a: F2 = undefined; + _ = a; +} +export fn entry3() void { + var a: F3 = undefined; + _ = a; +} + +// error +// backend=stage2 +// target=x86_64-linux-none +// +// :1:28: error: callconv 'Stdcall' is only available on i386, not x86_64 +// :2:28: error: callconv 'Fastcall' is only available on i386, not x86_64 +// :3:28: error: callconv 'Thiscall' is only available on i386, not x86_64 diff --git a/test/cases/compile_errors/callconv_vectorcall_on_unsupported_platform.zig b/test/cases/compile_errors/callconv_vectorcall_on_unsupported_platform.zig @@ -0,0 +1,7 @@ +export fn entry() callconv(.Vectorcall) void {} + +// error +// backend=stage2 +// target=x86_64-linux-none +// +// :1:29: error: callconv 'Vectorcall' is only available on i386 and AArch64, not x86_64 diff --git a/test/cases/compile_errors/compile-time_division_by_zero.zig b/test/cases/compile_errors/compile-time_division_by_zero.zig @@ -0,0 +1,12 @@ +comptime { + const a: i32 = 1; + const b: i32 = 0; + const c = a / b; + _ = c; +} + +// error +// backend=stage2 +// target=native +// +// :4:19: error: division by zero here causes undefined behavior diff --git a/test/cases/compile_errors/compile-time_remainder_division_by_zero.zig b/test/cases/compile_errors/compile-time_remainder_division_by_zero.zig @@ -0,0 +1,12 @@ +comptime { + const a: i32 = 1; + const b: i32 = 0; + const c = a % b; + _ = c; +} + +// error +// backend=stage2 +// target=native +// +// :4:19: error: division by zero here causes undefined behavior diff --git a/test/cases/compile_errors/compileLog_of_tagged_enum_doesnt_crash_the_compiler.zig b/test/cases/compile_errors/compileLog_of_tagged_enum_doesnt_crash_the_compiler.zig @@ -0,0 +1,17 @@ +const Bar = union(enum(u32)) { + X: i32 = 1 +}; + +fn testCompileLog(x: Bar) void { + @compileLog(x); +} + +pub export fn entry() void { + comptime testCompileLog(Bar{.X = 123}); +} + +// error +// backend=stage2 +// target=native +// +// :6:5: error: found compile log statement diff --git a/test/cases/compile_errors/compile_log.zig b/test/cases/compile_errors/compile_log.zig @@ -0,0 +1,14 @@ +export fn foo() void { + comptime bar(12, "hi",); +} +fn bar(a: i32, b: []const u8) void { + @compileLog("begin",); + @compileLog("a", a, "b", b); + @compileLog("end",); +} + +// error +// backend=llvm +// target=native +// +// :5:5: error: found compile log statement diff --git a/test/cases/compile_errors/compile_log_statement_inside_function_which_must_be_comptime_evaluated.zig b/test/cases/compile_errors/compile_log_statement_inside_function_which_must_be_comptime_evaluated.zig @@ -0,0 +1,14 @@ +fn Foo(comptime T: type) type { + @compileLog(@typeName(T)); + return T; +} +export fn entry() void { + _ = Foo(i32); + _ = @typeName(Foo(i32)); +} + +// error +// backend=stage2 +// target=native +// +// :2:5: error: found compile log statement diff --git a/test/cases/compile_errors/compile_time_division_by_zero.zig b/test/cases/compile_errors/compile_time_division_by_zero.zig @@ -0,0 +1,13 @@ +const y = foo(0); +fn foo(x: u32) u32 { + return 1 / x; +} + +export fn entry() usize { return @sizeOf(@TypeOf(y)); } + +// error +// backend=llvm +// target=native +// +// :3:16: error: division by zero here causes undefined behavior +// :1:14: note: called from here diff --git a/test/cases/compile_errors/deref_on_undefined_value.zig b/test/cases/compile_errors/deref_on_undefined_value.zig @@ -0,0 +1,10 @@ +comptime { + var a: *u8 = undefined; + _ = a.*; +} + +// error +// backend=stage2 +// target=native +// +// :3:10: error: cannot dereference undefined value diff --git a/test/cases/compile_errors/deref_slice_and_get_len_field.zig b/test/cases/compile_errors/deref_slice_and_get_len_field.zig @@ -0,0 +1,10 @@ +export fn entry() void { + var a: []u8 = undefined; + _ = a.*.len; +} + +// error +// backend=stage2 +// target=native +// +// :3:10: error: index syntax required for slice type '[]u8' diff --git a/test/cases/compile_errors/dereference_an_array.zig b/test/cases/compile_errors/dereference_an_array.zig @@ -0,0 +1,14 @@ +var s_buffer: [10]u8 = undefined; +pub fn pass(in: []u8) []u8 { + var out = &s_buffer; + out.*.* = in[0]; + return out.*[0..1]; +} + +export fn entry() usize { return @sizeOf(@TypeOf(&pass)); } + +// error +// backend=stage2 +// target=native +// +// :4:10: error: cannot dereference non-pointer type '[10]u8' diff --git a/test/cases/compile_errors/dereference_slice.zig b/test/cases/compile_errors/dereference_slice.zig @@ -0,0 +1,12 @@ +fn entry(x: []i32) i32 { + return x.*; +} +comptime { + _ = entry; +} + +// error +// backend=stage2 +// target=native +// +// :2:13: error: index syntax required for slice type '[]i32' diff --git a/test/cases/compile_errors/dereference_unknown_length_pointer.zig b/test/cases/compile_errors/dereference_unknown_length_pointer.zig @@ -0,0 +1,9 @@ +export fn entry(x: [*]i32) i32 { + return x.*; +} + +// error +// backend=stage2 +// target=native +// +// :2:13: error: index syntax required for unknown-length pointer type '[*]i32' diff --git a/test/cases/compile_errors/discarding_error_value.zig b/test/cases/compile_errors/discarding_error_value.zig @@ -0,0 +1,12 @@ +export fn entry() void { + _ = foo(); +} +fn foo() !void { + return error.OutOfMemory; +} + +// error +// backend=stage2 +// target=native +// +// :2:12: error: error is discarded. consider using `try`, `catch`, or `if` diff --git a/test/cases/compile_errors/division_by_zero.zig b/test/cases/compile_errors/division_by_zero.zig @@ -0,0 +1,17 @@ +const lit_int_x = 1 / 0; +const lit_float_x = 1.0 / 0.0; +const int_x = @as(u32, 1) / @as(u32, 0); +const float_x = @as(f32, 1.0) / @as(f32, 0.0); + +export fn entry1() usize { return @sizeOf(@TypeOf(lit_int_x)); } +export fn entry2() usize { return @sizeOf(@TypeOf(lit_float_x)); } +export fn entry3() usize { return @sizeOf(@TypeOf(int_x)); } +export fn entry4() usize { return @sizeOf(@TypeOf(float_x)); } // no error on purpose + +// error +// backend=stage2 +// target=native +// +// :1:23: error: division by zero here causes undefined behavior +// :2:27: error: division by zero here causes undefined behavior +// :3:29: error: division by zero here causes undefined behavior diff --git a/test/cases/compile_errors/duplicate_enum_field.zig b/test/cases/compile_errors/duplicate_enum_field.zig @@ -0,0 +1,16 @@ +const Foo = enum { + Bar, + Bar, +}; + +export fn entry() void { + const a: Foo = undefined; + _ = a; +} + +// error +// backend=stage2 +// target=native +// +// :3:5: error: duplicate enum field 'Bar' +// :2:5: note: other field here diff --git a/test/cases/compile_errors/duplicate_error_in_switch.zig b/test/cases/compile_errors/duplicate_error_in_switch.zig @@ -0,0 +1,22 @@ +export fn entry() void { + foo(452) catch |err| switch (err) { + error.Foo => {}, + error.Bar => {}, + error.Foo => {}, + else => {}, + }; +} +fn foo(x: i32) !void { + switch (x) { + 0 ... 10 => return error.Foo, + 11 ... 20 => return error.Bar, + else => {}, + } +} + +// error +// backend=llvm +// target=native +// +// :5:9: error: duplicate switch value +// :3:9: note: other value here diff --git a/test/cases/compile_errors/error_not_handled_in_switch.zig b/test/cases/compile_errors/error_not_handled_in_switch.zig @@ -0,0 +1,21 @@ +export fn entry() void { + foo(452) catch |err| switch (err) { + error.Foo => {}, + }; +} +fn foo(x: i32) !void { + switch (x) { + 0 ... 10 => return error.Foo, + 11 ... 20 => return error.Bar, + 21 ... 30 => return error.Baz, + else => {}, + } +} + +// error +// backend=llvm +// target=native +// +// :2:26: error: switch must handle all possibilities +// :2:26: note: unhandled error value: 'error.Bar' +// :2:26: note: unhandled error value: 'error.Baz' diff --git a/test/cases/compile_errors/explicitly_casting_non_tag_type_to_enum.zig b/test/cases/compile_errors/explicitly_casting_non_tag_type_to_enum.zig @@ -0,0 +1,18 @@ +const Small = enum(u2) { + One, + Two, + Three, + Four, +}; + +export fn entry() void { + var y = @as(f32, 3); + var x = @intToEnum(Small, y); + _ = x; +} + +// error +// backend=stage2 +// target=native +// +// :10:31: error: expected integer type, found 'f32' diff --git a/test/cases/compile_errors/fieldParentPtr-comptime_field_ptr_not_based_on_struct.zig b/test/cases/compile_errors/fieldParentPtr-comptime_field_ptr_not_based_on_struct.zig @@ -0,0 +1,17 @@ +const Foo = struct { + a: i32, + b: i32, +}; +const foo = Foo { .a = 1, .b = 2, }; + +comptime { + const field_ptr = @intToPtr(*i32, 0x1234); + const another_foo_ptr = @fieldParentPtr(Foo, "b", field_ptr); + _ = another_foo_ptr; +} + +// error +// backend=stage2 +// target=native +// +// :9:55: error: pointer value not based on parent struct diff --git a/test/cases/compile_errors/fieldParentPtr-comptime_wrong_field_index.zig b/test/cases/compile_errors/fieldParentPtr-comptime_wrong_field_index.zig @@ -0,0 +1,17 @@ +const Foo = struct { + a: i32, + b: i32, +}; +const foo = Foo { .a = 1, .b = 2, }; + +comptime { + const another_foo_ptr = @fieldParentPtr(Foo, "b", &foo.a); + _ = another_foo_ptr; +} + +// error +// backend=stage2 +// target=native +// +// :8:29: error: field 'b' has index '1' but pointer value is index '0' of struct 'tmp.Foo' +// :1:13: note: struct declared here diff --git a/test/cases/compile_errors/fieldParentPtr-field_pointer_is_not_pointer.zig b/test/cases/compile_errors/fieldParentPtr-field_pointer_is_not_pointer.zig @@ -0,0 +1,12 @@ +const Foo = extern struct { + a: i32, +}; +export fn foo(a: i32) *Foo { + return @fieldParentPtr(Foo, "a", a); +} + +// error +// backend=stage2 +// target=native +// +// :5:38: error: expected pointer type, found 'i32' diff --git a/test/cases/compile_errors/field_access_of_opaque_type.zig b/test/cases/compile_errors/field_access_of_opaque_type.zig @@ -0,0 +1,16 @@ +const MyType = opaque {}; + +export fn entry() bool { + var x: i32 = 1; + return bar(@ptrCast(*MyType, &x)); +} + +fn bar(x: *MyType) bool { + return x.blah; +} + +// error +// backend=stage2 +// target=native +// +// :9:13: error: type '*tmp.MyType' does not support field access diff --git a/test/cases/compile_errors/field_access_of_slices.zig b/test/cases/compile_errors/field_access_of_slices.zig @@ -0,0 +1,12 @@ +export fn entry() void { + var slice: []i32 = undefined; + const info = @TypeOf(slice).unknown; + _ = info; +} + +// error +// backend=stage2 +// target=native +// +// :3:32: error: type '[]i32' has no members +// :3:32: note: slice values have 'len' and 'ptr' members diff --git a/test/cases/compile_errors/field_access_of_unknown_length_pointer.zig b/test/cases/compile_errors/field_access_of_unknown_length_pointer.zig @@ -0,0 +1,13 @@ +const Foo = extern struct { + a: i32, +}; + +export fn entry(foo: [*]Foo) void { + foo.a += 1; +} + +// error +// backend=stage2 +// target=native +// +// :6:8: error: type '[*]tmp.Foo' does not support field access diff --git a/test/cases/compile_errors/ignored_deferred_function_call.zig b/test/cases/compile_errors/ignored_deferred_function_call.zig @@ -0,0 +1,10 @@ +export fn foo() void { + defer bar(); +} +fn bar() anyerror!i32 { return 0; } + +// error +// backend=stage2 +// target=native +// +// :2:14: error: error is ignored. consider using `try`, `catch`, or `if` diff --git a/test/cases/compile_errors/ignored_expression_in_while_continuation.zig b/test/cases/compile_errors/ignored_expression_in_while_continuation.zig @@ -0,0 +1,22 @@ +export fn a() void { + while (true) : (bad()) {} +} +export fn b() void { + var x: anyerror!i32 = 1234; + while (x) |_| : (bad()) {} else |_| {} +} +export fn c() void { + var x: ?i32 = 1234; + while (x) |_| : (bad()) {} +} +fn bad() anyerror!void { + return error.Bad; +} + +// error +// backend=stage2 +// target=native +// +// :2:24: error: error is ignored. consider using `try`, `catch`, or `if` +// :6:25: error: error is ignored. consider using `try`, `catch`, or `if` +// :10:25: error: error is ignored. consider using `try`, `catch`, or `if` diff --git a/test/cases/compile_errors/illegal_comparison_of_types.zig b/test/cases/compile_errors/illegal_comparison_of_types.zig @@ -0,0 +1,20 @@ +fn bad_eql_1(a: []u8, b: []u8) bool { + return a == b; +} +const EnumWithData = union(enum) { + One: void, + Two: i32, +}; +fn bad_eql_2(a: *const EnumWithData, b: *const EnumWithData) bool { + return a.* == b.*; +} + +export fn entry1() usize { return @sizeOf(@TypeOf(&bad_eql_1)); } +export fn entry2() usize { return @sizeOf(@TypeOf(&bad_eql_2)); } + +// error +// backend=stage2 +// target=native +// +// :2:14: error: operator == not allowed for type '[]u8' +// :9:16: error: operator == not allowed for type 'tmp.EnumWithData' diff --git a/test/cases/compile_errors/implicitly_casting_enum_to_tag_type.zig b/test/cases/compile_errors/implicitly_casting_enum_to_tag_type.zig @@ -0,0 +1,17 @@ +const Small = enum(u2) { + One, + Two, + Three, + Four, +}; + +export fn entry() void { + var x: u2 = Small.Two; + _ = x; +} + +// error +// backend=stage2 +// target=native +// +// :9:22: error: expected type 'u2', found 'tmp.Small' diff --git a/test/cases/compile_errors/incorrect_return_type.zig b/test/cases/compile_errors/incorrect_return_type.zig @@ -0,0 +1,21 @@ + pub export fn entry() void{ + _ = foo(); + } + const A = struct { + a: u32, + }; + fn foo() A { + return bar(); + } + const B = struct { + a: u32, + }; + fn bar() B { + unreachable; + } + +// error +// backend=stage2 +// target=native +// +// :8:16: error: expected type 'tmp.A', found 'tmp.B' diff --git a/test/cases/compile_errors/indexing_an_array_of_size_zero.zig b/test/cases/compile_errors/indexing_an_array_of_size_zero.zig @@ -0,0 +1,11 @@ +const array = [_]u8{}; +export fn foo() void { + const pointer = &array[0]; + _ = pointer; +} + +// error +// backend=stage2 +// target=native +// +// :3:27: error: indexing into empty array is not allowed diff --git a/test/cases/compile_errors/indexing_an_array_of_size_zero_with_runtime_index.zig b/test/cases/compile_errors/indexing_an_array_of_size_zero_with_runtime_index.zig @@ -0,0 +1,12 @@ +const array = [_]u8{}; +export fn foo() void { + var index: usize = 0; + const pointer = &array[index]; + _ = pointer; +} + +// error +// backend=stage2 +// target=native +// +// :4:27: error: indexing into empty array is not allowed diff --git a/test/cases/compile_errors/indexing_single-item_pointer.zig b/test/cases/compile_errors/indexing_single-item_pointer.zig @@ -0,0 +1,9 @@ +export fn entry(ptr: *i32) i32 { + return ptr[1]; +} + +// error +// backend=stage2 +// target=native +// +// :2:15: error: element access of non-indexable type '*i32' diff --git a/test/cases/compile_errors/invalid_cast_from_integral_type_to_enum.zig b/test/cases/compile_errors/invalid_cast_from_integral_type_to_enum.zig @@ -0,0 +1,17 @@ +const E = enum(usize) { One, Two }; + +export fn entry() void { + foo(1); +} + +fn foo(x: usize) void { + switch (x) { + E.One => {}, + } +} + +// error +// backend=stage2 +// target=native +// +// :9:10: error: expected type 'usize', found 'tmp.E' diff --git a/test/cases/compile_errors/invalid_deref_on_switch_target.zig b/test/cases/compile_errors/invalid_deref_on_switch_target.zig @@ -0,0 +1,17 @@ +comptime { + var tile = Tile.Empty; + switch (tile.*) { + Tile.Empty => {}, + Tile.Filled => {}, + } +} +const Tile = enum { + Empty, + Filled, +}; + +// error +// backend=stage2 +// target=native +// +// :3:17: error: cannot dereference non-pointer type 'tmp.Tile' diff --git a/test/cases/compile_errors/invalid_multiple_dereferences.zig b/test/cases/compile_errors/invalid_multiple_dereferences.zig @@ -0,0 +1,19 @@ +export fn a() void { + var box = Box{ .field = 0 }; + box.*.field = 1; +} +export fn b() void { + var box = Box{ .field = 0 }; + var boxPtr = &box; + boxPtr.*.*.field = 1; +} +pub const Box = struct { + field: i32, +}; + +// error +// backend=stage2 +// target=native +// +// :3:8: error: cannot dereference non-pointer type 'tmp.Box' +// :8:13: error: cannot dereference non-pointer type 'tmp.Box' diff --git a/test/cases/compile_errors/runtime_indexing_comptime_array.zig b/test/cases/compile_errors/runtime_indexing_comptime_array.zig @@ -24,9 +24,9 @@ pub export fn entry3() void { // target=native // backend=stage2 // -// :6:5: error: values of type '[2]fn() void' must be comptime known, but index value is runtime known -// :6:5: note: use '*const fn() void' for a function pointer type -// :13:5: error: values of type '[2]fn() void' must be comptime known, but index value is runtime known -// :13:5: note: use '*const fn() void' for a function pointer type -// :19:5: error: values of type '[2]fn() void' must be comptime known, but index value is runtime known -// :19:5: note: use '*const fn() void' for a function pointer type +// :7:10: error: values of type '[2]fn() void' must be comptime known, but index value is runtime known +// :7:10: note: use '*const fn() void' for a function pointer type +// :15:18: error: values of type '[2]fn() void' must be comptime known, but index value is runtime known +// :15:17: note: use '*const fn() void' for a function pointer type +// :21:19: error: values of type '[2]fn() void' must be comptime known, but index value is runtime known +// :21:18: note: use '*const fn() void' for a function pointer type diff --git a/test/cases/compile_errors/stage1/obj/comptime_ptrcast_of_zero-sized_type.zig b/test/cases/compile_errors/stage1/comptime_ptrcast_of_zero-sized_type.zig diff --git a/test/cases/compile_errors/stage1/deref_on_undefined_value.zig b/test/cases/compile_errors/stage1/deref_on_undefined_value.zig @@ -1,10 +0,0 @@ -comptime { - var a: *u8 = undefined; - _ = a.*; -} - -// error -// backend=stage1 -// target=native -// -// tmp.zig:3:9: error: attempt to dereference undefined value diff --git a/test/cases/compile_errors/stage1/obj/error_equality_but_sets_have_no_common_members.zig b/test/cases/compile_errors/stage1/error_equality_but_sets_have_no_common_members.zig diff --git a/test/cases/compile_errors/stage1/obj/implicit_cast_from_f64_to_f32.zig b/test/cases/compile_errors/stage1/implicit_cast_from_f64_to_f32.zig diff --git a/test/cases/compile_errors/stage1/obj/int_to_ptr_of_0_bits.zig b/test/cases/compile_errors/stage1/int_to_ptr_of_0_bits.zig diff --git a/test/cases/compile_errors/stage1/obj/assign_to_invalid_dereference.zig b/test/cases/compile_errors/stage1/obj/assign_to_invalid_dereference.zig @@ -1,9 +0,0 @@ -export fn entry() void { - 'a'.* = 1; -} - -// error -// backend=stage1 -// target=native -// -// tmp.zig:2:8: error: attempt to dereference non-pointer type 'comptime_int' diff --git a/test/cases/compile_errors/stage1/obj/bitCast_to_enum_type.zig b/test/cases/compile_errors/stage1/obj/bitCast_to_enum_type.zig @@ -1,10 +0,0 @@ -export fn entry() void { - const y = @bitCast(enum(u32) { a, b }, @as(u32, 3)); - _ = y; -} - -// error -// backend=stage1 -// target=native -// -// tmp.zig:2:24: error: cannot cast a value of type 'y' diff --git a/test/cases/compile_errors/stage1/obj/bogus_compile_var.zig b/test/cases/compile_errors/stage1/obj/bogus_compile_var.zig @@ -1,8 +0,0 @@ -const x = @import("builtin").bogus; -export fn entry() usize { return @sizeOf(@TypeOf(x)); } - -// error -// backend=stage1 -// target=native -// -// tmp.zig:1:29: error: container 'builtin' has no member called 'bogus' diff --git a/test/cases/compile_errors/stage1/obj/callconv_apcs_aapcs_aapcsvfp_on_unsupported_platform.zig b/test/cases/compile_errors/stage1/obj/callconv_apcs_aapcs_aapcsvfp_on_unsupported_platform.zig @@ -1,11 +0,0 @@ -export fn entry1() callconv(.APCS) void {} -export fn entry2() callconv(.AAPCS) void {} -export fn entry3() callconv(.AAPCSVFP) void {} - -// error -// backend=stage1 -// target=x86_64-linux-none -// -// tmp.zig:1:29: error: callconv 'APCS' is only available on ARM, not x86_64 -// tmp.zig:2:29: error: callconv 'AAPCS' is only available on ARM, not x86_64 -// tmp.zig:3:29: error: callconv 'AAPCSVFP' is only available on ARM, not x86_64 diff --git a/test/cases/compile_errors/stage1/obj/callconv_interrupt_on_unsupported_platform.zig b/test/cases/compile_errors/stage1/obj/callconv_interrupt_on_unsupported_platform.zig @@ -1,7 +0,0 @@ -export fn entry() callconv(.Interrupt) void {} - -// error -// backend=stage1 -// target=aarch64-linux-none -// -// tmp.zig:1:28: error: callconv 'Interrupt' is only available on x86, x86_64, AVR, and MSP430, not aarch64 diff --git a/test/cases/compile_errors/stage1/obj/callconv_signal_on_unsupported_platform.zig b/test/cases/compile_errors/stage1/obj/callconv_signal_on_unsupported_platform.zig @@ -1,7 +0,0 @@ -export fn entry() callconv(.Signal) void {} - -// error -// backend=stage1 -// target=x86_64-linux-none -// -// tmp.zig:1:28: error: callconv 'Signal' is only available on AVR, not x86_64 diff --git a/test/cases/compile_errors/stage1/obj/callconv_stdcall_fastcall_thiscall_on_unsupported_platform-0.zig b/test/cases/compile_errors/stage1/obj/callconv_stdcall_fastcall_thiscall_on_unsupported_platform-0.zig @@ -1,23 +0,0 @@ -const F1 = fn () callconv(.Stdcall) void; -const F2 = fn () callconv(.Fastcall) void; -const F3 = fn () callconv(.Thiscall) void; -export fn entry1() void { - var a: F1 = undefined; - _ = a; -} -export fn entry2() void { - var a: F2 = undefined; - _ = a; -} -export fn entry3() void { - var a: F3 = undefined; - _ = a; -} - -// error -// backend=stage1 -// target=x86_64-linux-none -// -// tmp.zig:1:27: error: callconv 'Stdcall' is only available on x86, not x86_64 -// tmp.zig:2:27: error: callconv 'Fastcall' is only available on x86, not x86_64 -// tmp.zig:3:27: error: callconv 'Thiscall' is only available on x86, not x86_64 diff --git a/test/cases/compile_errors/stage1/obj/callconv_stdcall_fastcall_thiscall_on_unsupported_platform-1.zig b/test/cases/compile_errors/stage1/obj/callconv_stdcall_fastcall_thiscall_on_unsupported_platform-1.zig @@ -1,11 +0,0 @@ -export fn entry1() callconv(.Stdcall) void {} -export fn entry2() callconv(.Fastcall) void {} -export fn entry3() callconv(.Thiscall) void {} - -// error -// backend=stage1 -// target=x86_64-linux-none -// -// tmp.zig:1:29: error: callconv 'Stdcall' is only available on x86, not x86_64 -// tmp.zig:2:29: error: callconv 'Fastcall' is only available on x86, not x86_64 -// tmp.zig:3:29: error: callconv 'Thiscall' is only available on x86, not x86_64 diff --git a/test/cases/compile_errors/stage1/obj/callconv_vectorcall_on_unsupported_platform.zig b/test/cases/compile_errors/stage1/obj/callconv_vectorcall_on_unsupported_platform.zig @@ -1,7 +0,0 @@ -export fn entry() callconv(.Vectorcall) void {} - -// error -// backend=stage1 -// target=x86_64-linux-none -// -// tmp.zig:1:28: error: callconv 'Vectorcall' is only available on x86 and AArch64, not x86_64 diff --git a/test/cases/compile_errors/stage1/obj/compile-time_division_by_zero.zig b/test/cases/compile_errors/stage1/obj/compile-time_division_by_zero.zig @@ -1,12 +0,0 @@ -comptime { - const a: i32 = 1; - const b: i32 = 0; - const c = a / b; - _ = c; -} - -// error -// backend=stage1 -// target=native -// -// tmp.zig:4:17: error: division by zero diff --git a/test/cases/compile_errors/stage1/obj/compile-time_remainder_division_by_zero.zig b/test/cases/compile_errors/stage1/obj/compile-time_remainder_division_by_zero.zig @@ -1,12 +0,0 @@ -comptime { - const a: i32 = 1; - const b: i32 = 0; - const c = a % b; - _ = c; -} - -// error -// backend=stage1 -// target=native -// -// tmp.zig:4:17: error: division by zero diff --git a/test/cases/compile_errors/stage1/obj/compileLog_of_tagged_enum_doesnt_crash_the_compiler.zig b/test/cases/compile_errors/stage1/obj/compileLog_of_tagged_enum_doesnt_crash_the_compiler.zig @@ -1,17 +0,0 @@ -const Bar = union(enum(u32)) { - X: i32 = 1 -}; - -fn testCompileLog(x: Bar) void { - @compileLog(x); -} - -pub fn main () void { - comptime testCompileLog(Bar{.X = 123}); -} - -// error -// backend=stage1 -// target=native -// -// tmp.zig:6:5: error: found compile log statement diff --git a/test/cases/compile_errors/stage1/obj/compile_log.zig b/test/cases/compile_errors/stage1/obj/compile_log.zig @@ -1,16 +0,0 @@ -export fn foo() void { - comptime bar(12, "hi",); -} -fn bar(a: i32, b: []const u8) void { - @compileLog("begin",); - @compileLog("a", a, "b", b); - @compileLog("end",); -} - -// error -// backend=stage1 -// target=native -// -// tmp.zig:5:5: error: found compile log statement -// tmp.zig:6:5: error: found compile log statement -// tmp.zig:7:5: error: found compile log statement diff --git a/test/cases/compile_errors/stage1/obj/compile_log_statement_inside_function_which_must_be_comptime_evaluated.zig b/test/cases/compile_errors/stage1/obj/compile_log_statement_inside_function_which_must_be_comptime_evaluated.zig @@ -1,14 +0,0 @@ -fn Foo(comptime T: type) type { - @compileLog(@typeName(T)); - return T; -} -export fn entry() void { - _ = Foo(i32); - _ = @typeName(Foo(i32)); -} - -// error -// backend=stage1 -// target=native -// -// tmp.zig:2:5: error: found compile log statement diff --git a/test/cases/compile_errors/stage1/obj/compile_time_division_by_zero.zig b/test/cases/compile_errors/stage1/obj/compile_time_division_by_zero.zig @@ -1,12 +0,0 @@ -const y = foo(0); -fn foo(x: u32) u32 { - return 1 / x; -} - -export fn entry() usize { return @sizeOf(@TypeOf(y)); } - -// error -// backend=stage1 -// target=native -// -// tmp.zig:3:14: error: division by zero diff --git a/test/cases/compile_errors/stage1/obj/deref_slice_and_get_len_field.zig b/test/cases/compile_errors/stage1/obj/deref_slice_and_get_len_field.zig @@ -1,10 +0,0 @@ -export fn entry() void { - var a: []u8 = undefined; - _ = a.*.len; -} - -// error -// backend=stage1 -// target=native -// -// tmp.zig:3:10: error: attempt to dereference non-pointer type '[]u8' diff --git a/test/cases/compile_errors/stage1/obj/dereference_an_array.zig b/test/cases/compile_errors/stage1/obj/dereference_an_array.zig @@ -1,14 +0,0 @@ -var s_buffer: [10]u8 = undefined; -pub fn pass(in: []u8) []u8 { - var out = &s_buffer; - out.*.* = in[0]; - return out.*[0..1]; -} - -export fn entry() usize { return @sizeOf(@TypeOf(pass)); } - -// error -// backend=stage1 -// target=native -// -// tmp.zig:4:10: error: attempt to dereference non-pointer type '[10]u8' diff --git a/test/cases/compile_errors/stage1/obj/dereference_unknown_length_pointer.zig b/test/cases/compile_errors/stage1/obj/dereference_unknown_length_pointer.zig @@ -1,9 +0,0 @@ -export fn entry(x: [*]i32) i32 { - return x.*; -} - -// error -// backend=stage1 -// target=native -// -// tmp.zig:2:13: error: index syntax required for unknown-length pointer type '[*]i32' diff --git a/test/cases/compile_errors/stage1/obj/discarding_error_value.zig b/test/cases/compile_errors/stage1/obj/discarding_error_value.zig @@ -1,12 +0,0 @@ -export fn entry() void { - _ = foo(); -} -fn foo() !void { - return error.OutOfMemory; -} - -// error -// backend=stage1 -// target=native -// -// tmp.zig:2:12: error: error is discarded. consider using `try`, `catch`, or `if` diff --git a/test/cases/compile_errors/stage1/obj/division_by_zero.zig b/test/cases/compile_errors/stage1/obj/division_by_zero.zig @@ -1,18 +0,0 @@ -const lit_int_x = 1 / 0; -const lit_float_x = 1.0 / 0.0; -const int_x = @as(u32, 1) / @as(u32, 0); -const float_x = @as(f32, 1.0) / @as(f32, 0.0); - -export fn entry1() usize { return @sizeOf(@TypeOf(lit_int_x)); } -export fn entry2() usize { return @sizeOf(@TypeOf(lit_float_x)); } -export fn entry3() usize { return @sizeOf(@TypeOf(int_x)); } -export fn entry4() usize { return @sizeOf(@TypeOf(float_x)); } - -// error -// backend=stage1 -// target=native -// -// tmp.zig:1:21: error: division by zero -// tmp.zig:2:25: error: division by zero -// tmp.zig:3:27: error: division by zero -// tmp.zig:4:31: error: division by zero diff --git a/test/cases/compile_errors/stage1/obj/duplicate_enum_field.zig b/test/cases/compile_errors/stage1/obj/duplicate_enum_field.zig @@ -1,16 +0,0 @@ -const Foo = enum { - Bar, - Bar, -}; - -export fn entry() void { - const a: Foo = undefined; - _ = a; -} - -// error -// backend=stage1 -// target=native -// -// tmp.zig:3:5: error: duplicate enum field: 'Bar' -// tmp.zig:2:5: note: other field here diff --git a/test/cases/compile_errors/stage1/obj/duplicate_error_in_switch.zig b/test/cases/compile_errors/stage1/obj/duplicate_error_in_switch.zig @@ -1,22 +0,0 @@ -export fn entry() void { - foo(452) catch |err| switch (err) { - error.Foo => {}, - error.Bar => {}, - error.Foo => {}, - else => {}, - }; -} -fn foo(x: i32) !void { - switch (x) { - 0 ... 10 => return error.Foo, - 11 ... 20 => return error.Bar, - else => {}, - } -} - -// error -// backend=stage1 -// target=native -// -// tmp.zig:5:14: error: duplicate switch value: '@typeInfo(@typeInfo(@TypeOf(foo)).Fn.return_type.?).ErrorUnion.error_set.Foo' -// tmp.zig:3:14: note: other value here diff --git a/test/cases/compile_errors/stage1/obj/error_not_handled_in_switch.zig b/test/cases/compile_errors/stage1/obj/error_not_handled_in_switch.zig @@ -1,20 +0,0 @@ -export fn entry() void { - foo(452) catch |err| switch (err) { - error.Foo => {}, - }; -} -fn foo(x: i32) !void { - switch (x) { - 0 ... 10 => return error.Foo, - 11 ... 20 => return error.Bar, - 21 ... 30 => return error.Baz, - else => {}, - } -} - -// error -// backend=stage1 -// target=native -// -// tmp.zig:2:26: error: error.Baz not handled in switch -// tmp.zig:2:26: error: error.Bar not handled in switch diff --git a/test/cases/compile_errors/stage1/obj/explicitly_casting_non_tag_type_to_enum.zig b/test/cases/compile_errors/stage1/obj/explicitly_casting_non_tag_type_to_enum.zig @@ -1,18 +0,0 @@ -const Small = enum(u2) { - One, - Two, - Three, - Four, -}; - -export fn entry() void { - var y = @as(f32, 3); - var x = @intToEnum(Small, y); - _ = x; -} - -// error -// backend=stage1 -// target=native -// -// tmp.zig:10:31: error: expected integer type, found 'f32' diff --git a/test/cases/compile_errors/stage1/obj/fieldParentPtr-comptime_field_ptr_not_based_on_struct.zig b/test/cases/compile_errors/stage1/obj/fieldParentPtr-comptime_field_ptr_not_based_on_struct.zig @@ -1,17 +0,0 @@ -const Foo = struct { - a: i32, - b: i32, -}; -const foo = Foo { .a = 1, .b = 2, }; - -comptime { - const field_ptr = @intToPtr(*i32, 0x1234); - const another_foo_ptr = @fieldParentPtr(Foo, "b", field_ptr); - _ = another_foo_ptr; -} - -// error -// backend=stage1 -// target=native -// -// tmp.zig:9:55: error: pointer value not based on parent struct diff --git a/test/cases/compile_errors/stage1/obj/fieldParentPtr-comptime_wrong_field_index.zig b/test/cases/compile_errors/stage1/obj/fieldParentPtr-comptime_wrong_field_index.zig @@ -1,16 +0,0 @@ -const Foo = struct { - a: i32, - b: i32, -}; -const foo = Foo { .a = 1, .b = 2, }; - -comptime { - const another_foo_ptr = @fieldParentPtr(Foo, "b", &foo.a); - _ = another_foo_ptr; -} - -// error -// backend=stage1 -// target=native -// -// tmp.zig:8:29: error: field 'b' has index 1 but pointer value is index 0 of struct 'Foo' diff --git a/test/cases/compile_errors/stage1/obj/fieldParentPtr-field_pointer_is_not_pointer.zig b/test/cases/compile_errors/stage1/obj/fieldParentPtr-field_pointer_is_not_pointer.zig @@ -1,12 +0,0 @@ -const Foo = extern struct { - a: i32, -}; -export fn foo(a: i32) *Foo { - return @fieldParentPtr(Foo, "a", a); -} - -// error -// backend=stage1 -// target=native -// -// tmp.zig:5:38: error: expected pointer, found 'i32' diff --git a/test/cases/compile_errors/stage1/obj/field_access_of_opaque_type.zig b/test/cases/compile_errors/stage1/obj/field_access_of_opaque_type.zig @@ -1,16 +0,0 @@ -const MyType = opaque {}; - -export fn entry() bool { - var x: i32 = 1; - return bar(@ptrCast(*MyType, &x)); -} - -fn bar(x: *MyType) bool { - return x.blah; -} - -// error -// backend=stage1 -// target=native -// -// tmp.zig:9:13: error: no member named 'blah' in opaque type 'MyType' diff --git a/test/cases/compile_errors/stage1/obj/field_access_of_slices.zig b/test/cases/compile_errors/stage1/obj/field_access_of_slices.zig @@ -1,11 +0,0 @@ -export fn entry() void { - var slice: []i32 = undefined; - const info = @TypeOf(slice).unknown; - _ = info; -} - -// error -// backend=stage1 -// target=native -// -// tmp.zig:3:32: error: type 'type' does not support field access diff --git a/test/cases/compile_errors/stage1/obj/field_access_of_unknown_length_pointer.zig b/test/cases/compile_errors/stage1/obj/field_access_of_unknown_length_pointer.zig @@ -1,13 +0,0 @@ -const Foo = extern struct { - a: i32, -}; - -export fn entry(foo: [*]Foo) void { - foo.a += 1; -} - -// error -// backend=stage1 -// target=native -// -// tmp.zig:6:8: error: type '[*]Foo' does not support field access diff --git a/test/cases/compile_errors/stage1/obj/ignored_deferred_function_call.zig b/test/cases/compile_errors/stage1/obj/ignored_deferred_function_call.zig @@ -1,10 +0,0 @@ -export fn foo() void { - defer bar(); -} -fn bar() anyerror!i32 { return 0; } - -// error -// backend=stage1 -// target=native -// -// tmp.zig:2:14: error: error is ignored. consider using `try`, `catch`, or `if` diff --git a/test/cases/compile_errors/stage1/obj/ignored_expression_in_while_continuation.zig b/test/cases/compile_errors/stage1/obj/ignored_expression_in_while_continuation.zig @@ -1,22 +0,0 @@ -export fn a() void { - while (true) : (bad()) {} -} -export fn b() void { - var x: anyerror!i32 = 1234; - while (x) |_| : (bad()) {} else |_| {} -} -export fn c() void { - var x: ?i32 = 1234; - while (x) |_| : (bad()) {} -} -fn bad() anyerror!void { - return error.Bad; -} - -// error -// backend=stage1 -// target=native -// -// tmp.zig:2:24: error: error is ignored. consider using `try`, `catch`, or `if` -// tmp.zig:6:25: error: error is ignored. consider using `try`, `catch`, or `if` -// tmp.zig:10:25: error: error is ignored. consider using `try`, `catch`, or `if` diff --git a/test/cases/compile_errors/stage1/obj/illegal_comparison_of_types.zig b/test/cases/compile_errors/stage1/obj/illegal_comparison_of_types.zig @@ -1,20 +0,0 @@ -fn bad_eql_1(a: []u8, b: []u8) bool { - return a == b; -} -const EnumWithData = union(enum) { - One: void, - Two: i32, -}; -fn bad_eql_2(a: *const EnumWithData, b: *const EnumWithData) bool { - return a.* == b.*; -} - -export fn entry1() usize { return @sizeOf(@TypeOf(bad_eql_1)); } -export fn entry2() usize { return @sizeOf(@TypeOf(bad_eql_2)); } - -// error -// backend=stage1 -// target=native -// -// tmp.zig:2:14: error: operator not allowed for type '[]u8' -// tmp.zig:9:16: error: operator not allowed for type 'EnumWithData' diff --git a/test/cases/compile_errors/stage1/obj/implicitly_casting_enum_to_tag_type.zig b/test/cases/compile_errors/stage1/obj/implicitly_casting_enum_to_tag_type.zig @@ -1,17 +0,0 @@ -const Small = enum(u2) { - One, - Two, - Three, - Four, -}; - -export fn entry() void { - var x: u2 = Small.Two; - _ = x; -} - -// error -// backend=stage1 -// target=native -// -// tmp.zig:9:22: error: expected type 'u2', found 'Small' diff --git a/test/cases/compile_errors/stage1/obj/incorrect_return_type.zig b/test/cases/compile_errors/stage1/obj/incorrect_return_type.zig @@ -1,21 +0,0 @@ - pub export fn entry() void{ - _ = foo(); - } - const A = struct { - a: u32, - }; - fn foo() A { - return bar(); - } - const B = struct { - a: u32, - }; - fn bar() B { - unreachable; - } - -// error -// backend=stage1 -// target=native -// -// tmp.zig:8:16: error: expected type 'A', found 'B' diff --git a/test/cases/compile_errors/stage1/obj/indexing_an_array_of_size_zero.zig b/test/cases/compile_errors/stage1/obj/indexing_an_array_of_size_zero.zig @@ -1,11 +0,0 @@ -const array = [_]u8{}; -export fn foo() void { - const pointer = &array[0]; - _ = pointer; -} - -// error -// backend=stage1 -// target=native -// -// tmp.zig:3:27: error: accessing a zero length array is not allowed diff --git a/test/cases/compile_errors/stage1/obj/indexing_an_array_of_size_zero_with_runtime_index.zig b/test/cases/compile_errors/stage1/obj/indexing_an_array_of_size_zero_with_runtime_index.zig @@ -1,12 +0,0 @@ -const array = [_]u8{}; -export fn foo() void { - var index: usize = 0; - const pointer = &array[index]; - _ = pointer; -} - -// error -// backend=stage1 -// target=native -// -// tmp.zig:4:27: error: accessing a zero length array is not allowed diff --git a/test/cases/compile_errors/stage1/obj/indexing_single-item_pointer.zig b/test/cases/compile_errors/stage1/obj/indexing_single-item_pointer.zig @@ -1,9 +0,0 @@ -export fn entry(ptr: *i32) i32 { - return ptr[1]; -} - -// error -// backend=stage1 -// target=native -// -// tmp.zig:2:15: error: index of single-item pointer diff --git a/test/cases/compile_errors/stage1/obj/invalid_cast_from_integral_type_to_enum.zig b/test/cases/compile_errors/stage1/obj/invalid_cast_from_integral_type_to_enum.zig @@ -1,17 +0,0 @@ -const E = enum(usize) { One, Two }; - -export fn entry() void { - foo(1); -} - -fn foo(x: usize) void { - switch (x) { - E.One => {}, - } -} - -// error -// backend=stage1 -// target=native -// -// tmp.zig:9:10: error: expected type 'usize', found 'E' diff --git a/test/cases/compile_errors/stage1/obj/invalid_deref_on_switch_target.zig b/test/cases/compile_errors/stage1/obj/invalid_deref_on_switch_target.zig @@ -1,17 +0,0 @@ -comptime { - var tile = Tile.Empty; - switch (tile.*) { - Tile.Empty => {}, - Tile.Filled => {}, - } -} -const Tile = enum { - Empty, - Filled, -}; - -// error -// backend=stage1 -// target=native -// -// tmp.zig:3:17: error: attempt to dereference non-pointer type 'Tile' diff --git a/test/cases/compile_errors/stage1/obj/invalid_multiple_dereferences.zig b/test/cases/compile_errors/stage1/obj/invalid_multiple_dereferences.zig @@ -1,19 +0,0 @@ -export fn a() void { - var box = Box{ .field = 0 }; - box.*.field = 1; -} -export fn b() void { - var box = Box{ .field = 0 }; - var boxPtr = &box; - boxPtr.*.*.field = 1; -} -pub const Box = struct { - field: i32, -}; - -// error -// backend=stage1 -// target=native -// -// tmp.zig:3:8: error: attempt to dereference non-pointer type 'Box' -// tmp.zig:8:13: error: attempt to dereference non-pointer type 'Box' diff --git a/test/cases/compile_errors/stage1/obj/take_slice_of_invalid_dereference.zig b/test/cases/compile_errors/stage1/obj/take_slice_of_invalid_dereference.zig @@ -1,10 +0,0 @@ -export fn entry() void { - const x = 'a'.*[0..]; - _ = x; -} - -// error -// backend=stage1 -// target=native -// -// tmp.zig:2:18: error: attempt to dereference non-pointer type 'comptime_int' diff --git a/test/cases/compile_errors/take_slice_of_invalid_dereference.zig b/test/cases/compile_errors/take_slice_of_invalid_dereference.zig @@ -0,0 +1,10 @@ +export fn entry() void { + const x = 'a'.*[0..]; + _ = x; +} + +// error +// backend=stage2 +// target=native +// +// :2:18: error: cannot dereference non-pointer type 'comptime_int' diff --git a/test/stage2/cbe.zig b/test/stage2/cbe.zig @@ -729,8 +729,8 @@ pub fn addCases(ctx: *TestContext) !void { \\ _ = E1.a; \\} , &.{ - ":1:28: error: duplicate enum tag", - ":1:22: note: other tag here", + ":1:28: error: duplicate enum field 'b'", + ":1:22: note: other field here", }); case.addError(