authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2026-03-02 15:45:35+00:00
committergravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2026-03-10 10:26:14+00:00
log9c9a5e722b84d12de34d16f53355adbe1f5e11d3
tree60aa2a9e2056ff7ed8bb65794510c380a03416dc
parent6d997ebe47d91641e70971bf3c227df6cbae041a
signaturelock-open Commit is signed but in an unrecognized format.

Sema: match master's weird pointer difference semantics for now

...except for master's handling of pointers to vectors, because that was unambiguously a bug.

1 files changed, 13 insertions(+), 3 deletions(-)

src/Sema.zig+13-3
......@@ -15249,15 +15249,25 @@ fn analyzeArithmetic(
1524915249 return sema.failWithInvalidPtrArithmetic(block, src, "pointer-pointer", "subtraction");
1525015250 }
1525115251
15252 // MLUGG TODO: these semantics are insane and matching them is causing my soul to fragment into a thousand pieces
15252 // TODO: these semantics are really weird. Pointer subtraction works in increments
15253 // of the pointer child for indexable pointers (excluding pointers to vectors),
15254 // which makes sense, but we also allow it for arbitrary single-item pointers, which
15255 // leads to the weird result that subtraction of '*T' works completely differently
15256 // depending on whether 'T' is an array. That seems dangerous and confusing, and
15257 // requires the odd logic below. This behavior originally came from a now-removed
15258 // function `Type.elemType2`, which was removed precisely *because* the thing it did
15259 // wasn't really well-defined; for that reason, these semantics were probably
15260 // largely accidental to begin with. We should change the langauge to avoid this
15261 // confusing behavior. For instance, perhaps pointer subtraction should only work on
15262 // indexable pointers.
1525315263 const lhs_elem_ty = ty: {
1525415264 const ptr_elem_ty = lhs_ty.childType(zcu);
15255 if (lhs_ty.ptrSize(zcu) == .one and ptr_elem_ty.isArrayOrVector(zcu)) break :ty ptr_elem_ty.childType(zcu);
15265 if (lhs_ty.ptrSize(zcu) == .one and ptr_elem_ty.zigTypeTag(zcu) == .array) break :ty ptr_elem_ty.childType(zcu);
1525615266 break :ty ptr_elem_ty;
1525715267 };
1525815268 const rhs_elem_ty = ty: {
1525915269 const ptr_elem_ty = rhs_ty.childType(zcu);
15260 if (rhs_ty.ptrSize(zcu) == .one and ptr_elem_ty.isArrayOrVector(zcu)) break :ty ptr_elem_ty.childType(zcu);
15270 if (rhs_ty.ptrSize(zcu) == .one and ptr_elem_ty.zigTypeTag(zcu) == .array) break :ty ptr_elem_ty.childType(zcu);
1526115271 break :ty ptr_elem_ty;
1526215272 };
1526315273 if (lhs_elem_ty.toIntern() != rhs_elem_ty.toIntern()) {