https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98077
--- Comment #3 from Jonathan Wakely <redi at gcc dot gnu.org> ---
Reduced:
template<typename T> T&& declval();
template<typename R> struct function
{
template<typename T> function(T) { }
};
template<typename T> function(T) -> function<decltype(declval<T>()())>;
template<typename T> constexpr bool is_void_v = false;
template<> constexpr bool is_void_v<void> = true;
template <typename T>
struct CallableTrait;
template <typename R>
struct CallableTrait<function<R>>
{
using ReturnType = R;
};
template <typename Callable>
using CallableTraitT = CallableTrait<decltype(function{declval<Callable>()})>;
template <typename Callable>
auto test(Callable&&)
{
using CallableInfo = CallableTraitT<Callable>;
static_assert(!is_void_v<typename CallableInfo::ReturnType>);
}
int main()
{
test([]() { return 42; });
}
98077.C: In instantiation of ‘auto test(Callable&&) [with Callable =
main()::<lambda()>]’:
98077.C:34:29: required from here
98077.C:29:20: error: invalid use of incomplete type ‘struct
CallableTrait<main()::<lambda()> >’
29 | static_assert(!is_void_v<typename CallableInfo::ReturnType>);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
98077.C:14:8: note: declaration of ‘struct CallableTrait<main()::<lambda()> >’
14 | struct CallableTrait;
| ^~~~~~~~~~~~~