https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67324
Andrew Pinski <pinskia at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|NEW |RESOLVED Keywords| |rejects-valid Resolution|--- |FIXED Target Milestone|--- |10.0 --- Comment #2 from Andrew Pinski <pinskia at gcc dot gnu.org> --- Note this is a fixed up testcase for GCC 10 with -std=c++17 -fconcepts (I don't know how to fix it up to C++20 syntax though): template< typename T, typename U > concept bool Same( ) { return __is_same_as(T, U); } template< class T > struct remove_reference { using type = T; }; template< class U > struct remove_reference<U& > { using type = U; }; template< class U > struct remove_reference<U&&> { using type = U; }; template< class T > using remove_reference_t = typename remove_reference<T>::type; template< typename T > constexpr T&& forward( remove_reference_t<T>& t) noexcept { return static_cast<T&&>(t); } template< typename T > constexpr T&& forward( remove_reference_t<T>&& t) noexcept { return static_cast<T&&>(t); } template< class T, class U = T > concept bool Assignable( ) { return requires( T&& a, U&& b ) { { forward<T>(a) = forward<U>(b) } -> Same<T&>; // #1 requires Same<T&, decltype(forward<T>(a) = forward<U>(b))>(); // #2 }; } template< typename T, typename U = T > constexpr bool test( ) { return false; } template< typename T, typename U = T > requires Assignable<T, U>() constexpr bool test( ) { return true; } struct A { }; struct B { B& operator = ( B const& ) = delete; }; struct C { C& operator = ( C&& ) = delete; }; struct D { D& operator = ( D const& ) = delete; D& operator = ( D&& ) = default; }; struct E { E& operator = ( E const & ); }; struct F { A& operator = ( F const & ); }; int main( ) { static_assert( not test<void>(), "" ); static_assert( test<bool&>(), "" ); static_assert( not test<int>(), "" ); static_assert( test<int&>(), "" ); static_assert( test<int*&>(), "" ); static_assert( not test<int const&>(), "" ); static_assert( test<char&>(), "" ); static_assert( test<unsigned&>(), "" ); static_assert( test<unsigned long&>(), "" ); static_assert( test<A&>(), "" ); static_assert( test<A&,A>(), "" ); static_assert( not test<B&>(), "" ); static_assert( not test<B&,B>(), "" ); static_assert( not test<C&>(), "" ); static_assert( not test<C&,C>(), "" ); static_assert( test<D&,D>(), "" ); static_assert( test<E&,E>(), "" ); static_assert( not test<F&,F>(), "" ); return 0; } Oh and it is fixed in GCC 10+, most likely by the rewrite of concepts to be complaint with the C++20 standard.