Wait, what does one have to do with the other?
valueless_by_exception happens when the move assignment operator throws (which should never happen in good C++, but is not disallowed by the language). That means, the variant used to hold value X, we were moving value Y into it, but the move assignment operator failed. What is now the state of the variant? It's not X, since we started running the move constructor, which could have started destroying the old value before throwing. But it's not Y either, because the constructor didn't finish. So what's the value that's being held? The answer is that there is no valid value.
How could this be fixed using allocation? Well, if you assume that std::variant allocated, it could be implemented in such a way that the std::variant just held a pointer to a heap area which stored the actual contents of the value. When you move assign, you construct a new element on the heap and move into that.
If the move assignment completes successfully, you swap the old value pointer for the new one and destroy the old value. But if move assignment/construction fails, you just retain the old pointer: nothing has been destroyed, and the variant still holds a valid value. This is very similar to the "strong exception guarantee" for std::vector, which is violated if the move assignment operator for the value throws.
This is one of many reasons why the move constructor/assignment operator should always be noexcept: there's no reason why it should ever throw, and it violates a bunch of these kinds of guarantees.
I think, anyway. I would be happy to be corrected if I got this wrong.