Skip to content

-mm=own: a method call on another module's @final class keeps its borrows - #681

Merged
ASDAlexander77 merged 1 commit into
mainfrom
own-final-imported-method
Oct 23, 2026
Merged

ASDAlexander77 merged 1 commit into
mainfrom
own-final-imported-method

Conversation

@ASDAlexander77

Copy link
Copy Markdown
Owner

Problem

Under -mm=own, a borrowing record (§32) could not be read after a method call on an object of another module's class, even when the library lists that method among its __own_no_drops. The call goes through the vtable, so resolveValue resolved it to the method's family. The importer cannot see the imported members of that family, so the call was unknown and might drop anything.

Fix

A @final class has no subclass, so its vtable slot holds the method the call names.

  • MLIRGen marks the ts.ThisVirtualSymbolRef of a @final receiver that is not called directly (the class is defined in another module) with __final_receiver (FINAL_RECEIVER_ATTR_NAME).
  • resolveValue resolves such a reference as a call to the function it names, not to its family, so addImported, and with it the library's __own_no_drops, applies.

A method of a class that is not @final may be overridden where the importer cannot see the override, so a call of one still ends the record's borrows.

Not covered: accessors on an imported @final class (ThisIndirectAccessorOp).

Tests

  • export_own_record.ts: Maker.weigh (on the @final class Maker) and a non-final Open.look. Both destroy nothing.
  • import_own_record.ts: both records are read across m.weigh(...). It runs under gc, rc and own, AOT and JIT, and own-shared-record.cmake still counts two box releases.
  • import_own_record_open_method.ts (new negative): a read after o.look(a) is still refused.
  • Full suites: Windows 5521/5521, Linux 5499/5499.

Spec notes: own memory model §15.7, final classes ("Amended 2026-10-24").

🤖 Generated with Claude Code

…rows

A call on an object of a @Final class another module defines still goes
through the vtable, so the signature pass resolved it to the method's family,
whose imported members it cannot see, and the call might drop anything: a
borrowing record could not be read across it, though the library lists the
method in __own_no_drops. No class can extend a @Final one, so the slot holds
the method the call names. MLIRGen now marks such a ts.ThisVirtualSymbolRef
__final_receiver, and resolveValue resolves it as a call to that function,
so addImported applies.

A method of a class that is not @Final may be overridden where the importer
cannot see, so a call of one still ends the record's borrows
(import_own_record_open_method.ts).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@ASDAlexander77
ASDAlexander77 merged commit 805448c into main Oct 23, 2026
2 checks passed
@ASDAlexander77
ASDAlexander77 deleted the own-final-imported-method branch October 23, 2026 23:42
ASDAlexander77 added a commit that referenced this pull request Oct 24, 2026
…ws too (#682)

#681 resolved a method call on an object of another module's @Final class as
a call to the method it names, so the library's __own_no_drops applied. An
accessor goes through the vtable by a ts.VirtualSymbolRef instead, which still
resolved to its family, so reading a getter or assigning a setter ended every
borrow it could reach: a record could not be read across `m.weight`. MLIRGen
now marks an accessor's ts.VirtualSymbolRef __final_receiver as it marks a
method's ts.ThisVirtualSymbolRef, and resolveValue reads it the same way.

An accessor the library does not list still drops
(import_own_record_final_drops.ts: a setter that replaces the borrowed node).

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
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