Skip to content

-mm=own: let [a, b] = pair borrows each element, as let a = pair[0] does - #677

Merged
ASDAlexander77 merged 1 commit into
mainfrom
own-guarded-element-read
Oct 23, 2026
Merged

ASDAlexander77 merged 1 commit into
mainfrom
own-guarded-element-read

Conversation

@ASDAlexander77

Copy link
Copy Markdown
Owner

What

Under -mm=own, let [a, b] = pair now borrows each element, as let a = pair[0] already does. String elements are copied, as any string read out of an element is (spec 22).

Why

A destructuring declaration reads each element behind a test of the array's length whose other branch yields the default. The local's value therefore arrives through a merge (a block argument), and own refused it: "is merged from several branches". This cost the corpus file 00owned_locals (follow-up 14 from own-raytrace).

soleBlockMergedInto (OwnershipFacts.h) finds the one value a merge can bring a block in by, when every other way in passes ts.Default / ts.Null / ts.Undef or something that holds no block. placeReadOf uses it, so the local becomes that element read. checkPlaceRead's walk from the read already follows the branch to the local, so the borrow's end is still checked.

These are still errors (probed, and two of them pinned): reassigning the array, storing into an element, shift, returning the local, storing it into a field, and capturing it.

Tests

  • own_destructure_elements covers class elements, built strings that outlive their array, and destructuring in a loop. It runs under own (including the no-counting check) and under rc, gc and none.
  • 00owned_locals now runs under own.
  • New negatives with pinned messages: own_err_destructure_element_reassigned and own_err_destructure_element_returned.
  • Own corpus on Linux: 533 → 534 files accepted. Nothing is lost; the one gained file gives the same output as gc under MALLOC_PERTURB_.
  • Full suite: Windows 5469/5469, Linux 5448/5448.

🤖 Generated with Claude Code

…]` does

A destructuring declaration reads each element behind a test of the array's
length whose other side is the default, so the local's value arrived through a
merge, and own refused it ("merged from several branches") though the plain
read `let a = pair[0]` is an element borrow. placeReadOf now sees through a
merge whose every other way in passes a default or what holds no block
(soleBlockMergedInto): the local is that element read, and checkPlaceRead's
walk from the read already follows the branch to it, so reassigning or
shrinking the array, storing, returning or capturing the local is still an
error. A string element is copied, as any string read out of an element is.

Own corpus 533 -> 534 (00owned_locals), none lost. Tests: own_destructure_elements
under every model, 00owned_locals under own, two negatives with pinned messages.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@ASDAlexander77
ASDAlexander77 merged commit ed6f5f6 into main Oct 23, 2026
2 checks passed
@ASDAlexander77
ASDAlexander77 deleted the own-guarded-element-read branch October 23, 2026 20:27
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