Skip to content

[BUG] Lowered UFCS doesn't SFINAE #497

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

Closed
JohelEGP opened this issue Jun 6, 2023 · 3 comments · Fixed by #506
Closed

[BUG] Lowered UFCS doesn't SFINAE #497

JohelEGP opened this issue Jun 6, 2023 · 3 comments · Fixed by #506
Labels
bug Something isn't working

Comments

@JohelEGP
Copy link
Contributor

JohelEGP commented Jun 6, 2023

Title: Lowered UFCS doesn't SFINAE.

Description:

Suppose #496 was fixed.
Attempting to check whether a UFCS candidate expression is well-formed
results in a hard error inside the UFCS machinery.

Minimal reproducer (https://cpp2.godbolt.org/z/Pn46vKMej):

#include "cpp2util.h"
template<typename T> [[nodiscard]] auto f()
requires (CPP2_UFCS_0_NONLOCAL(a, T()))
  {
}
struct B { };
static_assert([]<class T>() {
  return !requires { f<T>(); };
}.template operator()<B>());
Commands:
cppfront -clean-cpp1 main.cpp2
clang++17 -std=c++23 -stdlib=libc++ -lc++abi -pedantic-errors -Wall -Wextra -Wconversion -I . main.cpp

Expected result:

The assertion to pass.

Actual result and error:

Output:
build/_cppfront/main.cpp:3:32: error: use of undeclared identifier 'a'
    3 | requires (CPP2_UFCS_0_NONLOCAL(a, T()))
      |                                ^
build/_cppfront/main.cpp:3:11: note: in instantiation of function template specialization 'f()::(anonymous class)::operator()<B>' requested here
    3 | requires (CPP2_UFCS_0_NONLOCAL(a, T()))
      |           ^
raw.githubusercontent.com/hsutter/cppfront/main/include/cpp2util.h:746:47: note: expanded from macro 'CPP2_UFCS_0_NONLOCAL'
  746 | #define CPP2_UFCS_0_NONLOCAL(FUNCNAME,PARAM1) \
      |                                               ^
build/_cppfront/main.cpp:3:11: note: while substituting template arguments into constraint expression here
    3 | requires (CPP2_UFCS_0_NONLOCAL(a, T()))
      |           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
raw.githubusercontent.com/hsutter/cppfront/main/include/cpp2util.h:746:47: note: expanded from macro 'CPP2_UFCS_0_NONLOCAL'
  746 | #define CPP2_UFCS_0_NONLOCAL(FUNCNAME,PARAM1) \
      |                                               ^
  747 | [](auto&& obj) CPP2_FORCE_INLINE_LAMBDA -> decltype(auto) { \
      | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  748 |     if constexpr (requires{ CPP2_FORWARD(obj).FUNCNAME(); }) { \
      |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  749 |         return CPP2_FORWARD(obj).FUNCNAME(); \
      |         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  750 |     } else { \
      |     ~~~~~~~~~~
  751 |         return FUNCNAME(CPP2_FORWARD(obj)); \
      |         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  752 |     } \
      |     ~~~
  753 | }(PARAM1)
      | ~~~~~~~~~
build/_cppfront/main.cpp:8:22: note: while checking constraint satisfaction for template 'f<B>' required here
    8 |   return !requires { f<T>(); };
      |                      ^
build/_cppfront/main.cpp:8:22: note: in instantiation of function template specialization 'f<B>' requested here
build/_cppfront/main.cpp:8:22: note: in instantiation of requirement here
    8 |   return !requires { f<T>(); };
      |                      ^~~~~~
build/_cppfront/main.cpp:9:12: note: in instantiation of function template specialization '(anonymous class)::operator()<B>' requested here
    9 | }.template operator()<B>());
      |            ^
build/_cppfront/main.cpp:3:32: error: no matching function for call to 'a'
    3 | requires (CPP2_UFCS_0_NONLOCAL(a, T()))
      |                                ^
raw.githubusercontent.com/hsutter/cppfront/main/include/cpp2util.h:751:16: note: expanded from macro 'CPP2_UFCS_0_NONLOCAL'
  751 |         return FUNCNAME(CPP2_FORWARD(obj)); \
      |                ^~~~~~~~
build/_cppfront/main.cpp:3:11: note: in instantiation of function template specialization 'f()::(anonymous class)::operator()<B>' requested here
    3 | requires (CPP2_UFCS_0_NONLOCAL(a, T()))
      |           ^
raw.githubusercontent.com/hsutter/cppfront/main/include/cpp2util.h:746:47: note: expanded from macro 'CPP2_UFCS_0_NONLOCAL'
  746 | #define CPP2_UFCS_0_NONLOCAL(FUNCNAME,PARAM1) \
      |                                               ^
build/_cppfront/main.cpp:3:11: note: while substituting template arguments into constraint expression here
    3 | requires (CPP2_UFCS_0_NONLOCAL(a, T()))
      |           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
raw.githubusercontent.com/hsutter/cppfront/main/include/cpp2util.h:746:47: note: expanded from macro 'CPP2_UFCS_0_NONLOCAL'
  746 | #define CPP2_UFCS_0_NONLOCAL(FUNCNAME,PARAM1) \
      |                                               ^
  747 | [](auto&& obj) CPP2_FORCE_INLINE_LAMBDA -> decltype(auto) { \
      | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  748 |     if constexpr (requires{ CPP2_FORWARD(obj).FUNCNAME(); }) { \
      |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  749 |         return CPP2_FORWARD(obj).FUNCNAME(); \
      |         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  750 |     } else { \
      |     ~~~~~~~~~~
  751 |         return FUNCNAME(CPP2_FORWARD(obj)); \
      |         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  752 |     } \
      |     ~~~
  753 | }(PARAM1)
      | ~~~~~~~~~
build/_cppfront/main.cpp:8:22: note: while checking constraint satisfaction for template 'f<B>' required here
    8 |   return !requires { f<T>(); };
      |                      ^
build/_cppfront/main.cpp:8:22: note: while substituting deduced template arguments into function template 'f' [with T = B]
build/_cppfront/main.cpp:8:22: note: in instantiation of requirement here
    8 |   return !requires { f<T>(); };
      |                      ^~~~~~
build/_cppfront/main.cpp:9:12: note: in instantiation of function template specialization '(anonymous class)::operator()<B>' requested here
    9 | }.template operator()<B>());
      |            ^
2 errors generated.
References:
@JohelEGP JohelEGP added the bug Something isn't working label Jun 6, 2023
@JohelEGP

This comment was marked as outdated.

@JohelEGP

This comment was marked as outdated.

@JohelEGP
Copy link
Contributor Author

JohelEGP commented Jun 7, 2023

There's also noexcept propagation.
Building on #490 (comment): https://compiler-explorer.com/z/PvTx5qrr1.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant