Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions include/pybind11/detail/type_caster_base.h
Original file line number Diff line number Diff line change
Expand Up @@ -563,7 +563,7 @@ struct cast_sources {
// Use the given pointer with its compile-time type, possibly downcast
// via polymorphic_type_hook()
template <typename itype>
cast_sources(const itype *ptr); // NOLINT(google-explicit-constructor)
explicit cast_sources(const itype *ptr);

// Use the given pointer and type
// NOLINTNEXTLINE(google-explicit-constructor)
Expand Down Expand Up @@ -1621,8 +1621,7 @@ class type_caster_base : public type_caster_generic {
// that's correct in this context, so you can't use type_caster_base<A>
// to convert an unrelated B* to Python.
struct cast_sources : detail::cast_sources {
// NOLINTNEXTLINE(google-explicit-constructor)
cast_sources(const itype *ptr) : detail::cast_sources(ptr) {}
explicit cast_sources(const itype *ptr) : detail::cast_sources(ptr) {}
};

static handle cast(const itype &src, return_value_policy policy, handle parent) {
Expand All @@ -1637,6 +1636,10 @@ class type_caster_base : public type_caster_generic {
return cast(std::addressof(src), return_value_policy::move, parent);
}

static handle cast(const itype *src, return_value_policy policy, handle parent) {
return cast(cast_sources{src}, policy, parent);
}

static handle cast(const cast_sources &srcs, return_value_policy policy, handle parent) {
return type_caster_generic::cast(srcs,
policy,
Expand All @@ -1645,6 +1648,10 @@ class type_caster_base : public type_caster_generic {
make_move_constructor((const itype *) nullptr));
}

static handle cast_holder(const itype *src, const void *holder) {
return cast_holder(cast_sources{src}, holder);
}

static handle cast_holder(const cast_sources &srcs, const void *holder) {
auto policy = return_value_policy::take_ownership;
return type_caster_generic::cast(srcs, policy, {}, nullptr, nullptr, holder);
Expand Down
12 changes: 12 additions & 0 deletions tests/test_class.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,13 @@ class ForwardClass;
class Args : public py::args {};
} // namespace pr5396_forward_declared_class

struct ConvertibleFromAnything {
ConvertibleFromAnything() = default;
template <class T>
// NOLINTNEXTLINE(bugprone-forwarding-reference-overload,google-explicit-constructor)
ConvertibleFromAnything(T &&) {}
};

} // namespace test_class

static_assert(py::detail::is_same_or_base_of<py::args, py::args>::value, "");
Expand Down Expand Up @@ -578,6 +585,11 @@ TEST_SUBMODULE(class_, m) {
});

test_class::pr4220_tripped_over_this::bind_empty0(m);

// Regression test for compiler error that showed up in #5866
m.def("return_universal_recipient", []() -> test_class::ConvertibleFromAnything {
return test_class::ConvertibleFromAnything{};
});
}

template <int N>
Expand Down
Loading