Skip to content

Add non-template ref-to-value converting constructor to __basic_any#8320

Open
bdice wants to merge 3 commits intoNVIDIA:mainfrom
bdice:fix/any-resource-ref-constructor
Open

Add non-template ref-to-value converting constructor to __basic_any#8320
bdice wants to merge 3 commits intoNVIDIA:mainfrom
bdice:fix/any-resource-ref-constructor

Conversation

@bdice
Copy link
Copy Markdown
Contributor

@bdice bdice commented Apr 7, 2026

Description

closes #8316

Add a non-template converting constructor __basic_any(__basic_any<_Interface&> const&) to the __basic_any value specialization, enabling implicit conversion from proxy types that wrap a __basic_any reference type.

The __basic_any value specialization provides a forwarding constructor __basic_any(_Tp&&) and template converting constructors __basic_any(__basic_any<_OtherInterface> const&). When a proxy type wraps a __basic_any<I&> (e.g. a resource_ref) and provides operator __basic_any<I&>&(), neither path works: the forwarding constructor deduces the proxy type which doesn't satisfy the interface, and the template converting constructors can't deduce _OtherInterface from the proxy since implicit user-defined conversions are not considered during template argument deduction.

This occurs concretely with Cython's __Pyx_FakeReference<T>, which wraps intermediate C++ expression results and provides operator T&(). Constructing any_resource<P...> from a Cython-wrapped resource_ref<P...> fails at compile time.

The fix adds a non-template constructor for the same-interface ref-to-value conversion. Because the parameter is non-template, the compiler considers implicit conversion sequences through the proxy's operator T&(). The existing template converting constructor gains an additional !same_as<_OtherInterface, _Interface&> constraint to avoid ambiguity.

This single fix in __basic_any covers all downstream types: any_resource, any_synchronous_resource, and any future __basic_any-based value types.

Testing: A new test was added based on the minimal reproducer in the issue. RMM Cython bindings build and pass tests using direct any_resource construction from resource_ref without workaround helpers.

Checklist

  • New or existing tests cover these changes.
  • The documentation is up to date with these changes.

The __basic_any value specialization inherits converting constructors
from templates that accept __basic_any<_OtherInterface>. When a proxy
type wraps a __basic_any reference type (e.g. __basic_any<I&>) and
provides operator __basic_any<I&>&(), these template constructors
cannot match: template argument deduction deduces the proxy type, not
the underlying __basic_any, and implicit user-defined conversions are
not considered during deduction.

Add a non-template constructor __basic_any(__basic_any<_Interface&>
const&) for the ref-to-value conversion case. Non-template parameters
participate in implicit conversion sequences, allowing proxy types to
convert through their user-defined conversion operator.

This fixes any_resource construction from proxy-wrapped resource_ref
and any_synchronous_resource from proxy-wrapped synchronous_resource_ref
without requiring per-type overloads.

Fixes NVIDIA#8316
@github-project-automation github-project-automation bot moved this to Todo in CCCL Apr 7, 2026
@bdice bdice requested a review from a team as a code owner April 7, 2026 20:20
@bdice bdice requested a review from griwes April 7, 2026 20:20
@cccl-authenticator-app cccl-authenticator-app bot moved this from Todo to In Review in CCCL Apr 7, 2026
…d refs

Add regression tests for NVIDIA#8316 verifying that any_resource and
any_synchronous_resource can be constructed from a value_proxy<T>
that wraps resource_ref or synchronous_resource_ref via operator T&(),
mimicking Cython's __Pyx_FakeReference proxy pattern.
Copy link
Copy Markdown
Contributor

@ericniebler ericniebler left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

very nice 👍

Co-authored-by: Eric Niebler <eniebler@boost.org>
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 7, 2026

😬 CI Workflow Results

🟥 Finished in 2h 13m: Pass: 47%/108 | Total: 1d 06h | Max: 58m 54s | Hits: 94%/65024

See results here.

Comment on lines +171 to +180
//! @brief Non-template converting constructor from the corresponding
//! reference type `__basic_any<_Interface&>`. This enables implicit
//! conversion from proxy types (e.g. Cython's __Pyx_FakeReference)
//! that wrap a `__basic_any<_Interface&>` and provide
//! `operator __basic_any<_Interface&>&()`, since non-template parameters
//! participate in implicit conversion sequences.
_CCCL_API __basic_any(__basic_any<_Interface&> const& __other)
{
__convert_from(__other);
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the fix, please also add the corresponding move constructor and test for rvalue proxy

@github-project-automation github-project-automation bot moved this from In Review to In Progress in CCCL Apr 8, 2026
bdice added a commit to bdice/rmm that referenced this pull request Apr 9, 2026
Work around CCCL issue where any_resource cannot be constructed from
Cython's __Pyx_FakeReference proxy type wrapping resource_ref.
Declare any_resource and device_accessible in .pxd, add inline
make_any_device_resource helper. Update all 12 constructor call sites
in .pyx to use the helper.

Ref: NVIDIA/cccl#8320
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: In Progress

Development

Successfully merging this pull request may close these issues.

any_resource(resource_ref) construction breaks with proxy types due to missing non-template overload

3 participants