Open
Description
After #138731 being landed, clang now rejects the following program:
template <class...>
using void_t = void;
template <class T>
T&& declval();
namespace invoke_detail {
template <typename F>
struct traits {
template <typename... A>
using result = decltype(declval<F>()(declval<A>()...));
};
template <typename F, typename... A>
using invoke_result_t = typename traits<F>::template result<A...>;
template <typename Void, typename F, typename... A>
inline constexpr bool is_invocable_v = false;
template <typename F, typename... A>
inline constexpr bool
is_invocable_v<void_t<invoke_result_t<F, A...>>, F, A...> = true;
}
template <typename F, typename... A>
inline constexpr bool is_invocable_v =
invoke_detail::is_invocable_v<void, F, A...>;
static_assert(!is_invocable_v<int>);
We are now treating this as a hard error:
<source>:12:27: error: called object type 'int' is not a function or function pointer
12 | using result = decltype(declval<F>()(declval<A>()...));
| ^~~~~~~~~~~~
while clang-20, gcc, msvc accepted it. This change breaks folly invocability suite, which is used by large amount of currently working code. My understanding is that this code should not be considered ill-formed.
See this on compiler explorer: https://godbolt.org/z/EosEEnMsf