diff options
| -rw-r--r-- | src/Sema.zig | 62 | ||||
| -rw-r--r-- | test/cases/compile_errors/array_access_of_non_array.zig | 10 | ||||
| -rw-r--r-- | test/cases/compile_errors/array_access_of_type.zig | 3 | ||||
| -rw-r--r-- | test/cases/compile_errors/compile_time_null_ptr_cast.zig | 2 | ||||
| -rw-r--r-- | test/cases/compile_errors/for.zig | 4 | ||||
| -rw-r--r-- | test/cases/compile_errors/incorrect_type_to_memset_memcpy.zig | 8 | ||||
| -rw-r--r-- | test/cases/compile_errors/indexing_non-tuple_struct.zig | 3 | ||||
| -rw-r--r-- | test/cases/compile_errors/indexing_single-item_pointer.zig | 3 |
8 files changed, 46 insertions, 49 deletions
diff --git a/src/Sema.zig b/src/Sema.zig index b2387dfe12..225a6c5bff 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -3401,8 +3401,8 @@ fn indexablePtrLen( ) CompileError!Air.Inst.Ref { const object_ty = sema.typeOf(object); const is_pointer_to = object_ty.isSinglePointer(); - const array_ty = if (is_pointer_to) object_ty.childType() else object_ty; - try checkIndexable(sema, block, src, array_ty); + const indexable_ty = if (is_pointer_to) object_ty.childType() else object_ty; + try checkIndexable(sema, block, src, indexable_ty); return sema.fieldVal(block, src, object, "len", src); } @@ -3413,7 +3413,7 @@ fn indexablePtrLenOrNone( object: Air.Inst.Ref, ) CompileError!Air.Inst.Ref { const object_ty = sema.typeOf(object); - const array_ty = t: { + const indexable_ty = t: { const ptr_size = object_ty.ptrSizeOrNull() orelse break :t object_ty; break :t switch (ptr_size) { .Many => return .none, @@ -3421,7 +3421,7 @@ fn indexablePtrLenOrNone( else => object_ty, }; }; - try checkIndexable(sema, block, src, array_ty); + try checkIndexable(sema, block, src, indexable_ty); return sema.fieldVal(block, src, object, "len", src); } @@ -3991,7 +3991,16 @@ fn zirForLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. .input_index = i, } }; const arg_len_uncoerced = if (is_int) object else l: { - try checkIndexable(sema, block, arg_src, object_ty); + if (!object_ty.isIndexable()) { + // Instead of using checkIndexable we customize this error. + const msg = msg: { + const msg = try sema.errMsg(block, arg_src, "type '{}' is not indexable and not a range", .{object_ty.fmt(sema.mod)}); + errdefer msg.destroy(sema.gpa); + try sema.errNote(block, arg_src, msg, "for loop operand must be a range, array, slice, tuple, or vector", .{}); + break :msg msg; + }; + return sema.failWithOwnedErrorMsg(msg); + } if (!object_ty.indexableHasLen()) continue; break :l try sema.fieldVal(block, arg_src, object, "len", arg_src); @@ -19910,7 +19919,7 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air return sema.failWithUseOfUndef(block, operand_src); } if (!dest_ty.ptrAllowsZero() and operand_val.isNull()) { - return sema.fail(block, operand_src, "null pointer casted to type {}", .{dest_ty.fmt(sema.mod)}); + return sema.fail(block, operand_src, "null pointer casted to type '{}'", .{dest_ty.fmt(sema.mod)}); } if (dest_ty.zigTypeTag() == .Optional and sema.typeOf(ptr).zigTypeTag() != .Optional) { return sema.addConstant(dest_ty, try Value.Tag.opt_payload.create(sema.arena, operand_val)); @@ -22013,10 +22022,10 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void const msg = msg: { const msg = try sema.errMsg(block, src, "unknown @memcpy length", .{}); errdefer msg.destroy(sema.gpa); - try sema.errNote(block, dest_src, msg, "destination type {} provides no length", .{ + try sema.errNote(block, dest_src, msg, "destination type '{}' provides no length", .{ sema.typeOf(dest_ptr).fmt(sema.mod), }); - try sema.errNote(block, src_src, msg, "source type {} provides no length", .{ + try sema.errNote(block, src_src, msg, "source type '{}' provides no length", .{ sema.typeOf(src_ptr).fmt(sema.mod), }); break :msg msg; @@ -22746,7 +22755,7 @@ fn resolveExternOptions( const payload = library_name_val.castTag(.opt_payload).?.data; const library_name = try payload.toAllocatedBytes(Type.initTag(.const_slice_u8), sema.arena, mod); if (library_name.len == 0) { - return sema.fail(block, library_src, "library name name cannot be empty", .{}); + return sema.fail(block, library_src, "library name cannot be empty", .{}); } break :blk try sema.handleExternLibName(block, library_src, library_name); } else null; @@ -24767,9 +24776,7 @@ fn elemPtr( .Pointer => indexable_ptr_ty.elemType(), else => return sema.fail(block, indexable_ptr_src, "expected pointer, found '{}'", .{indexable_ptr_ty.fmt(sema.mod)}), }; - if (!indexable_ty.isIndexable()) { - return sema.fail(block, src, "element access of non-indexable type '{}'", .{indexable_ty.fmt(sema.mod)}); - } + try checkIndexable(sema, block, src, indexable_ty); switch (indexable_ty.zigTypeTag()) { .Array, .Vector => return sema.elemPtrArray(block, src, indexable_ptr_src, indexable_ptr, elem_index_src, elem_index, init, oob_safety), @@ -24801,9 +24808,7 @@ fn elemPtrOneLayerOnly( const indexable_ty = sema.typeOf(indexable); const target = sema.mod.getTarget(); - if (!indexable_ty.isIndexable()) { - return sema.fail(block, src, "element access of non-indexable type '{}'", .{indexable_ty.fmt(sema.mod)}); - } + try checkIndexable(sema, block, src, indexable_ty); switch (indexable_ty.ptrSize()) { .Slice => return sema.elemPtrSlice(block, src, indexable_src, indexable, elem_index_src, elem_index, oob_safety), @@ -24824,7 +24829,7 @@ fn elemPtrOneLayerOnly( return block.addPtrElemPtr(indexable, elem_index, result_ty); }, .One => { - assert(indexable_ty.childType().zigTypeTag() == .Array); // Guaranteed by isIndexable + assert(indexable_ty.childType().zigTypeTag() == .Array); // Guaranteed by checkIndexable return sema.elemPtrArray(block, src, indexable_src, indexable, elem_index_src, elem_index, init, oob_safety); }, } @@ -24843,9 +24848,7 @@ fn elemVal( const indexable_ty = sema.typeOf(indexable); const target = sema.mod.getTarget(); - if (!indexable_ty.isIndexable()) { - return sema.fail(block, src, "element access of non-indexable type '{}'", .{indexable_ty.fmt(sema.mod)}); - } + try checkIndexable(sema, block, src, indexable_ty); // TODO in case of a vector of pointers, we need to detect whether the element // index is a scalar or vector instead of unconditionally casting to usize. @@ -24873,7 +24876,7 @@ fn elemVal( return block.addBinOp(.ptr_elem_val, indexable, elem_index); }, .One => { - assert(indexable_ty.childType().zigTypeTag() == .Array); // Guaranteed by isIndexable + assert(indexable_ty.childType().zigTypeTag() == .Array); // Guaranteed by checkIndexable const elem_ptr = try sema.elemPtr(block, indexable_src, indexable, elem_index, elem_index_src, false, oob_safety); return sema.analyzeLoad(block, indexable_src, elem_ptr, elem_index_src); }, @@ -30997,23 +31000,12 @@ fn checkBackingIntType(sema: *Sema, block: *Block, src: LazySrcLoc, backing_int_ } } -fn checkIndexable(sema: *Sema, block: *Block, src: LazySrcLoc, array_ty: Type) !void { - if (!array_ty.isIndexable()) { +fn checkIndexable(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) !void { + if (!ty.isIndexable()) { const msg = msg: { - const msg = try sema.errMsg( - block, - src, - "type '{}' does not support indexing", - .{array_ty.fmt(sema.mod)}, - ); + const msg = try sema.errMsg(block, src, "type '{}' does not support indexing", .{ty.fmt(sema.mod)}); errdefer msg.destroy(sema.gpa); - try sema.errNote( - block, - src, - msg, - "for loop operand must be an array, slice, tuple, or vector", - .{}, - ); + try sema.errNote(block, src, msg, "operand must be an array, slice, tuple, or vector", .{}); break :msg msg; }; return sema.failWithOwnedErrorMsg(msg); diff --git a/test/cases/compile_errors/array_access_of_non_array.zig b/test/cases/compile_errors/array_access_of_non_array.zig index 06fa1569e6..0f06bae1dd 100644 --- a/test/cases/compile_errors/array_access_of_non_array.zig +++ b/test/cases/compile_errors/array_access_of_non_array.zig @@ -1,9 +1,9 @@ export fn f() void { - var bad : bool = undefined; + var bad: bool = undefined; bad[0] = bad[0]; } export fn g() void { - var bad : bool = undefined; + var bad: bool = undefined; _ = bad[0]; } @@ -11,5 +11,7 @@ export fn g() void { // backend=stage2 // target=native // -// :3:8: error: element access of non-indexable type 'bool' -// :7:12: error: element access of non-indexable type 'bool' +// :3:8: error: type 'bool' does not support indexing +// :3:8: note: operand must be an array, slice, tuple, or vector +// :7:12: error: type 'bool' does not support indexing +// :7:12: note: operand must be an array, slice, tuple, or vector diff --git a/test/cases/compile_errors/array_access_of_type.zig b/test/cases/compile_errors/array_access_of_type.zig index d38a13b2fa..1e66ca3776 100644 --- a/test/cases/compile_errors/array_access_of_type.zig +++ b/test/cases/compile_errors/array_access_of_type.zig @@ -7,4 +7,5 @@ export fn foo() void { // backend=stage2 // target=native // -// :2:14: error: element access of non-indexable type 'type' +// :2:14: error: type 'type' does not support indexing +// :2:14: note: operand must be an array, slice, tuple, or vector diff --git a/test/cases/compile_errors/compile_time_null_ptr_cast.zig b/test/cases/compile_errors/compile_time_null_ptr_cast.zig index d3750c8654..25805e9f35 100644 --- a/test/cases/compile_errors/compile_time_null_ptr_cast.zig +++ b/test/cases/compile_errors/compile_time_null_ptr_cast.zig @@ -8,4 +8,4 @@ comptime { // backend=llvm // target=native // -// :3:32: error: null pointer casted to type *i32 +// :3:32: error: null pointer casted to type '*i32' diff --git a/test/cases/compile_errors/for.zig b/test/cases/compile_errors/for.zig index 5bd3aa0c64..435bb68607 100644 --- a/test/cases/compile_errors/for.zig +++ b/test/cases/compile_errors/for.zig @@ -31,8 +31,8 @@ export fn d() void { // :2:5: error: non-matching for loop lengths // :2:11: note: length 10 here // :2:19: note: length 11 here -// :9:14: error: type 'bool' does not support indexing -// :9:14: note: for loop operand must be an array, slice, tuple, or vector +// :9:14: error: type 'bool' is not indexable and not a range +// :9:14: note: for loop operand must be a range, array, slice, tuple, or vector // :15:16: error: pointer capture of non pointer type '[10]u8' // :15:10: note: consider using '&' here // :22:5: error: unbounded for loop diff --git a/test/cases/compile_errors/incorrect_type_to_memset_memcpy.zig b/test/cases/compile_errors/incorrect_type_to_memset_memcpy.zig index 910ec807a8..2a4990b1ec 100644 --- a/test/cases/compile_errors/incorrect_type_to_memset_memcpy.zig +++ b/test/cases/compile_errors/incorrect_type_to_memset_memcpy.zig @@ -25,12 +25,12 @@ pub export fn non_matching_lengths() void { // target=native // // :5:5: error: unknown @memcpy length -// :5:18: note: destination type [*]u8 provides no length -// :5:24: note: source type [*]align(4) const u8 provides no length +// :5:18: note: destination type '[*]u8' provides no length +// :5:24: note: source type '[*]align(4) const u8' provides no length // :10:13: error: type 'u8' does not support indexing -// :10:13: note: for loop operand must be an array, slice, tuple, or vector +// :10:13: note: operand must be an array, slice, tuple, or vector // :15:13: error: type '*u8' does not support indexing -// :15:13: note: for loop operand must be an array, slice, tuple, or vector +// :15:13: note: operand must be an array, slice, tuple, or vector // :20:5: error: non-matching @memcpy lengths // :20:13: note: length 6 here // :20:20: note: length 5 here diff --git a/test/cases/compile_errors/indexing_non-tuple_struct.zig b/test/cases/compile_errors/indexing_non-tuple_struct.zig index 912ee689d1..1691faaae0 100644 --- a/test/cases/compile_errors/indexing_non-tuple_struct.zig +++ b/test/cases/compile_errors/indexing_non-tuple_struct.zig @@ -8,4 +8,5 @@ export fn a() void { // backend=stage2 // target=native // -// :4:6: error: element access of non-indexable type 'tmp.a.S' +// :4:6: error: type 'tmp.a.S' does not support indexing +// :4:6: note: operand must be an array, slice, tuple, or vector diff --git a/test/cases/compile_errors/indexing_single-item_pointer.zig b/test/cases/compile_errors/indexing_single-item_pointer.zig index efd063817c..41b94c8f26 100644 --- a/test/cases/compile_errors/indexing_single-item_pointer.zig +++ b/test/cases/compile_errors/indexing_single-item_pointer.zig @@ -6,4 +6,5 @@ export fn entry(ptr: *i32) i32 { // backend=stage2 // target=native // -// :2:15: error: element access of non-indexable type '*i32' +// :2:15: error: type '*i32' does not support indexing +// :2:15: note: operand must be an array, slice, tuple, or vector |
