Skip to content

[Clang] expression SFINAE in variable template partial specialization became a hard error #139163

Open
@yuxuanchen1997

Description

@yuxuanchen1997

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    c++14clang:frontendLanguage frontend issues, e.g. anything involving "Sema"diverges-from:gccDoes the clang frontend diverge from gcc on this issuediverges-from:msvcDoes the clang frontend diverge from msvc on this issue

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions