merge: reconcile upstream through 19813544 (16 C/C++ resolution fixes)
fork/consolidated now contains upstream main through 19813544 (16 C and C++ resolution fixes). C++ calls through iterators, subscripts, front()/back()/at(), macro-defined methods, explicit specializations and overloaded free functions now link to the method C++ calls, and a C call reaches the function its own file can see. On nlohmann/json this drops 940 call links that all pointed, wrongly, at one test file's using json alias.
The fork resolves references in the Rust kernel, so upstream's TypeScript resolver files stay deleted (name-matcher.ts, cpp-includers.ts, cpp-macro-visibility.ts, cpp-namespaces.ts, cpp-type-aliases.ts, and the new c-feature-variants.ts). Their upstream versions were the specification for the native ports below. Extraction follows upstream as written: c-cpp.ts, cpp-brace-scopes.ts, the new cpp-macro-methods.ts, and the parse-worker and tree-sitter changes. The kernel's C++ naming takes upstream's explicit-specialization names (ccpp/names.rs).
Upstream PRs
- #2567 qualified receiver type never reaches a class that only shares its last name: ported natively (
c0d14580). Two of its assertions are kept unlinked (02892a99): a member whose type a template argument decides, and a receiver another function declares. In both, upstream matches by name alone. - #2568 alias of a global-scope type: ported natively (
c0d14580). A namespace alias is looked up in the caller's include closure, and of a file's alternative aliases the first wins. - #2569 receiver type written from the global scope: ported natively (
c0d14580). - #2573 receiver declared as a class template's member type: ported natively (
dcad03ba). - #2576
->on a declared container iterator: ported natively (77fc74d7). TheRunAllassertion is kept unlinked (69dd1bd4), because the element is written only by the class template's ownoperator*. - #2579
autolocal holding a library container's iterator: ported natively (77fc74d7). - #2598 dereferenced iterator or pointer: ported natively (
77fc74d7). - #2601 member of the pair a map's iterator points at: ported natively (
77fc74d7). TheRep::Getassertion is kept unlinked (69dd1bd4), becausep.firstis aT*the template writes. - #2602 element read by subscript: ported natively (
77fc74d7). - #2605 macro-defined methods: the extraction merged as written. The resolver now reads the return type, parameters and deleted state from the macro expansion (
543a705a). - #2609 explicit specializations named after their template: the names come from
ccpp/names.rsat the merge. The resolver picks the specialization a call's template arguments name in the newresolve/cpp_specializations.rs(d2905a86). The callback synthesizer reads the same arguments throughsrc/resolution/cpp-specializations.ts. - #2612 overloaded free functions: ported natively (
39907fc3). - #2613 C call reaches the function its own file can see: ported natively (
87808361). This adds the C branch of overload selection and treats statics of included sources as visible. A standard header is never matched by the end of its path. - #2615 C header definition for a flag nothing sets: ported natively in the new
resolve/c_feature_variants.rs(aa7f5db5), with three-valued#ifevaluation. - #2616
front()/back()/at()/get()/value()results: ported natively (77fc74d7). - #2618 overloads alike but for
const: ported natively (568c0695). Four existing fork assertions now expect what upstream's specs give (c59f3b9f):- two subscript-result
dumpoverloads; overload_unreadleft unlinked;- leveldb's
DropreachingSlice::remove_prefixthroughvalue_type; FlushreachingCache::resetthrough element access.
- two subscript-result
Conflicts. Eight files conflicted:
- The deleted resolver files stay deleted.
src/index.tskeeps the fork's version.- The synthesizer imports
cppSpecializationArgumentsfrom the newsrc/resolution/cpp-specializations.ts. ccpp/names.rstakes upstream's naming.CHANGELOG.mdwas rebuilt withscripts/changelog-reconcile.mjs.
Verification, on this head (d2905a86 code; f494cb6a adds only README and CHANGELOG)
- Upstream's 16 new test files and the other C/C++ test files: 67 of 67 files, 617 of 617 tests.
- Full suite: 742 files, 9,221 tests pass (39 skipped). stderr has no
Native stack traceand noWorker exited unexpectedly. npx tsc,npm run check:agent-docs(AGENTS.md 12,800 of 32,768 bytes) andcargo clippy --release --lib -- -D warningsare clean.- Golden dumps:
UPDATE_GOLDEN=1rewrote no.dumpfile (8 of 8 pass, no diff). - Precision gate (
eval:precision), basea5f14290against this head:
| Corpus | Edges before | Edges after | Change | Graded cases |
|---|---|---|---|---|
| jq (C) | 7,784 | 7,784 | identical | none graded |
| nlohmann/json (C++) | 29,428 | 28,803 | −625 (−2.1%) | absent 11/11, present 7/7 held |
The json call edges changed in three ways:
- Lost: 973. 940 went to the
using jsonalias intests/src/fuzzer-parse_bjdata.cpp, which every test file'sjsoncall reached by name, and 23 to a test helpertestinunit-noexcept.cpp. Both are wrong cross-file guesses. - Gained: 431. Of these, 377 are instance-method calls that the iterator, element and overload ports now type.
- Retargeted: 66.
CHANGELOG. All of upstream's bullets are kept. Three fork changes:
- The older copy of the C++
->entry, which upstream's expanded entry replaces, is dropped. The fork's existing "left unlinked" wording for a class derived from adecltype(…)is kept. - The string-literal entry is dropped again, as at the last merge, because the fork already behaved that way.
- One fork entry is added for the calls the native resolver leaves unlinked where upstream matches by name alone.
README rows checked:
- The merge point is changed to
19813544. - "Name resolution" is still accurate.
- The C++ typedef/using aliases row is unchanged.
- The C++
->smart-pointer row is unchanged. - The C++
autolocal / chained call / data member row now also names an iterator's element and a map's key or value that a class template writes. - The C++ namespace aliases include-closure row is still accurate: the alias port reads only files in the caller's include closure.
- The C++ object-creation row is unchanged.
- "What the fork adds", "Measured results" and "What it costs" are unchanged.
Not covered.
- The fork-vs-upstream benchmark and the CPython edge-count row ("2% fewer on CPython") were not re-measured. The C ports (#2613, #2615) may move CPython's counts, though jq's did not change.
- I narrowed the drop of the fuzzer-alias guess to the merge commit plus
77fc74d7(an earlier kernel build already had no edges to it), but did not isolate which change caused it. - No C/C++ corpus beyond jq and nlohmann/json was run.
- The merge commit keeps upstream's
19813544as a parent, so land it as a merge commit.
Summary by cubic
Merges upstream main through 19813544, porting 16 C/C++ resolution fixes to the fork's native Rust kernel. Upstream's TypeScript resolver files stay deleted; their behavior is reimplemented natively.
C++ calls through iterators, subscripts, container accessors, macro-defined methods, explicit specializations, and overloaded free functions now link where C++ resolves them; a C call reaches the function its own file can see. On nlohmann/json the net effect is −625 call edges (−2.1%): 940 wrong links to one test file's using json alias are gone, replaced by 377 instance-method calls that now type.
Resolver changes
->on a container iterator orautoiterator, dereferences, mapfirst/second, and element subscripts read the element's class;front()/back()/at()/top()/get()/value()name what the container holds. A map'svalue_typeis its pair, so a call on it stays unlinked rather than reaching the key's method.- Explicit specializations are named after their template; a call's template arguments pick among them, and a class's own member template ends the lookup.
- Free-function overloads now pick by argument count and type, including
const-twin fits. - Macro-defined methods get nodes where invoked, with signature read from the expansion and default arguments their class declares inside a namespace.
- C calls prefer the file's own function, then an included header's; a header definition compiled only by an unset flag yields to the compiled source. Standard headers never match by path tail.
Verification
- 9,221 tests pass (39 skipped);
tsc, clippy, and agent-docs clean; golden dumps unchanged. - Precision gate holds all graded cases: jq identical, nlohmann/json −625 edges with 18/18 graded cases held.
- Conflicted files resolved as planned: upstream's deleted resolver files stay deleted, extraction merges as written,
ccpp/names.rstakes upstream's naming, CHANGELOG rebuilt.
Summary by CodeRabbit
-
Improvements
- C and C++ call links now better handle overloads, aliases, explicit template specializations, macro-defined methods, and visibility across source files.
- C++ calls through containers, iterators, pointers, arrays, and accessor results resolve more accurately when their types can be determined. Ambiguous or unreadable types remain unlinked.
- C call resolution better accounts for build flags and conditional compilation when selecting definitions.
-
Documentation
- Updated resolution notes for C++, Go, and map key/value types.