Skip to content

-mm=own: sort and reverse over class instances (swap op, forwarded callbacks) - #703

Merged
ASDAlexander77 merged 5 commits into
mainfrom
own-array-element-moves
Oct 27, 2026
Merged

ASDAlexander77 merged 5 commits into
mainfrom
own-array-element-moves

Conversation

@ASDAlexander77

Copy link
Copy Markdown
Owner

sort and reverse over arrays of class instances now compile and run under -mm=own (spec sections 42 and 43).

Swaps that move nothing (spec 42)

A swap through a local, let t = a[i]; a[i] = a[j]; a[j] = t, gives the object in t a second owner. Under own that is an error.

  • An expression statement [p, q] = [q, p] that names the same two elements or fields of one type is now a new op, ts.Swap.
  • ts.Swap emits no retain, release or drop in any memory model. Its LLVM lowering loads both values before storing either.
  • The inference treats a swap as a drop of any borrow read out of either place. The signature pass treats it as an overwrite of both places for callers.
  • Anything else (locals, accessors, an assignment whose value is used) compiles as before.

A callback passed on through a parameter keeps its facts (spec 43)

DefaultLib sort passes its optional comparator on to a helper. A callback passed on through a parameter used to have no facts under own, so compare(a[i], a[j]) was a use of the two elements after a call that may release them.

  • Callback families now take the functions passed for the caller's own parameter.
  • A family passed on stays closed only while the families on both ends are closed.

Tests

  • own_swap_elements and own_callback_forwarded run under own, rc, gc and none.
  • Negatives: own_err_swap_borrow_used_after, own_err_swap_call_borrow_used_after, own_err_callback_forwarded_drops and own_err_callback_forwarded_keeps.
  • Full ctest -C Release passes locally.
  • Leak check (scripts/measure_memory_model.ps1): own and rc peak at 4.7 MB at 1k, 100k and 400k iterations.

The DefaultLib PR that uses this goes with it.

🤖 Generated with Claude Code

ASDAlexander77 and others added 5 commits October 27, 2026 18:04
…nto a place

A function that returns `this` has a result that borrows `this`, and spec 22.4 kept every string
read out of it from being copied - so `this[t] = this[s]` (copyWithin) and a swap's `let v = this[i]`
(reverse) were "borrows an element". The fact is about what is returned: `copyForRetain` now copies
such a read stored into an element or a field, and starts a `let` from a copy when the local cannot
be returned (`mayBeReturned`). A read returned, directly or through a local, stays the borrow.
Spec section 41.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A swap through a local, `let v = a[i]; a[i] = a[j]; a[j] = v`, gives an object element a second
owner, so `sort` and `reverse` over class instances did not compile under own. An expression
statement `[p, q] = [q, p]` whose two sides name the same two elements or fields of one type is
now a `ts.Swap` of the two places: every value keeps one place, so it is emitted with no retain,
release or drop in any model, and its lowering loads both before it stores either.

The inference treats a swap as a drop of a borrow read out of either place (it is the other
place's now, perhaps under another root), and the signature pass as an overwrite of both places
for the callers. Spec section 42; docs limits bullet updated.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…backs

`reverse` over class instances works with the exchange (spec 42); `sort` does not yet, because it
gives its optional comparison on to a helper, and a callback given on through a parameter has no
callback facts. The limits bullet and spec section 42 say so.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A callback parameter (a function value, or an optional one) that is only called, tested for being
given, unwrapped or passed to one call is in a family whose members are the functions passed for
it - including those passed for the caller's own parameter it is given from. A family given on is
closed only while the families it is given from and to are. A call of an optional callback once
tested resolves through its family too. DefaultLib `sort` over class instances with a comparison
compiles under own (spec 43).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
# Conflicts:
#	docs/own-memory-model.md
#	tslang/docs/superpowers/specs/2026-09-24-own-memory-model-design.md
#	tslang/test/tester/CMakeLists.txt
@ASDAlexander77
ASDAlexander77 merged commit a172477 into main Oct 27, 2026
2 checks passed
@ASDAlexander77
ASDAlexander77 deleted the own-array-element-moves branch October 27, 2026 21:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant