Commit Graph
1 Commits
Author SHA1 Message Date
Colby MchenryandClaude Opus 5.5 226ac930de fix(cpp): a call through a written class template specialization, like formatter<int>::format(…), never reaches another specialization's member (#2725)
The index names a class template specialization's out-of-line member
after the template: fmt's test-only `auto
fmt::formatter<incomplete_type>::format(…)` is `fmt::formatter::format`.
So `formatter<int>::format(42, ctx)` in fmt's tests reached that member,
defined in another file, and `formatter<std::tm, Char>::parse(ctx)`,
where the template declares no such member, fell through to a guess by
the receiver's name: `native_formatter::parse`.

- A C++ call whose qualifier is written with template arguments keeps a
  candidate defined out of line for a full specialization of its class
  only when that specialization's arguments are the call's. A template's
  own members, which have a `template <…>` header with parameters,
  partial specializations' members and members defined in their class
  stay. This applies beside the existing specialization pool in the exact
  and partial qualified-name matches and in cppMethodOf's own members.
- When the class strategy finds no member for a call through a project
  class template's written specialization, matchMethodCall stops: a
  method picked by the receiver's name would be another class's.

Measured on main f6d8f19b: fmt 17 wrong edges removed; json's 16
changed sites all point at a phantom node (a noexcept clause read as a
declaration, filed separately); rocksdb, protobuf, leveldb, abseil,
redis and seven controls in other languages are byte-identical.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-21 03:10:30 +00:00