https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113854
Nathaniel Shead <nshead at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |nshead at gcc dot gnu.org --- Comment #6 from Nathaniel Shead <nshead at gcc dot gnu.org> --- With the above patch, the original std::ranges::find_if call now gives the following diagnostic (using experimental-nesting=yes for clarity): $ g++-16 -std=c++20 -S -fdiagnostics-set-output=text:experimental-nesting=yes test.cpp test.cpp: In function ‘int main()’: test.cpp:8:24: error: no match for call to ‘(const std::ranges::__find_if_fn) (std::vector<std::unique_ptr<int> >&, main()::<lambda(auto:10)>)’ 8 | std::ranges::find_if (v, [] (auto i) { return !!i; }); | ~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ In file included from /home/wreien/.local/include/c++/16.0.0/tuple:46, from /home/wreien/.local/include/c++/16.0.0/bits/uses_allocator_args.h:41, from /home/wreien/.local/include/c++/16.0.0/bits/memory_resource.h:43, from /home/wreien/.local/include/c++/16.0.0/vector:91, from test.cpp:1: • there are 2 candidates /home/wreien/.local/include/c++/16.0.0/bits/ranges_util.h:550:10: 550 | struct __find_if_fn | ^~~~~~~~~~~~ • candidate 1: ‘template<class _Iter, class _Sent, class _Proj, class _Pred> requires (input_iterator<_Iter>) && (sentinel_for<_Sent, _Iter>) && (indirect_unary_predicate<_Pred, typename std::__detail::__projected<_Iter, _Proj>::__type>) constexpr _Iter std::ranges::__find_if_fn::operator()(_Iter, _Sent, _Pred, _Proj) const’ /home/wreien/.local/include/c++/16.0.0/bits/ranges_util.h:556:7: 556 | operator()(_Iter __first, _Sent __last, | ^~~~~~~~ • candidate expects 3 arguments, 2 provided • candidate 2: ‘template<class _Range, class _Proj, class _Pred> requires (input_range<_Range>) && (indirect_unary_predicate<_Pred, typename std::__detail::__projected<decltype(std::ranges::__access::__begin((declval<_Container&>)())), _Proj>::__type>) constexpr std::ranges::borrowed_iterator_t<_Range> std::ranges::__find_if_fn::operator()(_Range&&, _Pred, _Proj) const’ /home/wreien/.local/include/c++/16.0.0/bits/ranges_util.h:569:7: 569 | operator()(_Range&& __r, _Pred __pred, _Proj __proj = {}) const | ^~~~~~~~ • template argument deduction/substitution failed: • constraints not satisfied In file included from /home/wreien/.local/include/c++/16.0.0/compare:43, from /home/wreien/.local/include/c++/16.0.0/bits/stl_pair.h:65, from /home/wreien/.local/include/c++/16.0.0/bits/stl_algobase.h:64, from /home/wreien/.local/include/c++/16.0.0/vector:64: • /home/wreien/.local/include/c++/16.0.0/concepts: In substitution of ‘template<class _Range, class _Proj, class _Pred> requires (input_range<_Range>) && (indirect_unary_predicate<_Pred, typename std::__detail::__projected<decltype(std::ranges::__access::__begin((declval<_Container&>)())), _Proj>::__type>) constexpr std::ranges::borrowed_iterator_t<_Range> std::ranges::__find_if_fn::operator()(_Range&&, _Pred, _Proj) const [with _Range = std::vector<std::unique_ptr<int> >&; _Proj = std::identity; _Pred = main()::<lambda(auto:10)>]’: • required from here test.cpp:8:24: 8 | std::ranges::find_if (v, [] (auto i) { return !!i; }); | ~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ • required for the satisfaction of ‘invocable<_Fn, _Args ...>’ [with _Fn = main::._anon_122&; _Args = {std::unique_ptr<int, std::default_delete<int> >&}] /home/wreien/.local/include/c++/16.0.0/concepts:362:13: 362 | concept invocable = is_invocable_v<_Fn, _Args...>; | ^~~~~~~~~ • required for the satisfaction of ‘regular_invocable<_Fn, _Args ...>’ [with _Fn = main::._anon_122&; _Args = {std::unique_ptr<int, std::default_delete<int> >&}] /home/wreien/.local/include/c++/16.0.0/concepts:366:13: 366 | concept regular_invocable = invocable<_Fn, _Args...>; | ^~~~~~~~~~~~~~~~~ • required for the satisfaction of ‘predicate<_Fn&, typename std::__detail::__indirect_value<_Iter>::type>’ [with _Fn = main::._anon_122; _Iter = std::__detail::__projected<__gnu_cxx::__normal_iterator<std::unique_ptr<int, std::default_delete<int> >*, std::vector<std::unique_ptr<int, std::default_delete<int> >, std::allocator<std::unique_ptr<int, std::default_delete<int> > > > >, std::identity>::__type] /home/wreien/.local/include/c++/16.0.0/concepts:370:13: 370 | concept predicate = regular_invocable<_Fn, _Args...> | ^~~~~~~~~ • required for the satisfaction of ‘indirect_unary_predicate<_Pred, std::projected<decltype (std::ranges::__access::__begin(declval<_Container&>())), _Proj> >’ [with _Pred = main::._anon_122; _Range = std::vector<std::unique_ptr<int, std::default_delete<int> >, std::allocator<std::unique_ptr<int, std::default_delete<int> > > >&; _Proj = std::identity] /home/wreien/.local/include/c++/16.0.0/bits/iterator_concepts.h:731:13: 731 | concept indirect_unary_predicate = indirectly_readable<_Iter> | ^~~~~~~~~~~~~~~~~~~~~~~~ • the expression ‘is_invocable_v<_Fn, _Args ...> [with _Fn = main::._anon_122&; _Args = {std::unique_ptr<int, std::default_delete<int> >&}]’ evaluated to ‘false’ /home/wreien/.local/include/c++/16.0.0/concepts:362:25: 362 | concept invocable = is_invocable_v<_Fn, _Args...>; | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~ • ‘main()::<lambda(auto:10)>&’ is not invocable by ‘std::unique_ptr<int>&’, because • error: use of deleted function ‘std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = int; _Dp = std::default_delete<int>]’ In file included from /home/wreien/.local/include/c++/16.0.0/memory:80, from test.cpp:2: • declared here /home/wreien/.local/include/c++/16.0.0/bits/unique_ptr.h:525:7: 525 | unique_ptr(const unique_ptr&) = delete; | ^~~~~~~~~~ • use ‘-fdiagnostics-all-candidates’ to display considered candidates /home/wreien/.local/include/c++/16.0.0/concepts:362:25: 362 | concept invocable = is_invocable_v<_Fn, _Args...>; | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~ • initializing argument 1 of ‘main()::<lambda(auto:10)> [with auto:10 = std::unique_ptr<int>]’ test.cpp:8:28: 8 | std::ranges::find_if (v, [] (auto i) { return !!i; }); | This now includes the additional detail of: ‘main()::<lambda(auto:10)>&’ is not invocable by ‘std::unique_ptr<int>&’, because error: use of deleted function ‘std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = int; _Dp = std::default_delete<int>]’ which at least now says exactly what went wrong. The message can still be improved a lot though; there's a fair bit of extra noise here, still, and the ordering of the constraints backtrace IMO is confusing.