Skip to content

interop: let a virtual_ parameter of an any carry a registry - #116

Merged
jll63 merged 1 commit into
boostorg:developfrom
jll63:fix/interop-virtual-param-registry
Sep 17, 2026
Merged

jll63 merged 1 commit into
boostorg:developfrom
jll63:fix/interop-virtual-param-registry

Conversation

@jll63

@jll63 jll63 commented Sep 17, 2026

Copy link
Copy Markdown
Collaborator

(Written by Claude Code, on behalf of @jll63.)

Follow-up to #113.

The problem

#113 gave virtual_ a registry parameter: template<typename T, class Registry = typename detail::registry_affinity_aux<T>::declared> struct virtual_;. The validate_method_parameter specializations in the any and type_erasure interop headers were left spelling virtual_<T>, which after the change matches only the defaulted second argument. A method whose parameter names a registry — valid, and the shape #113 introduced — falls through to the primary template instead:

using name_ = method<struct name_id,
    auto(virtual_<const std::any&, my_registry>)->std::string, my_registry>;
error: static assertion failed: virtual_<> parameter is not a polymorphic class
       and no boost_openmethod_vptr is applicable

Twelve specializations are affected: three in std_any.hpp, three in boost_any.hpp, six in boost_type_erasure.hpp.

The fix

Give the registry virtual_ carries its own template parameter, as the specializations in core.hpp do:

template<class ParamRegistry, class Registry>
struct validate_method_parameter<
    virtual_<const std::any&, ParamRegistry>, Registry, void> : std::true_type {};

The rejecting specialization is fixed the same way — an owning type_erasure::any passed by value with a spelled registry was getting the vague message above instead of its own "an owning type_erasure::any must be passed by reference".

virtual_any.hpp needs nothing: it marks parameters virtual through is_virtual<virtual_any<…>&>, not through virtual_<>.

Tests

static_asserts in the three dispatch tests, covering every accepting spelling the headers provide — const& / & / && for each any, plus the two type_erasure any reference forms. Verified to be real guards: with the header change stashed and the tests kept, test_dispatch_std_any.cpp:39 fails.

Verified locally: gcc 13.3 Debug -Werror, full suite 189/189; clang 22 on the touched tests; clang-format-22 clean.

🤖 Generated with Claude Code

https://claude.ai/code/session_018FzFtVWNk6d4Wut5SboCZC

boostorg#113 gave `virtual_` a registry parameter, so that a method can be
declared without naming a registry and a parameter can name one. The
`validate_method_parameter` specializations in the `any` and
type_erasure interop headers were left spelling `virtual_<T>`, which
after the change matches only the defaulted second argument. A method
declared `virtual_<const std::any&, R>` - valid, and what the registry
affinity machinery produces when a parameter names its registry - fell
through to the primary template instead:

    error: virtual_<> parameter is not a polymorphic class and no
    boost_openmethod_vptr is applicable

Give the registry `virtual_` carries its own template parameter, as the
specializations in core.hpp do. The rejecting one, for an owning
`type_erasure::any` passed by value, is fixed the same way, so that it
keeps reporting "an owning type_erasure::any must be passed by
reference" rather than the vague message above.

The three dispatch tests assert the accepting spellings, in each form
the header covers.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018FzFtVWNk6d4Wut5SboCZC
@cppalliance-bot

Copy link
Copy Markdown

An automated preview of the documentation is available at https://116.openmethod.prtest3.cppalliance.org/libs/openmethod/doc/html/index.html

If more commits are pushed to the pull request, the docs will rebuild at the same URL.

2026-09-17 21:07:34 UTC

@jll63
jll63 merged commit f16e03d into boostorg:develop Sep 17, 2026
52 of 53 checks passed
@jll63
jll63 deleted the fix/interop-virtual-param-registry branch September 18, 2026 01:26
jll63 added a commit to jll63/openmethod that referenced this pull request Sep 18, 2026
…g#116)

boostorg#113 gave `virtual_` a registry parameter, so that a method can be
declared without naming a registry and a parameter can name one. The
`validate_method_parameter` specializations in the `any` and
type_erasure interop headers were left spelling `virtual_<T>`, which
after the change matches only the defaulted second argument. A method
declared `virtual_<const std::any&, R>` - valid, and what the registry
affinity machinery produces when a parameter names its registry - fell
through to the primary template instead:

    error: virtual_<> parameter is not a polymorphic class and no
    boost_openmethod_vptr is applicable

Give the registry `virtual_` carries its own template parameter, as the
specializations in core.hpp do. The rejecting one, for an owning
`type_erasure::any` passed by value, is fixed the same way, so that it
keeps reporting "an owning type_erasure::any must be passed by
reference" rather than the vague message above.

The three dispatch tests assert the accepting spellings, in each form
the header covers.


Claude-Session: https://claude.ai/code/session_018FzFtVWNk6d4Wut5SboCZC

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
jll63 added a commit to jll63/openmethod that referenced this pull request Sep 19, 2026
Both were falsified by changes that did not update the prose around them.

boostorg#113 collapsed the "Two things deliberately do not participate" bullets
into one sentence, because `use_classes` had just started participating -
but then named two things under "One thing": the interop headers and the
C++26 `register_classes`. Restore the bullet form for the two that are
left.

The same sentence says the `any` and `type_erasure` interop headers "are
untouched". boostorg#116 touched all three of them, and had to: boostorg#113 gave
`virtual_` a registry parameter, and their `validate_method_parameter`
specializations still spelled `virtual_<T>`, which after the change
matches only the defaulted argument. What survives is the affinity claim,
which is the point of the paragraph - a `virtual_any` contributes none.
Say that, and record why a specialization there cannot go back to the
bare spelling.

The PCH paragraph names `test_capture_errors.hpp` as the only header that
carries the override on a test's behalf. `test/CMakeLists.txt` has
scanned for `test_checked_registry.hpp` as well since boostorg#93; the sentence
three lines above, "do not add a fourth marker", already counts three.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
jll63 added a commit to jll63/openmethod that referenced this pull request Sep 19, 2026
Both were falsified by changes that did not update the prose around them.

boostorg#113 collapsed the "Two things deliberately do not participate" bullets
into one sentence, because `use_classes` had just started participating -
but then named two things under "One thing": the interop headers and the
C++26 `register_classes`. Restore the bullet form for the two that are
left.

The same sentence says the `any` and `type_erasure` interop headers "are
untouched". boostorg#116 touched all three of them, and had to: boostorg#113 gave
`virtual_` a registry parameter, and their `validate_method_parameter`
specializations still spelled `virtual_<T>`, which after the change
matches only the defaulted argument. What survives is the affinity claim,
which is the point of the paragraph - a `virtual_any` contributes none.
Say that, and record why a specialization there cannot go back to the
bare spelling.

The PCH paragraph names `test_capture_errors.hpp` as the only header that
carries the override on a test's behalf. `test/CMakeLists.txt` has
scanned for `test_checked_registry.hpp` as well since boostorg#93; the sentence
three lines above, "do not add a fourth marker", already counts three.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
jll63 added a commit that referenced this pull request Sep 19, 2026
…e notes (#118)

* doc: correct two stale notes in CLAUDE.md's registry-affinity section

Both were falsified by changes that did not update the prose around them.

#113 collapsed the "Two things deliberately do not participate" bullets
into one sentence, because `use_classes` had just started participating -
but then named two things under "One thing": the interop headers and the
C++26 `register_classes`. Restore the bullet form for the two that are
left.

The same sentence says the `any` and `type_erasure` interop headers "are
untouched". #116 touched all three of them, and had to: #113 gave
`virtual_` a registry parameter, and their `validate_method_parameter`
specializations still spelled `virtual_<T>`, which after the change
matches only the defaulted argument. What survives is the affinity claim,
which is the point of the paragraph - a `virtual_any` contributes none.
Say that, and record why a specialization there cannot go back to the
bare spelling.

The PCH paragraph names `test_capture_errors.hpp` as the only header that
carries the override on a test's behalf. `test/CMakeLists.txt` has
scanned for `test_checked_registry.hpp` as well since #93; the sentence
three lines above, "do not add a fourth marker", already counts three.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* doc: state the rule against committing build output

#103 merged 415 files of b2 output - 613 MiB expanded, 94 MiB in the
pack, on a repository of about 3 MB - days after #108 added the `bin/`
ignore rule intended to prevent it. The branch was cut before that rule
landed, and an ignore rule does not apply to a path that is already
tracked, so the merge carried them in.

Nothing in the build or the review catches this, and #117 could only
untrack them: the superproject pins this library by SHA and its bot
bumps the pin within minutes of every merge, so rewriting `develop`
orphans commits `boostorg/boost` already points at - and would not even
remove the blobs, which stay reachable through `refs/pull/<n>/head`.

Write the rule down where the workflow is: stage named paths, never
`git add <dir>`, and ask before committing a build artefact or any file
over 1MB.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 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.

2 participants