The following compiles on trunk: struct NonMovable { NonMovable() = default; NonMovable(NonMovable&&) = delete; }; static_assert( __reference_converts_from_temporary(int&&, int)); static_assert(!__reference_converts_from_temporary(NonMovable&&, NonMovable)); static_assert( __reference_constructs_from_temporary(int&&, int)); static_assert(!__reference_constructs_from_temporary(NonMovable&&, NonMovable)); When the NonMovable assertions should fail because there *is* a temporary being bound to a reference (in exactly the same way as the int case). We can observe it instantiating constructors that shouldn't be too: template<typename T> struct S { template<typename U = T> S(const S&&) noexcept(U()) {} }; static_assert(__reference_converts_from_temporary(const S<bool>&&, const S<bool>)); static_assert(__reference_converts_from_temporary(const S<void*>&&, const S<void*>)); Which complains about a conversion from void* to bool even though constructors shouldn't be looked at.
This seems to be https://cplusplus.github.io/LWG/issue3819