There were basically two bugs here:
- When C++20 to_address is called on int arr[10], then const _Ptr& becomes a reference to a const array, and then we dispatch to __to_address<const int(&)[10]>, which, oops, gives us a const int* result instead of an int* result. Solution: We need to provide the two standard-specified overloads of std::to_address in exactly the same way that we provide two overloads of __to_address.
- When __to_address is called on a pointer type, __to_address(const _Ptr&) is disabled so we successfully avoid trying to instantiate pointer_traits of that pointer type. But when it's called on an array type, __to_address(const _Ptr&) is not disabled for array types, so we go ahead and instantiate pointer_traits<int[10]>, which goes boom. Solution: We need to disable __to_address(const _Ptr&) for both pointer and array types.
Maybe we should disable it for function types too? Those are supposed not to work, but it'd affect the wording of the error message we gave. [This has now been done.]
Looking at this static assert I feel it's intended this assertion's error message should be shown when a function pointer is used.