| ... | @@ -17045,17 +17045,9 @@ fn elemVal( | ... | @@ -17045,17 +17045,9 @@ fn elemVal( |
| 17045 | const indexable_val = maybe_indexable_val orelse break :rs indexable_src; | 17045 | const indexable_val = maybe_indexable_val orelse break :rs indexable_src; |
| 17046 | const index_val = maybe_index_val orelse break :rs elem_index_src; | 17046 | const index_val = maybe_index_val orelse break :rs elem_index_src; |
| 17047 | const index = @intCast(usize, index_val.toUnsignedInt(target)); | 17047 | const index = @intCast(usize, index_val.toUnsignedInt(target)); |
| 17048 | const elem_ty = indexable_ty.elemType2(); | 17048 | const elem_ptr_val = try indexable_val.elemPtr(indexable_ty, sema.arena, index, target); |
| 17049 | | | |
| 17050 | var payload: Value.Payload.ElemPtr = .{ .data = .{ | | |
| 17051 | .array_ptr = indexable_val, | | |
| 17052 | .elem_ty = elem_ty, | | |
| 17053 | .index = index, | | |
| 17054 | } }; | | |
| 17055 | const elem_ptr_val = Value.initPayload(&payload.base); | | |
| 17056 | | | |
| 17057 | if (try sema.pointerDeref(block, indexable_src, elem_ptr_val, indexable_ty)) |elem_val| { | 17049 | if (try sema.pointerDeref(block, indexable_src, elem_ptr_val, indexable_ty)) |elem_val| { |
| 17058 | return sema.addConstant(elem_ty, elem_val); | 17050 | return sema.addConstant(indexable_ty.elemType2(), elem_val); |
| 17059 | } | 17051 | } |
| 17060 | break :rs indexable_src; | 17052 | break :rs indexable_src; |
| 17061 | }; | 17053 | }; |
| ... | @@ -17310,12 +17302,7 @@ fn elemValSlice( | ... | @@ -17310,12 +17302,7 @@ fn elemValSlice( |
| 17310 | const sentinel_label: []const u8 = if (slice_sent) " +1 (sentinel)" else ""; | 17302 | const sentinel_label: []const u8 = if (slice_sent) " +1 (sentinel)" else ""; |
| 17311 | return sema.fail(block, elem_index_src, "index {d} outside slice of length {d}{s}", .{ index, slice_len, sentinel_label }); | 17303 | return sema.fail(block, elem_index_src, "index {d} outside slice of length {d}{s}", .{ index, slice_len, sentinel_label }); |
| 17312 | } | 17304 | } |
| 17313 | var elem_ptr_pl: Value.Payload.ElemPtr = .{ .data = .{ | 17305 | const elem_ptr_val = try slice_val.elemPtr(slice_ty, sema.arena, index, target); |
| 17314 | .array_ptr = slice_val.slicePtr(), | | |
| 17315 | .elem_ty = elem_ty, | | |
| 17316 | .index = index, | | |
| 17317 | } }; | | |
| 17318 | const elem_ptr_val = Value.initPayload(&elem_ptr_pl.base); | | |
| 17319 | if (try sema.pointerDeref(block, slice_src, elem_ptr_val, slice_ty)) |elem_val| { | 17306 | if (try sema.pointerDeref(block, slice_src, elem_ptr_val, slice_ty)) |elem_val| { |
| 17320 | return sema.addConstant(elem_ty, elem_val); | 17307 | return sema.addConstant(elem_ty, elem_val); |
| 17321 | } | 17308 | } |
| ... | @@ -18765,6 +18752,11 @@ fn beginComptimePtrLoad( | ... | @@ -18765,6 +18752,11 @@ fn beginComptimePtrLoad( |
| 18765 | const elem_ty = elem_ptr.elem_ty; | 18752 | const elem_ty = elem_ptr.elem_ty; |
| 18766 | var deref = try beginComptimePtrLoad(sema, block, src, elem_ptr.array_ptr, null); | 18753 | var deref = try beginComptimePtrLoad(sema, block, src, elem_ptr.array_ptr, null); |
| 18767 | | 18754 | |
| | 18755 | // This code assumes that elem_ptrs have been "flattened" in order for direct dereference |
| | 18756 | // to succeed, meaning that elem ptrs of the same elem_ty are coalesced. Here we check that |
| | 18757 | // our parent is not an elem_ptr with the same elem_ty, since that would be "unflattened" |
| | 18758 | if (elem_ptr.array_ptr.castTag(.elem_ptr)) |parent_elem_ptr| assert(!(parent_elem_ptr.data.elem_ty.eql(elem_ty, target))); |
| | 18759 | |
| 18768 | if (elem_ptr.index != 0) { | 18760 | if (elem_ptr.index != 0) { |
| 18769 | if (elem_ty.hasWellDefinedLayout()) { | 18761 | if (elem_ty.hasWellDefinedLayout()) { |
| 18770 | if (deref.parent) |*parent| { | 18762 | if (deref.parent) |*parent| { |
| ... | @@ -18793,13 +18785,6 @@ fn beginComptimePtrLoad( | ... | @@ -18793,13 +18785,6 @@ fn beginComptimePtrLoad( |
| 18793 | | 18785 | |
| 18794 | var array_tv = deref.pointee.?; | 18786 | var array_tv = deref.pointee.?; |
| 18795 | const check_len = array_tv.ty.arrayLenIncludingSentinel(); | 18787 | const check_len = array_tv.ty.arrayLenIncludingSentinel(); |
| 18796 | if (elem_ptr.index >= check_len) { | | |
| 18797 | // TODO have the deref include the decl so we can say "declared here" | | |
| 18798 | return sema.fail(block, src, "comptime load of index {d} out of bounds of array length {d}", .{ | | |
| 18799 | elem_ptr.index, check_len, | | |
| 18800 | }); | | |
| 18801 | } | | |
| 18802 | | | |
| 18803 | if (maybe_array_ty) |load_ty| { | 18788 | if (maybe_array_ty) |load_ty| { |
| 18804 | // It's possible that we're loading a [N]T, in which case we'd like to slice | 18789 | // It's possible that we're loading a [N]T, in which case we'd like to slice |
| 18805 | // the pointee array directly from our parent array. | 18790 | // the pointee array directly from our parent array. |
| ... | @@ -18813,10 +18798,10 @@ fn beginComptimePtrLoad( | ... | @@ -18813,10 +18798,10 @@ fn beginComptimePtrLoad( |
| 18813 | } | 18798 | } |
| 18814 | } | 18799 | } |
| 18815 | | 18800 | |
| 18816 | deref.pointee = .{ | 18801 | deref.pointee = if (elem_ptr.index < check_len) TypedValue{ |
| 18817 | .ty = elem_ty, | 18802 | .ty = elem_ty, |
| 18818 | .val = try array_tv.val.elemValue(sema.arena, elem_ptr.index), | 18803 | .val = try array_tv.val.elemValue(sema.arena, elem_ptr.index), |
| 18819 | }; | 18804 | } else null; |
| 18820 | break :blk deref; | 18805 | break :blk deref; |
| 18821 | }, | 18806 | }, |
| 18822 | | 18807 | |