The reality is that there is no possible way IPv6 could have been designed that would both solve the IPv4 address exhaustion problem and natively interoperate with IPv4. When you send a packet to an IPv4 host, it needs to know where to send the response, and there simply aren't enough bits in the IPv4 header to fit more than 2^32 possible addresses.
You need something in the middle to translate between IPv6 and IPv4 addresses, and we already have that: it's called NAT64. It works the same way you would expect NAT to, and just like NAT on IPv4, there's no need to codify it as an explicit part of the IP protocol itself.