https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92067
--- Comment #7 from Jonathan Wakely <redi at gcc dot gnu.org> --- (In reply to Jason Merrill from comment #3) > Hmm? but the standard says that a precondition for std::is_constructible is > the type being complete, and we enforce that with a static_assert (since > PR71579). Why would it be a problem for the builtin to enforce it as well? It's a problem when the standard is wrong :-) https://cplusplus.github.io/LWG/issue2939 We certainly need a complete type for is_constructible<T> and is_constructible<int, T> and for is_assignable<int, T> (which is PR 109997), but we don't need a complete type for: __is_constructible(T&&, T) // currently true __is_constructible(T&, T) // currently false __is_nothrow_constructible(T&&, T) // currently ill-formed! __is_convertible(T, T&&) // currently ill-formed! The last two seem wrong, we should be able to give a correct answer. See PR 100667. https://wg21.link/p1285r0 changed the library traits to say that it's only undefined to instantiate the traits with incomplete types if "instantiation could yield a different result were T hypothetically completed". So std::is_constructible_v<T&&, T> is not undefined (because completing T doesn't change the fact that you can always bind T&& to an rvalue of type T) and so we should not reject it.