Your code has undefined behaviour as you are passing uninitialized memory to poll_read without first passing it to prepare_uninitialized_buffer.
Note that tokio provies AsyncRead::poll_read_buf which does this for you in the case of a BytesMut. If you are interested in the details of how it works, you can read the source here.
As @alice said, your code is currently considered UB; that's what .poll_read_buf() is for. The irony here is that the current implementation of .poll_read_buf() is actually doing kind of what you were already doing, so the UB is still there. But we can hope it will be fixed in the long run.