Bug 98077

Summary: C++ 17: Using alias template bug in gcc
Product: gcc Reporter: juergen.reiss
Component: c++Assignee: Not yet assigned to anyone <unassigned>
Status: RESOLVED DUPLICATE    
Severity: normal CC: ppalka, webrown.cpp
Priority: P3 Keywords: rejects-valid
Version: 11.0   
Target Milestone: ---   
Host: Target:
Build: Known to work:
Known to fail: Last reconfirmed: 2020-12-01 00:00:00

Description juergen.reiss 2020-12-01 07:15:21 UTC
The error was reported here: https://stackoverflow.com/questions/65079471/c-17-using-alias-template-bug-in-gcc
A demo is here: https://godbolt.org/z/avGv3n
Comment 1 Jonathan Wakely 2020-12-01 10:33:12 UTC
Please see https://gcc.gnu.org/bugs for the requested info.
Comment 2 Jonathan Wakely 2020-12-01 13:11:10 UTC
The testcase from the godbolt link is:

// { dg-options "-std=gnu++17" }
#include <functional>

template <typename T>
struct CallableTrait;

template <typename R, typename... Args>
struct CallableTrait<std::function<R(Args...)>>
{
    using ReturnType = R;
};

template <typename Callable>
using CallableTraitT = CallableTrait<decltype(std::function{std::declval<Callable>()})>;

template <typename Callable>
auto test(Callable&&)
{
    using CallableInfo = CallableTraitT<Callable>;
    static_assert(!std::is_void_v<typename CallableInfo::ReturnType>);
}

int main()
{
    test([]() { return 42; });
}


It requires at least C++17.
Comment 3 Jonathan Wakely 2020-12-01 13:15:03 UTC
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;
      |        ^~~~~~~~~~~~~
Comment 4 Patrick Palka 2021-06-24 19:25:44 UTC
This is essentially a dup of the older 91911, I think

*** This bug has been marked as a duplicate of bug 91911 ***