Repository navigation
-mm=own: tuple field reads, caught values, defaulted parameters, literals into arrays, --di locals - #704
Merged
Conversation
…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
…rals into arrays, --di locals Five borrows or moves that own refused although they were safe: nothing could free what was read, or nothing else held what was moved. - A field read out of a borrowed tuple value borrows what the tuple borrows. console.log of the T | undefined that find returns reads each field with ts.ExtractProperty. A number field keeps nothing (spec 44). - A caught value belongs to the exception until the catch ends. A throw takes what it throws, since own refuses to throw a borrow. So a call frees what is read out of a catch variable only when it is given something derived from it (spec 44). - A parameter with a default (constructor(private d: T[] = [])) is kept as any parameter is. Its slot merges the argument with the default made here, and it counts as the parameter's slot. The argument left out is a ts.Undef of the optional type, which holds no block (spec 45). - An object literal that owns what it holds moves into an array literal's element or a pushed item, as it already moved into a local, the result or a box (spec 46). - Under --di, a borrowing local's ts.DebugVariable keeps nothing (spec 47). DefaultLib now compiles these under own: array_find2/3, catch_library_error, new Array<number>(), regexp_parse_examples, and concat and owning_copies in the debug pass. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
# Conflicts: # tslang/docs/superpowers/specs/2026-09-24-own-memory-model-design.md # tslang/test/tester/CMakeLists.txt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Five places where
-mm=ownrefused a borrow or a move that was safe. Each one blocked a DefaultLib test. Spec sections 44–47, and the user doc's limits section is updated.array_find2,array_find3catch_library_errornew Array<number>()(array_every)regexp_parse_examples--di, the debugger's record of a local keeps nothingarray_concat,owning_copiesDetails
Tuple field reads (§44).
console.logof theT | undefinedthatfindreturns reads each field withts.ExtractProperty.walkBorrowedused to take that read for a keep. Now a number field keeps nothing, and a field that holds a block is walked on as part of the same borrow, so storing it is still refused.Caught values (§44).
ts.SaveCatchVarfills a catch variable and nothing else assigns it. A throw takes what it throws, and own refuses to throw an element, a field or a reassigned global. So nothing but the exception holds the caught value: a call can free what is read out of it only when the call is given something derived from it. Before,<RangeError>efollowed by a virtualinstanceofcall was refused.Defaulted parameters (§45). MLIRGen builds a parameter with a default as a merge of
Value(p)and the default.isParameterSlotandparameterSlotsOfnow accept that local as the parameter's slot, so the §33 rules for kept parameters apply. Callers move the argument in, and a path that does not keep it releases what the slot holds: the argument given or the default.isLiteraltreats ats.Undefof an optional type, the argument left out, as holding no block.Object literals in arrays (§46).
recordRetainOfnow also lets a literal's read go into ats.CreateArrayelement or ats.ArrayPushitem. Each fresh field value's release is erased, and the array's release frees them.--dilocals (§47).collectBorrowerUsesnow skipsts.DebugVariable.Tests
own_optional_record_readown_param_default_keptown_literal_into_arrayown_for_of_nested_di: built with--diand run under the JIT.own_caught_value_call: compile-only.own_err_optional_record_field_kept.main: 1548/1548.Still failing under own
string_matchAll,string_match_lastIndex: keeping a value a generator yields ([...s.matchAll(re)], or a push insidefor...of) needs a new way to move a value out ofnext()'s result.array_reduceRight: the accumulator starts as an element borrow and later becomes owned. Separately,a.concat(b)movesbinto the rest array.The dependent DefaultLib PR follows.
🤖 Generated with Claude Code