- emit_return's place test matched only bare Ident/Field/Index, so
`return "${p.content}"` (p a loop borrow) returned the part's own
string; the caller's eventual drop freed it under the container —
arena corruption surfacing two requests later (multipart slice)
- the return test now sees through Interp exactly as copy_place_text
does (is_borrowed_value_t, container reads excluded); bare
Ident/Field/Index behavior at return unchanged
- interp-borrowed-field fixture grows the return flavor (fn first),
50 iterations exact
- gates: oop-e2e 89/0 (ASan stage), woc-test green
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- copy_place_text matched only bare Ident/Field/Index, so a Text-typed
single-segment interpolation ("${r.method}", r a loop borrow) passed
the place's own register through a binding/assignment boundary — the
local aliased the row's field and its overwrite freed it
- release-build crash; invisible to ASan (in-arena free, no redzones)
- now asks is_borrowed_value_t && not is_container_read — exactly
drop_fresh_text's place test; Int segments (fresh int_to_text) and
container reads (already copies) stay uncopied as before
- pinned by tests/corpus/run/interp-borrowed-field (crashed both
runtimes before the fix, 50 iterations now exact)
- gates: woc-test 540/0, oop-e2e 89/0 (ASan stage included)
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>