diff --git a/.clang-tidy b/.clang-tidy index a6437dd494..dbe85a8b47 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -31,9 +31,10 @@ modernize-use-override, modernize-use-using, *performance*, readability-avoid-const-params-in-decls, +readability-const-return-type, readability-container-size-empty, -readability-else-after-return, readability-delete-null-pointer, +readability-else-after-return, readability-implicit-bool-conversion, readability-make-member-function-const, readability-misplaced-array-index, diff --git a/include/pybind11/cast.h b/include/pybind11/cast.h index db79f57cda..13ae3e9c1d 100644 --- a/include/pybind11/cast.h +++ b/include/pybind11/cast.h @@ -1178,13 +1178,15 @@ class argument_loader { } template + // NOLINTNEXTLINE(readability-const-return-type) enable_if_t::value, Return> call(Func &&f) && { - return std::move(*this).template call_impl(std::forward(f), indices{}, Guard{}); + return std::move(*this).template call_impl>(std::forward(f), indices{}, Guard{}); } template + // NOLINTNEXTLINE(readability-const-return-type) enable_if_t::value, void_type> call(Func &&f) && { - std::move(*this).template call_impl(std::forward(f), indices{}, Guard{}); + std::move(*this).template call_impl>(std::forward(f), indices{}, Guard{}); return void_type(); } @@ -1206,6 +1208,7 @@ class argument_loader { } template + // NOLINTNEXTLINE(readability-const-return-type) Return call_impl(Func &&f, index_sequence, Guard &&) && { return std::forward(f)(cast_op(std::move(std::get(argcasters)))...); } diff --git a/include/pybind11/detail/descr.h b/include/pybind11/detail/descr.h index 0b498e5e72..c62e541bda 100644 --- a/include/pybind11/detail/descr.h +++ b/include/pybind11/detail/descr.h @@ -77,7 +77,8 @@ constexpr enable_if_t _(const T1 &d, const T2 &) { return d; } template constexpr enable_if_t _(const T1 &, const T2 &d) { return d; } -template auto constexpr _() -> decltype(int_to_str::digits) { +template +auto constexpr _() -> remove_cv_t::digits)> { return int_to_str::digits; } diff --git a/include/pybind11/pybind11.h b/include/pybind11/pybind11.h index 82d339751e..c4e5ea6e1f 100644 --- a/include/pybind11/pybind11.h +++ b/include/pybind11/pybind11.h @@ -2002,13 +2002,13 @@ template ()).first), #endif typename... Extra> -iterator make_key_iterator(Iterator first, Sentinel last, Extra &&... extra) { +iterator make_key_iterator(Iterator first, Sentinel last, Extra &&...extra) { using state = detail::iterator_state; if (!detail::get_type_info(typeid(state), false)) { class_(handle(), "iterator", pybind11::module_local()) .def("__iter__", [](state &s) -> state& { return s; }) - .def("__next__", [](state &s) -> KeyType { + .def("__next__", [](state &s) -> detail::remove_cv_t { if (!s.first_or_done) ++s.it; else diff --git a/include/pybind11/pytypes.h b/include/pybind11/pytypes.h index 971db85f37..2de3f5f106 100644 --- a/include/pybind11/pytypes.h +++ b/include/pybind11/pytypes.h @@ -773,7 +773,7 @@ class sequence_fast_readonly { protected: using iterator_category = std::random_access_iterator_tag; using value_type = handle; - using reference = const handle; + using reference = handle; using pointer = arrow_proxy; sequence_fast_readonly(handle obj, ssize_t n) : ptr(PySequence_Fast_ITEMS(obj.ptr()) + n) { } @@ -816,7 +816,7 @@ class dict_readonly { protected: using iterator_category = std::forward_iterator_tag; using value_type = std::pair; - using reference = const value_type; + using reference = value_type; using pointer = arrow_proxy; dict_readonly() = default; @@ -966,7 +966,7 @@ class iterator : public object { using iterator_category = std::input_iterator_tag; using difference_type = ssize_t; using value_type = handle; - using reference = const handle; + using reference = handle; using pointer = const handle *; PYBIND11_OBJECT_DEFAULT(iterator, object, PyIter_Check) diff --git a/tests/test_eigen.cpp b/tests/test_eigen.cpp index 651be0575f..ad572b2ad7 100644 --- a/tests/test_eigen.cpp +++ b/tests/test_eigen.cpp @@ -178,6 +178,7 @@ TEST_SUBMODULE(eigen, m) { ReturnTester() { print_created(this); } ~ReturnTester() { print_destroyed(this); } static Eigen::MatrixXd create() { return Eigen::MatrixXd::Ones(10, 10); } + // NOLINTNEXTLINE(readability-const-return-type) static const Eigen::MatrixXd createConst() { return Eigen::MatrixXd::Ones(10, 10); } Eigen::MatrixXd &get() { return mat; } Eigen::MatrixXd *getPtr() { return &mat; } @@ -244,6 +245,9 @@ TEST_SUBMODULE(eigen, m) { // test_fixed, and various other tests m.def("fixed_r", [mat]() -> FixedMatrixR { return FixedMatrixR(mat); }); + // Our Eigen does a hack which respects constness through the numpy writeable flag. + // Therefore, the const return actually affects this type despite being an rvalue. + // NOLINTNEXTLINE(readability-const-return-type) m.def("fixed_r_const", [mat]() -> const FixedMatrixR { return FixedMatrixR(mat); }); m.def("fixed_c", [mat]() -> FixedMatrixC { return FixedMatrixC(mat); }); m.def("fixed_copy_r", [](const FixedMatrixR &m) -> FixedMatrixR { return m; });