| ... | ... | @@ -3401,8 +3401,8 @@ fn indexablePtrLen( |
| 3401 | 3401 | ) CompileError!Air.Inst.Ref { |
| 3402 | 3402 | const object_ty = sema.typeOf(object); |
| 3403 | 3403 | const is_pointer_to = object_ty.isSinglePointer(); |
| 3404 | | const array_ty = if (is_pointer_to) object_ty.childType() else object_ty; |
| 3405 | | try checkIndexable(sema, block, src, array_ty); |
| 3404 | const indexable_ty = if (is_pointer_to) object_ty.childType() else object_ty; |
| 3405 | try checkIndexable(sema, block, src, indexable_ty); |
| 3406 | 3406 | return sema.fieldVal(block, src, object, "len", src); |
| 3407 | 3407 | } |
| 3408 | 3408 | |
| ... | ... | @@ -3413,7 +3413,7 @@ fn indexablePtrLenOrNone( |
| 3413 | 3413 | object: Air.Inst.Ref, |
| 3414 | 3414 | ) CompileError!Air.Inst.Ref { |
| 3415 | 3415 | const object_ty = sema.typeOf(object); |
| 3416 | | const array_ty = t: { |
| 3416 | const indexable_ty = t: { |
| 3417 | 3417 | const ptr_size = object_ty.ptrSizeOrNull() orelse break :t object_ty; |
| 3418 | 3418 | break :t switch (ptr_size) { |
| 3419 | 3419 | .Many => return .none, |
| ... | ... | @@ -3421,7 +3421,7 @@ fn indexablePtrLenOrNone( |
| 3421 | 3421 | else => object_ty, |
| 3422 | 3422 | }; |
| 3423 | 3423 | }; |
| 3424 | | try checkIndexable(sema, block, src, array_ty); |
| 3424 | try checkIndexable(sema, block, src, indexable_ty); |
| 3425 | 3425 | return sema.fieldVal(block, src, object, "len", src); |
| 3426 | 3426 | } |
| 3427 | 3427 | |
| ... | ... | @@ -3991,7 +3991,16 @@ fn zirForLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. |
| 3991 | 3991 | .input_index = i, |
| 3992 | 3992 | } }; |
| 3993 | 3993 | const arg_len_uncoerced = if (is_int) object else l: { |
| 3994 | | try checkIndexable(sema, block, arg_src, object_ty); |
| 3994 | if (!object_ty.isIndexable()) { |
| 3995 | // Instead of using checkIndexable we customize this error. |
| 3996 | const msg = msg: { |
| 3997 | const msg = try sema.errMsg(block, arg_src, "type '{}' is not indexable and not a range", .{object_ty.fmt(sema.mod)}); |
| 3998 | errdefer msg.destroy(sema.gpa); |
| 3999 | try sema.errNote(block, arg_src, msg, "for loop operand must be a range, array, slice, tuple, or vector", .{}); |
| 4000 | break :msg msg; |
| 4001 | }; |
| 4002 | return sema.failWithOwnedErrorMsg(msg); |
| 4003 | } |
| 3995 | 4004 | if (!object_ty.indexableHasLen()) continue; |
| 3996 | 4005 | |
| 3997 | 4006 | 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 |
| 19910 | 19919 | return sema.failWithUseOfUndef(block, operand_src); |
| 19911 | 19920 | } |
| 19912 | 19921 | if (!dest_ty.ptrAllowsZero() and operand_val.isNull()) { |
| 19913 | | return sema.fail(block, operand_src, "null pointer casted to type {}", .{dest_ty.fmt(sema.mod)}); |
| 19922 | return sema.fail(block, operand_src, "null pointer casted to type '{}'", .{dest_ty.fmt(sema.mod)}); |
| 19914 | 19923 | } |
| 19915 | 19924 | if (dest_ty.zigTypeTag() == .Optional and sema.typeOf(ptr).zigTypeTag() != .Optional) { |
| 19916 | 19925 | 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 |
| 22013 | 22022 | const msg = msg: { |
| 22014 | 22023 | const msg = try sema.errMsg(block, src, "unknown @memcpy length", .{}); |
| 22015 | 22024 | errdefer msg.destroy(sema.gpa); |
| 22016 | | try sema.errNote(block, dest_src, msg, "destination type {} provides no length", .{ |
| 22025 | try sema.errNote(block, dest_src, msg, "destination type '{}' provides no length", .{ |
| 22017 | 22026 | sema.typeOf(dest_ptr).fmt(sema.mod), |
| 22018 | 22027 | }); |
| 22019 | | try sema.errNote(block, src_src, msg, "source type {} provides no length", .{ |
| 22028 | try sema.errNote(block, src_src, msg, "source type '{}' provides no length", .{ |
| 22020 | 22029 | sema.typeOf(src_ptr).fmt(sema.mod), |
| 22021 | 22030 | }); |
| 22022 | 22031 | break :msg msg; |
| ... | ... | @@ -22746,7 +22755,7 @@ fn resolveExternOptions( |
| 22746 | 22755 | const payload = library_name_val.castTag(.opt_payload).?.data; |
| 22747 | 22756 | const library_name = try payload.toAllocatedBytes(Type.initTag(.const_slice_u8), sema.arena, mod); |
| 22748 | 22757 | if (library_name.len == 0) { |
| 22749 | | return sema.fail(block, library_src, "library name name cannot be empty", .{}); |
| 22758 | return sema.fail(block, library_src, "library name cannot be empty", .{}); |
| 22750 | 22759 | } |
| 22751 | 22760 | break :blk try sema.handleExternLibName(block, library_src, library_name); |
| 22752 | 22761 | } else null; |
| ... | ... | @@ -24767,9 +24776,7 @@ fn elemPtr( |
| 24767 | 24776 | .Pointer => indexable_ptr_ty.elemType(), |
| 24768 | 24777 | else => return sema.fail(block, indexable_ptr_src, "expected pointer, found '{}'", .{indexable_ptr_ty.fmt(sema.mod)}), |
| 24769 | 24778 | }; |
| 24770 | | if (!indexable_ty.isIndexable()) { |
| 24771 | | return sema.fail(block, src, "element access of non-indexable type '{}'", .{indexable_ty.fmt(sema.mod)}); |
| 24772 | | } |
| 24779 | try checkIndexable(sema, block, src, indexable_ty); |
| 24773 | 24780 | |
| 24774 | 24781 | switch (indexable_ty.zigTypeTag()) { |
| 24775 | 24782 | .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( |
| 24801 | 24808 | const indexable_ty = sema.typeOf(indexable); |
| 24802 | 24809 | const target = sema.mod.getTarget(); |
| 24803 | 24810 | |
| 24804 | | if (!indexable_ty.isIndexable()) { |
| 24805 | | return sema.fail(block, src, "element access of non-indexable type '{}'", .{indexable_ty.fmt(sema.mod)}); |
| 24806 | | } |
| 24811 | try checkIndexable(sema, block, src, indexable_ty); |
| 24807 | 24812 | |
| 24808 | 24813 | switch (indexable_ty.ptrSize()) { |
| 24809 | 24814 | .Slice => return sema.elemPtrSlice(block, src, indexable_src, indexable, elem_index_src, elem_index, oob_safety), |
| ... | ... | @@ -24824,7 +24829,7 @@ fn elemPtrOneLayerOnly( |
| 24824 | 24829 | return block.addPtrElemPtr(indexable, elem_index, result_ty); |
| 24825 | 24830 | }, |
| 24826 | 24831 | .One => { |
| 24827 | | assert(indexable_ty.childType().zigTypeTag() == .Array); // Guaranteed by isIndexable |
| 24832 | assert(indexable_ty.childType().zigTypeTag() == .Array); // Guaranteed by checkIndexable |
| 24828 | 24833 | return sema.elemPtrArray(block, src, indexable_src, indexable, elem_index_src, elem_index, init, oob_safety); |
| 24829 | 24834 | }, |
| 24830 | 24835 | } |
| ... | ... | @@ -24843,9 +24848,7 @@ fn elemVal( |
| 24843 | 24848 | const indexable_ty = sema.typeOf(indexable); |
| 24844 | 24849 | const target = sema.mod.getTarget(); |
| 24845 | 24850 | |
| 24846 | | if (!indexable_ty.isIndexable()) { |
| 24847 | | return sema.fail(block, src, "element access of non-indexable type '{}'", .{indexable_ty.fmt(sema.mod)}); |
| 24848 | | } |
| 24851 | try checkIndexable(sema, block, src, indexable_ty); |
| 24849 | 24852 | |
| 24850 | 24853 | // TODO in case of a vector of pointers, we need to detect whether the element |
| 24851 | 24854 | // index is a scalar or vector instead of unconditionally casting to usize. |
| ... | ... | @@ -24873,7 +24876,7 @@ fn elemVal( |
| 24873 | 24876 | return block.addBinOp(.ptr_elem_val, indexable, elem_index); |
| 24874 | 24877 | }, |
| 24875 | 24878 | .One => { |
| 24876 | | assert(indexable_ty.childType().zigTypeTag() == .Array); // Guaranteed by isIndexable |
| 24879 | assert(indexable_ty.childType().zigTypeTag() == .Array); // Guaranteed by checkIndexable |
| 24877 | 24880 | const elem_ptr = try sema.elemPtr(block, indexable_src, indexable, elem_index, elem_index_src, false, oob_safety); |
| 24878 | 24881 | return sema.analyzeLoad(block, indexable_src, elem_ptr, elem_index_src); |
| 24879 | 24882 | }, |
| ... | ... | @@ -30997,23 +31000,12 @@ fn checkBackingIntType(sema: *Sema, block: *Block, src: LazySrcLoc, backing_int_ |
| 30997 | 31000 | } |
| 30998 | 31001 | } |
| 30999 | 31002 | |
| 31000 | | fn checkIndexable(sema: *Sema, block: *Block, src: LazySrcLoc, array_ty: Type) !void { |
| 31001 | | if (!array_ty.isIndexable()) { |
| 31003 | fn checkIndexable(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) !void { |
| 31004 | if (!ty.isIndexable()) { |
| 31002 | 31005 | const msg = msg: { |
| 31003 | | const msg = try sema.errMsg( |
| 31004 | | block, |
| 31005 | | src, |
| 31006 | | "type '{}' does not support indexing", |
| 31007 | | .{array_ty.fmt(sema.mod)}, |
| 31008 | | ); |
| 31006 | const msg = try sema.errMsg(block, src, "type '{}' does not support indexing", .{ty.fmt(sema.mod)}); |
| 31009 | 31007 | errdefer msg.destroy(sema.gpa); |
| 31010 | | try sema.errNote( |
| 31011 | | block, |
| 31012 | | src, |
| 31013 | | msg, |
| 31014 | | "for loop operand must be an array, slice, tuple, or vector", |
| 31015 | | .{}, |
| 31016 | | ); |
| 31008 | try sema.errNote(block, src, msg, "operand must be an array, slice, tuple, or vector", .{}); |
| 31017 | 31009 | break :msg msg; |
| 31018 | 31010 | }; |
| 31019 | 31011 | return sema.failWithOwnedErrorMsg(msg); |