From a47659ad3bf6de563824544d77fcb28b6f3de749 Mon Sep 17 00:00:00 2001 From: Joshua Oreman Date: Wed, 15 Oct 2025 05:45:51 -0600 Subject: [PATCH 1/4] type_caster_generic: fix compiler error when casting a T that is implicitly convertible from T* --- include/pybind11/detail/type_caster_base.h | 13 ++++++++++--- tests/test_class.cpp | 12 ++++++++++++ 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/include/pybind11/detail/type_caster_base.h b/include/pybind11/detail/type_caster_base.h index cf32401b0c..c6b80734bc 100644 --- a/include/pybind11/detail/type_caster_base.h +++ b/include/pybind11/detail/type_caster_base.h @@ -563,7 +563,7 @@ struct cast_sources { // Use the given pointer with its compile-time type, possibly downcast // via polymorphic_type_hook() template - 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) @@ -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 // 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) { @@ -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, @@ -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); diff --git a/tests/test_class.cpp b/tests/test_class.cpp index 0c05614e6a..c91c43d909 100644 --- a/tests/test_class.cpp +++ b/tests/test_class.cpp @@ -58,6 +58,12 @@ class ForwardClass; class Args : public py::args {}; } // namespace pr5396_forward_declared_class +struct ConvertibleFromAnything { + ConvertibleFromAnything() = default; + template + ConvertibleFromAnything(T&&) {} // NOLINT(google-explicit-constructor) +}; + } // namespace test_class static_assert(py::detail::is_same_or_base_of::value, ""); @@ -578,6 +584,12 @@ 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 From e978e92a173cb8d7b363b3dc046fddedf0a7acd6 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 15 Oct 2025 11:48:39 +0000 Subject: [PATCH 2/4] style: pre-commit fixes --- tests/test_class.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/tests/test_class.cpp b/tests/test_class.cpp index c91c43d909..04393b3f57 100644 --- a/tests/test_class.cpp +++ b/tests/test_class.cpp @@ -61,7 +61,7 @@ class Args : public py::args {}; struct ConvertibleFromAnything { ConvertibleFromAnything() = default; template - ConvertibleFromAnything(T&&) {} // NOLINT(google-explicit-constructor) + ConvertibleFromAnything(T &&) {} // NOLINT(google-explicit-constructor) }; } // namespace test_class @@ -586,10 +586,9 @@ 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{}; - }); + m.def("return_universal_recipient", []() -> test_class::ConvertibleFromAnything { + return test_class::ConvertibleFromAnything{}; + }); } template From 758727e21c162dfce4e2cf8650d59ce77bd030cc Mon Sep 17 00:00:00 2001 From: Joshua Oreman Date: Wed, 15 Oct 2025 06:09:24 -0600 Subject: [PATCH 3/4] Placate clang-tidy --- tests/test_class.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_class.cpp b/tests/test_class.cpp index 04393b3f57..f0f649a94b 100644 --- a/tests/test_class.cpp +++ b/tests/test_class.cpp @@ -61,7 +61,7 @@ class Args : public py::args {}; struct ConvertibleFromAnything { ConvertibleFromAnything() = default; template - ConvertibleFromAnything(T &&) {} // NOLINT(google-explicit-constructor) + ConvertibleFromAnything(T &&) {} // NOLINT }; } // namespace test_class From 1f4a3918201293aa759f6fcb237df17b8579b2dc Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Wed, 15 Oct 2025 08:21:16 -0700 Subject: [PATCH 4/4] Expand NOLINT to specify Clang-Tidy check names --- tests/test_class.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/test_class.cpp b/tests/test_class.cpp index f0f649a94b..2030cd6715 100644 --- a/tests/test_class.cpp +++ b/tests/test_class.cpp @@ -61,7 +61,8 @@ class Args : public py::args {}; struct ConvertibleFromAnything { ConvertibleFromAnything() = default; template - ConvertibleFromAnything(T &&) {} // NOLINT + // NOLINTNEXTLINE(bugprone-forwarding-reference-overload,google-explicit-constructor) + ConvertibleFromAnything(T &&) {} }; } // namespace test_class