Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: improve UFCS error messages #490

Closed
wants to merge 2 commits into from

Conversation

JohelEGP
Copy link
Contributor

@JohelEGP JohelEGP commented Jun 2, 2023

Resolves #439.

See it working at https://compiler-explorer.com/z/7asaMGY9o.

Before and after
Clang before
build/_cppfront/main.cpp:185:13: error: use of undeclared identifier 'push_back'
  185 |   CPP2_UFCS(push_back, vi, "oops");
      |             ^
build/_cppfront/main.cpp:185:3: note: in instantiation of function template specialization 'main()::(anonymous class)::operator()<std::vector<int> &, const char (&)[5]>' requested here
  185 |   CPP2_UFCS(push_back, vi, "oops");
      |   ^
raw.githubusercontent.com/hsutter/cppfront/main/include/cpp2util.h:702:2: note: expanded from macro 'CPP2_UFCS'
  702 | }(PARAM1, __VA_ARGS__)
      |  ^
1 error generated.
Clang after
build/_cppfront/main.cpp:185:3: error: static assertion failed due to requirement 'ufcs_invocable': 
  UFCS candidates are invalid:
    1) vi.push_back("oops")
    2) push_back(vi, "oops")
  Calling them unconditionally to have them diagnosed.
  185 |   CPP2_UFCS(push_back, vi, "oops");
      |   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
build/_cppfront/main.cpp:40:27: note: expanded from macro 'CPP2_UFCS'
   40 |             static_assert(ufcs_invocable, \
      |                           ^~~~~~~~~~~~~~
build/_cppfront/main.cpp:185:3: note: in instantiation of function template specialization 'main()::(anonymous class)::operator()<std::vector<int> &, const char (&)[5]>' requested here
build/_cppfront/main.cpp:46:2: note: expanded from macro 'CPP2_UFCS'
   46 | }(PARAM1, __VA_ARGS__)
      |  ^
build/_cppfront/main.cpp:185:13: error: no matching member function for call to 'push_back'
  185 |   CPP2_UFCS(push_back, vi, "oops");
      |   ~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~
build/_cppfront/main.cpp:43:27: note: expanded from macro 'CPP2_UFCS'
   43 |         CPP2_FORWARD(obj).FUNCNAME(CPP2_FORWARD(params)...); \
      |         ~~~~~~~~~~~~~~~~~~^~~~~~~~
/opt/compiler-explorer/clang-trunk-20230602/bin/../include/c++/v1/vector:650:62: note: candidate function not viable: no known conversion from 'const char[5]' to 'const value_type' (aka 'const int') for 1st argument
  650 |     _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void push_back(const_reference __x);
      |                                                              ^
/opt/compiler-explorer/clang-trunk-20230602/bin/../include/c++/v1/vector:652:62: note: candidate function not viable: no known conversion from 'const char[5]' to 'value_type' (aka 'int') for 1st argument
  652 |     _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void push_back(value_type&& __x);
      |                                                              ^
build/_cppfront/main.cpp:185:13: error: use of undeclared identifier 'push_back'
  185 |   CPP2_UFCS(push_back, vi, "oops");
      |             ^
3 errors generated.
GCC before
In file included from /app/cpp2util.h:1,
                 from /app/build/_cppfront/main.cpp:3:
build/_cppfront/main.cpp: In instantiation of 'main()::<lambda(auto:85&&, auto:86&& ...)> [with auto:85 = std::vector<int>&; auto:86 = {const char (&)[5]}]':
build/_cppfront/main.cpp:185:3:   required from here
build/_cppfront/main.cpp:185:3: error: 'push_back' was not declared in this scope
  185 |   CPP2_UFCS(push_back, vi, "oops");
      |   ^
GCC after
build/_cppfront/main.cpp: In instantiation of 'main()::<lambda(auto:85&&, auto:86&& ...)> [with auto:85 = std::vector<int>&; auto:86 = {const char (&)[5]}]':
build/_cppfront/main.cpp:185:3:   required from here
build/_cppfront/main.cpp:40:27: error: static assertion failed: 
  UFCS candidates are invalid:
    1) vi.push_back("oops")
    2) push_back(vi, "oops")
  Calling them unconditionally to have them diagnosed.
   40 |             static_assert(ufcs_invocable, \
      |                           ^~~~~~~~~~~~~~
build/_cppfront/main.cpp:185:3: note: in expansion of macro 'CPP2_UFCS'
  185 |   CPP2_UFCS(push_back, vi, "oops");
      |   ^~~~~~~~~
build/_cppfront/main.cpp:40:27: note: 'ufcs_invocable' evaluates to false
   40 |             static_assert(ufcs_invocable, \
      |                           ^~~~~~~~~~~~~~
build/_cppfront/main.cpp:185:3: note: in expansion of macro 'CPP2_UFCS'
  185 |   CPP2_UFCS(push_back, vi, "oops");
      |   ^~~~~~~~~
build/_cppfront/main.cpp:43:35: error: no matching function for call to 'push_back(const char [5])'
   43 |         CPP2_FORWARD(obj).FUNCNAME(CPP2_FORWARD(params)...); \
      |                                   ^
build/_cppfront/main.cpp:185:3: note: in expansion of macro 'CPP2_UFCS'
  185 |   CPP2_UFCS(push_back, vi, "oops");
      |   ^~~~~~~~~
In file included from /opt/compiler-explorer/gcc-trunk-20230602/include/c++/14.0.0/vector:66,
                 from /app/raw.githubusercontent.com/hsutter/cppfront/main/include/cpp2util.h:206,
                 from /app/cpp2util.h:1,
                 from /app/build/_cppfront/main.cpp:3:
/opt/compiler-explorer/gcc-trunk-20230602/include/c++/14.0.0/bits/stl_vector.h:1281:7: note: candidate: 'constexpr void std::vector<_Tp, _Alloc>::push_back(const value_type&) [with _Tp = int; _Alloc = std::allocator<int>; value_type = int]' (near match)
 1281 |       push_back(const value_type& __x)
      |       ^~~~~~~~~
/opt/compiler-explorer/gcc-trunk-20230602/include/c++/14.0.0/bits/stl_vector.h:1281:7: note:   conversion of argument 1 would be ill-formed:
/opt/compiler-explorer/gcc-trunk-20230602/include/c++/14.0.0/bits/stl_vector.h:1281:7: error: invalid conversion from 'const char*' to 'std::vector<int>::value_type' {aka 'int'} [-fpermissive]
 1281 |       push_back(const value_type& __x)
      |       ^~~~~~~~~
      |       |
      |       const char*
/opt/compiler-explorer/gcc-trunk-20230602/include/c++/14.0.0/bits/stl_vector.h:1298:7: note: candidate: 'constexpr void std::vector<_Tp, _Alloc>::push_back(value_type&&) [with _Tp = int; _Alloc = std::allocator<int>; value_type = int]' (near match)
 1298 |       push_back(value_type&& __x)
      |       ^~~~~~~~~
/opt/compiler-explorer/gcc-trunk-20230602/include/c++/14.0.0/bits/stl_vector.h:1298:7: note:   conversion of argument 1 would be ill-formed:
/opt/compiler-explorer/gcc-trunk-20230602/include/c++/14.0.0/bits/stl_vector.h:1298:7: error: invalid conversion from 'const char*' to 'std::vector<int>::value_type' {aka 'int'} [-fpermissive]
 1298 |       push_back(value_type&& __x)
      |       ^~~~~~~~~
      |       |
      |       const char*
build/_cppfront/main.cpp:44:17: error: 'push_back' was not declared in this scope
   44 |         FUNCNAME(CPP2_FORWARD(obj), CPP2_FORWARD(params)...); \
      |                 ^
build/_cppfront/main.cpp:185:3: note: in expansion of macro 'CPP2_UFCS'
  185 |   CPP2_UFCS(push_back, vi, "oops");
      |   ^~~~~~~~~
Testing summary.
99% tests passed, 1 tests failed out of 253

Total Test time (real) = 114.06 sec

The following tests FAILED:
  122 - build/pure2-bugfix-for-better-ufcs-error-messages (Failed)
Errors while running CTest
Acknowledgements.

@JohelEGP
Copy link
Contributor Author

JohelEGP commented Jun 3, 2023

What do you think about having a single UFCS macro: https://compiler-explorer.com/z/hbaacdf16?

Before
auto main() -> int{
  CPP2_UFCS(push_back, vi, "oops");
  CPP2_UFCS_0(push_back, vi);
  CPP2_UFCS_TEMPLATE(push_back, (<0>), vi, "oops");
  CPP2_UFCS_TEMPLATE_0(push_back, (<0>), vi);
  CPP2_UFCS_TEMPLATE(push_back, (<0,0>), vi, 0, 0);
}
cpp2::i32 i0 {CPP2_UFCS_NONLOCAL(push_back, vi, "oops")}; 
cpp2::i32 i1 {CPP2_UFCS_0_NONLOCAL(push_back, vi)}; 
cpp2::i32 i2 {CPP2_UFCS_TEMPLATE_NONLOCAL(push_back, (<0>), vi, "oops")}; 
cpp2::i32 i3 {CPP2_UFCS_TEMPLATE_0_NONLOCAL(push_back, (<0>), vi)}; 
cpp2::i32 i4 {CPP2_UFCS_TEMPLATE_NONLOCAL(push_back, (<0,0>), vi, 0, 0)}; 
After

() and (,) for comma can be gone pending #46 (comment).

auto main_() -> int {
  CPP2_UFCS(&,,(push_back),vi,(,),"oops");
  CPP2_UFCS(&,,(push_back),vi,());
  CPP2_UFCS(&,template,(push_back<0>),vi,(,),"oops");
  CPP2_UFCS(&,template,(push_back<0>),vi,());
  CPP2_UFCS(&,template,(push_back<0, 0>),vi,(,), 0, 0);
}
cpp2::i32 i5 {CPP2_UFCS(,,(push_back),vi,(,),"oops")};
cpp2::i32 i6 {CPP2_UFCS(,,(push_back),vi,())};
cpp2::i32 i7 {CPP2_UFCS(,template,(push_back<0>),vi,(,),"oops")};
cpp2::i32 i8 {CPP2_UFCS(,template,(push_back<0>),vi,())};
cpp2::i32 i9 {CPP2_UFCS(,template,(push_back<0, 0>),vi,(,), 0, 0)};

Or somewhere in-between.

@JohelEGP
Copy link
Contributor Author

JohelEGP commented Jun 6, 2023

I think this should be superseded by the resolution for #497.
Here's the single UFCS macro with #497 fixed: https://compiler-explorer.com/z/KxavrccTc.

The error message on Clang is pretty good:

Relevant lines:

<source>:27:3: error: no matching function for call to object of type '(lambda at <source>:27:3)'
   27 |   CPP2_UFCS(&,,(push_back),vi,(,),"oops");
      |   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<source>:27:3: note: candidate template ignored: constraints not satisfied [with obj:auto = std::vector<int> &, params:auto = <const char (&)[5]>]
<source>:27:17: note: because 'std::forward<decltype(obj)>(obj).push_back(std::forward<decltype(params)>(params)...)' would be invalid: no matching member function for call to 'push_back'
<source>:27:17: note: and 'push_back(std::forward<decltype(obj)>(obj), std::forward<decltype(params)>(params)...)' would be invalid: use of undeclared identifier 'push_back'

Full output:

<source>:27:3: error: no matching function for call to object of type '(lambda at <source>:27:3)'
   27 |   CPP2_UFCS(&,,(push_back),vi,(,),"oops");
      |   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<source>:14:65: note: expanded from macro 'CPP2_UFCS'
   14 | #define CPP2_UFCS(LAMBDADEFCAPT,TEMPKW,FUNCID,PARAM1,COMMA,...) \
      |                                                                 ^
   15 | [LAMBDADEFCAPT](auto&& obj, auto&& ...params) CPP2_FORCE_INLINE_LAMBDA -> decltype(auto) \
      | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   16 |     requires requires { CPP2_FORWARD(obj).TEMPKW CPP2_UFCS_REMPARENS FUNCID(CPP2_FORWARD(params)...); } \
      |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   17 |              || requires { CPP2_UFCS_REMPARENS FUNCID(CPP2_FORWARD(obj), CPP2_FORWARD(params)...); } { \
      |              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   18 |     if constexpr (requires{ CPP2_FORWARD(obj).TEMPKW CPP2_UFCS_REMPARENS FUNCID(CPP2_FORWARD(params)...); }) { \
      |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   19 |         return CPP2_FORWARD(obj).TEMPKW CPP2_UFCS_REMPARENS FUNCID(CPP2_FORWARD(params)...); \
      |         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   20 |     } else { \
      |     ~~~~~~~~~~
   21 |         return CPP2_UFCS_REMPARENS FUNCID(CPP2_FORWARD(obj), CPP2_FORWARD(params)...); \
      |         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   22 |     } \
      |     ~~~
<source>:27:3: note: candidate template ignored: constraints not satisfied [with obj:auto = std::vector<int> &, params:auto = <const char (&)[5]>]
<source>:14:65: note: expanded from macro 'CPP2_UFCS'
   14 | #define CPP2_UFCS(LAMBDADEFCAPT,TEMPKW,FUNCID,PARAM1,COMMA,...) \
      |                                                                 ^
<source>:27:17: note: because 'std::forward<decltype(obj)>(obj).push_back(std::forward<decltype(params)>(params)...)' would be invalid: no matching member function for call to 'push_back'
   27 |   CPP2_UFCS(&,,(push_back),vi,(,),"oops");
      |                 ^
<source>:27:17: note: and 'push_back(std::forward<decltype(obj)>(obj), std::forward<decltype(params)>(params)...)' would be invalid: use of undeclared identifier 'push_back'
GCC with `-fconcepts-diagnostics-depth=2`:

Relevant lines:

<source>:27:3: note: in expansion of macro 'CPP2_UFCS'
   27 |   CPP2_UFCS(&,,(push_back),vi,(,),"oops");
      |   ^~~~~~~~~
<source>: In substitution of 'template<class auto:85, class ... auto:86> main_()::<lambda(auto:85&&, auto:86&& ...)> [with auto:85 = std::vector<int>&; auto:86 = {const char (&)[5]}]':
<source>:16:76: note: the required expression 'forward<decltype (obj)>(obj).push_back((forward<decltype(params)>)(params)...)' is invalid
<source>:17:54: note: the required expression 'push_back(forward<decltype (obj)>(obj), (forward<decltype(params)>)(params)...)' is invalid

Full output:

<source>:23:2: error: no match for call to '(main_()::<lambda(auto:85&&, auto:86&& ...)>) (std::vector<int>&, const char [5])'
   15 | [LAMBDADEFCAPT](auto&& obj, auto&& ...params) CPP2_FORCE_INLINE_LAMBDA -> decltype(auto) \
      | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   16 |     requires requires { CPP2_FORWARD(obj).TEMPKW CPP2_UFCS_REMPARENS FUNCID(CPP2_FORWARD(params)...); } \
      |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   17 |              || requires { CPP2_UFCS_REMPARENS FUNCID(CPP2_FORWARD(obj), CPP2_FORWARD(params)...); } { \
      |              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   18 |     if constexpr (requires{ CPP2_FORWARD(obj).TEMPKW CPP2_UFCS_REMPARENS FUNCID(CPP2_FORWARD(params)...); }) { \
      |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   19 |         return CPP2_FORWARD(obj).TEMPKW CPP2_UFCS_REMPARENS FUNCID(CPP2_FORWARD(params)...); \
      |         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   20 |     } else { \
      |     ~~~~~~~~~~
   21 |         return CPP2_UFCS_REMPARENS FUNCID(CPP2_FORWARD(obj), CPP2_FORWARD(params)...); \
      |         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   22 |     } \
      |     ~~~
   23 | }(PARAM1 CPP2_UFCS_REMPARENS COMMA __VA_ARGS__)
      | ~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<source>:27:3: note: in expansion of macro 'CPP2_UFCS'
   27 |   CPP2_UFCS(&,,(push_back),vi,(,),"oops");
      |   ^~~~~~~~~
<source>:15:1: note: candidate: 'template<class auto:85, class ... auto:86> main_()::<lambda(auto:85&&, auto:86&& ...)>'
   15 | [LAMBDADEFCAPT](auto&& obj, auto&& ...params) CPP2_FORCE_INLINE_LAMBDA -> decltype(auto) \
      | ^
<source>:27:3: note: in expansion of macro 'CPP2_UFCS'
   27 |   CPP2_UFCS(&,,(push_back),vi,(,),"oops");
      |   ^~~~~~~~~
<source>:15:1: note:   template argument deduction/substitution failed:
   15 | [LAMBDADEFCAPT](auto&& obj, auto&& ...params) CPP2_FORCE_INLINE_LAMBDA -> decltype(auto) \
      | ^
<source>:27:3: note: in expansion of macro 'CPP2_UFCS'
   27 |   CPP2_UFCS(&,,(push_back),vi,(,),"oops");
      |   ^~~~~~~~~
<source>:15:1: note: constraints not satisfied
   15 | [LAMBDADEFCAPT](auto&& obj, auto&& ...params) CPP2_FORCE_INLINE_LAMBDA -> decltype(auto) \
      | ^
<source>:27:3: note: in expansion of macro 'CPP2_UFCS'
   27 |   CPP2_UFCS(&,,(push_back),vi,(,),"oops");
      |   ^~~~~~~~~
<source>: In substitution of 'template<class auto:85, class ... auto:86> main_()::<lambda(auto:85&&, auto:86&& ...)> [with auto:85 = std::vector<int>&; auto:86 = {const char (&)[5]}]':
<source>:27:3:   required from here
<source>:27:3:   required by the constraints of 'template<class auto:85, class ... auto:86> main_()::<lambda(auto:85&&, auto:86&& ...)>'
<source>:17:14: note: no operand of the disjunction is satisfied
   16 |     requires requires { CPP2_FORWARD(obj).TEMPKW CPP2_UFCS_REMPARENS FUNCID(CPP2_FORWARD(params)...); } \
      |              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   17 |              || requires { CPP2_UFCS_REMPARENS FUNCID(CPP2_FORWARD(obj), CPP2_FORWARD(params)...); } { \
      |              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<source>:27:3: note: in expansion of macro 'CPP2_UFCS'
   27 |   CPP2_UFCS(&,,(push_back),vi,(,),"oops");
      |   ^~~~~~~~~
<source>:16:14: note: the operand 'requires{(forward<decltype(obj)>)(obj).push_back((forward<decltype(params)>)(params)...);}' is unsatisfied because
   16 |     requires requires { CPP2_FORWARD(obj).TEMPKW CPP2_UFCS_REMPARENS FUNCID(CPP2_FORWARD(params)...); } \
      |              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   17 |              || requires { CPP2_UFCS_REMPARENS FUNCID(CPP2_FORWARD(obj), CPP2_FORWARD(params)...); } { \
      |              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<source>:27:3: note: in expansion of macro 'CPP2_UFCS'
   27 |   CPP2_UFCS(&,,(push_back),vi,(,),"oops");
      |   ^~~~~~~~~
<source>:27:3:   required by the constraints of 'template<class auto:85, class ... auto:86> main_()::<lambda(auto:85&&, auto:86&& ...)>'
<source>:27:3:   in requirements  [with auto:85 = std::vector<int, std::allocator<int> >&; auto:86 = {const char (&)[5]}]
<source>:16:76: note: the required expression 'forward<decltype (obj)>(obj).push_back((forward<decltype(params)>)(params)...)' is invalid
   16 |     requires requires { CPP2_FORWARD(obj).TEMPKW CPP2_UFCS_REMPARENS FUNCID(CPP2_FORWARD(params)...); } \
<source>:27:3: note: in expansion of macro 'CPP2_UFCS'
   27 |   CPP2_UFCS(&,,(push_back),vi,(,),"oops");
      |   ^~~~~~~~~
<source>:17:17: note: the operand 'requires{push_back((forward<decltype(obj)>)(obj), (forward<decltype(params)>)(params)...);}' is unsatisfied because
   16 |     requires requires { CPP2_FORWARD(obj).TEMPKW CPP2_UFCS_REMPARENS FUNCID(CPP2_FORWARD(params)...); } \
      |              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   17 |              || requires { CPP2_UFCS_REMPARENS FUNCID(CPP2_FORWARD(obj), CPP2_FORWARD(params)...); } { \
      |              ~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<source>:27:3: note: in expansion of macro 'CPP2_UFCS'
   27 |   CPP2_UFCS(&,,(push_back),vi,(,),"oops");
      |   ^~~~~~~~~
<source>:27:3:   required by the constraints of 'template<class auto:85, class ... auto:86> main_()::<lambda(auto:85&&, auto:86&& ...)>'
<source>:27:3:   in requirements  [with auto:85 = std::vector<int, std::allocator<int> >&; auto:86 = {const char (&)[5]}]
<source>:17:54: note: the required expression 'push_back(forward<decltype (obj)>(obj), (forward<decltype(params)>)(params)...)' is invalid
   17 |              || requires { CPP2_UFCS_REMPARENS FUNCID(CPP2_FORWARD(obj), CPP2_FORWARD(params)...); } { \
      |                                                      ^
<source>:27:3: note: in expansion of macro 'CPP2_UFCS'
   27 |   CPP2_UFCS(&,,(push_back),vi,(,),"oops");
      |   ^~~~~~~~~
cc1plus: note: set '-fconcepts-diagnostics-depth=' to at least 3 for more detail
MSVC:

Full output:

<source>(27): error C3889: call to object of class type 'main_::<lambda_1>': no matching call operator found
<source>(27): note: could be 'decltype(auto) main_::<lambda_1>::operator ()(_T1 &&,_T2 &&...) const'
<source>(27): note: Failed to specialize function template 'decltype(auto) main_::<lambda_1>::operator ()(_T1 &&,_T2 &&...) const'
<source>(27): note: With the following template arguments:
<source>(27): note: '_T1=std::vector<int,std::allocator<int>> &'
<source>(27): note: '_T2={const char (&)[5]}'

@JohelEGP
Copy link
Contributor Author

Marking as draft to prevent merging
as this should be superseded by #506.

@JohelEGP
Copy link
Contributor Author

JohelEGP commented Sep 5, 2023

I think this should be superseded by the resolution for #497.

@JohelEGP JohelEGP closed this Sep 5, 2023
@JohelEGP JohelEGP deleted the ufcs_error_message branch September 5, 2023 15:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[SUGGESTION] UFCS error message could be less misleading
1 participant