Skip to content

type closure-call results; make lambda returns transfer#275

Merged
kacy merged 1 commit into
mainfrom
generic-compare
Jul 8, 2026
Merged

type closure-call results; make lambda returns transfer#275
kacy merged 1 commit into
mainfrom
generic-compare

Conversation

@kacy

@kacy kacy commented Jul 8, 2026

Copy link
Copy Markdown
Owner

summary

two ownership-model holes, closed together because fixing the first exposed the second:

  1. generic bodies compared strings by pointer — the comparison dispatch reads checked types, which are suppressed in generic bodies, so key(a) < key(b) with fn(T) -> String ordered by allocation address. fix: closure-typed params record their declared return kinds (unwrapping the returns AST node), calls through them infer it, and unannotated binds carry it. sort_by_key drops its strcmp sidestep for the natural <.
  2. lambda returns never honored transfer semantics — a lambda returning a borrowed field handed out an uncounted reference, balanced only while closure-call results were untracked. once the typing fix landed, parq's golden check caught a freed job name within minutes. lambda expression returns now retain borrowed strings on the way out, like named function returns.

what was tested

new regression pins the generic comparison (bound + inline); parq's golden diff doubles as the use-after-free regression; leak scan clean on parq; full suite green including all four golden checks; fixed point byte-identical; seed refreshed.

two ownership-model holes, closed together because fixing the first
exposed the second.

ordered string comparison inside generic bodies compared pointers:
the comparison dispatch reads checked operand types, and generic
bodies check with type parameters suppressed, so key(a) < key(b) with
a fn(T) -> String key ordered by allocation address. closure-typed
parameters now record their declared return kinds (the return type
hides inside a "returns" wrapper node), calls through them infer that
kind, and unannotated binds from such calls carry it — so the
comparison sees strings and calls the runtime. sort_by_key drops its
strcmp sidestep for the natural comparison it was written with.

the new typing exposed the second hole: lambda returns never honored
transfer semantics. a lambda returning a borrowed field handed out an
uncounted reference, balanced only by the accident that closure-call
results were untracked — once tracked, the caller's release freed a
job name out from under parq, and the golden check caught the empty
string within minutes. lambda expression returns now retain borrowed
strings on the way out, exactly as named function returns do.

a regression pins the generic comparison in both bound and inline
form; parq's golden diff doubles as the use-after-free regression.
@kacy kacy merged commit 6fee17b into main Jul 8, 2026
2 checks passed
@kacy kacy deleted the generic-compare branch July 8, 2026 00:33
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