https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94260
Bug ID: 94260 Summary: Specific friend function inside c++20 concept-constrained class template triggers 'not usable in a constant expression' error Product: gcc Version: 10.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: niekb at scintilla dot utwente.nl Target Milestone: --- Dear GCC-devs, I stumbled upon the following error, while working with a particular friend function inside a concepts-contrained templated class. I tried to make a minimal example, but maybe it can be further slimmed down. I am not sure if this is a bug in GCC; however, on clang-trunk the same code compiles with no error. I've created examples on Godbolt's Compiler Explorer. The example on which GCC-trunk fails is: https://godbolt.org/z/fc3HbB The same code compiles successfully with Clang-trunk: https://godbolt.org/z/JiB_UB The error disappears when removing the concept-constraint from the class definition. The error also disappears when turning the 'fun' function into an non-friend function. kind regards, Niek NB: I've also copy-pasted the source code below: #include <utility> #include <concepts> #include <future> template<typename T> concept my_concept = std::regular<T>; template <typename T, typename runtime_t> class wrapper { T d; runtime_t& x; public: wrapper(T&& data, runtime_t& runtime) : d(std::move(data)), x(runtime) {} T& fut() { return d; } runtime_t& runtime() { return x; } }; template<my_concept field_element> //template<typename field_element> // replacing the above line by this line fixes the compilation error on GGC-trunk class test { public: friend auto fun(wrapper<std::shared_future<field_element>, test<field_element>>& a, wrapper<std::shared_future<field_element>, test<field_element>>& b) -> wrapper<std::shared_future<field_element>, test<field_element>> { return wrapper<std::shared_future<field_element>, test<field_element>> ( std::async(std::launch::deferred, [a,b]() mutable { return a.fut().get() + b.fut().get(); }), a.runtime() ); } }; int main(){ static_assert(std::regular<int>); test<int> t; std::shared_future<int> f1 = std::async(std::launch::deferred, []() { return 42; }); std::shared_future<int> f2 = std::async(std::launch::deferred, []() { return 42; }); wrapper<std::shared_future<int>, test<int>> a(std::move(f1),t); wrapper<std::shared_future<int>, test<int>> b(std::move(f2),t); fun(a, b); }