merge: reconcile upstream through e8ec7fd8 (C++ member-chain calls, test temp-dir cleanup)

Merged
BO
1d ago
+494-42

Brings fork/consolidated up to upstream main e8ec7fd8. Upstream's two C++ member-chain fixes need no resolver change here: the Rust resolver already links thread->rand.Next() to the member's class and gives no edge for options.cf_paths.emplace_back(…) on a std::vector. This PR adds upstream's tests for that behavior and its test temp-dir cleanup.

The merge commit keeps upstream's parent, so land it as a merge commit.

What was ported

  • #2622 test: stop test runs leaving temp dirs behind: merged as written. vitest runs upstream's home-sandbox teardown after the fork's per-run temp directory setup.
  • #2624 test: wait for what holds an MCP test's dir before removing it: merged as written. mcp-initialize's teardown uses upstream's removeWhenReleased in place of the fork's rmTempDir.
  • #2626 fix(cpp): library-type member chains: the behavior was already native. __tests__/cpp-member-chain-outside-calls.test.ts (6 tests) passes with no kernel change.
  • #2627 fix(cpp): project-class member chains: the behavior was already native (cpp_complex_call → cpp_expression_owner / cpp_field_types in cpp_receivers.rs, which read the member from the class node C++ lookup found). __tests__/cpp-member-chain-project-calls.test.ts (6 tests) passes with no kernel change.

src/resolution/name-matcher.ts stays deleted. The CHANGELOG keeps the fork's entries and takes upstream's new wording of its two C++ member-call entries. The rebuild script would have restored four entries earlier reconciles removed on purpose.

Verification

  • Kernel rebuilt from the merged tree before testing. All 12 new tests pass on it, and also on an older fork kernel from before #511. A sample of #511's own tests fails on that older kernel (4 failures), which confirms the override reached the tests.
  • Golden dumps re-run with UPDATE_GOLDEN=1: 8/8, no .dump changes.
  • eval:precision: jq has 7,784 edges and no cases. json has 28,803 edges, 11/11 absent and 7/7 present cases held. The kernel sources are identical to the base commit, so these are the before and after figures.
  • leveldb (bb74ef7), indexed with this build. 15 sampled linked member-chain calls were read by hand and all are correct, e.g. thread->rand.Uniform → Random::Uniform and t.meta.smallest.DecodeFrom → InternalKey::DecodeFrom. The kernel is unchanged, so the before and after graphs are the same build: 0 edges added, retargeted or removed.
  • Full suite: 744 files, 9,256 passed, 40 skipped; no Native stack trace or Worker exited unexpectedly in stderr.
  • npx tsc, npm run check:agent-docs and cargo clippy --release --lib -- -D warnings pass.

README rows checked: the upstream merge point (updated to e8ec7fd8) and the C++ rows under the fork's differences (the data-member line still holds: member chains take the declared type, as upstream's now do). No numbers moved.

Not covered

On leveldb, member-chain calls of these shapes stay unlinked in the fork. Upstream's kit A/B reports 42 added and 30 retargeted calls in leveldb, so upstream likely links some of them. I have not run upstream's build to confirm which.

  • A member of a struct defined out of line as a nested class, like struct DBImpl::CompactionState { Compaction* const compaction; } with compact->compaction->level(): about 60 candidate sites (a few are correctly unlinked standard-library calls) in db_impl.cc, table_builder.cc and table.cc.
  • A member of a global-namespace struct whose type comes in through using ns::WriteBatch;, like b->rep.Clear(): about 25 sites in db/c.cc.
  • A local built with constructor-call syntax, like SharedState shared(n); shared.mu.Lock(). Tree-sitter reads this as a function declaration. A one-hop shared.Go() and the brace form both link.
  • this->mu_->Lock() inside a class written with an attribute macro (class SCOPED_LOCKABLE MutexLock).

These are left for a follow-up fix.


Summary by cubic

Reconciles fork/consolidated with upstream main through e8ec7fd8. The two C++ member-chain fixes need no resolver change — the Rust kernel already resolves thread->rand.Next() to the member's class and gives no edge for options.cf_paths.emplace_back(…) on a std::vector — so this brings in upstream's tests for that behavior and ports its test temp-dir cleanup. Land as a merge commit.

Ported from upstream

  • Home sandboxes are removed at the end of a run even when a suite skips every test, and mcp-initialize's teardown waits for a held dir before removing it.
  • The 12 new C++ member-chain tests pass unchanged on the rebuilt kernel; full suite passes (9,256 tests) with no kernel changes.

Not covered

  • Four leveldb member-chain shapes stay unlinked in the fork: members of out-of-line nested structs, types reached through using ns::WriteBatch;, locals built with constructor-call syntax, and a this-> member inside an attribute-macro class. Upstream's kit A/B reports 42 added and 30 retargeted calls in leveldb, so upstream likely links some of them; left for a follow-up.

Summary by CodeRabbit

  • Bug Fixes
    • C++ calls through members and chained member access now resolve to methods declared on the member’s type, using declarations visible to the calling file. Unrelated same-named project methods are no longer linked, including for calls through external types and raw pointers. Supported smart-pointer, iterator, and optional dereferencing remains intact.
  • Chores
    • Improved cleanup of temporary test directories and home sandboxes.
  • Documentation
    • Updated the documented upstream baseline.