.delegatecall(bytes memory) returns (bool, bytes memory)
issue low-level DELEGATECALL with the given payload, returns success condition and
return data, forwards all available gas, adjustable
Since Solidity 0.5, delegatecall provides access to the return data:
The proxy was written prior to Solidity 0.5.
Some assembly is still required as the fallback function can’t have a return value, so Solidity won’t allow us to return anything.
The proxy could potentially be changed to only use assembly for the return statement. Using assembly for the entire block may be cheaper but the gas costs haven’t been measured.
It is however true that the receive ether function can't have a return type. And since receive is used in OpenZeppelin's Proxy.sol, assembly is still required.
At any rate, I would love to see the _delegate implementation use assembly only for the return statement. The Solidity-level delegatecall is much more palatable.