Lift restrictions against allocating the last storage slot
Currently, defining a storage variable that covers the last storage slot results in a compilation error. Either when contract's variables are so large that they cover the whole storage (this is already possible) or when the layout base is shifted so much that reasonably-sized variables reach the last slot (which will be possible after #597).
It's not clear why the restriction was added. It may have been done to keep the last slot reserved, but this wasn't documented anywhere, so it could just as well have been be a mistake.
We should remove the restriction.
Steps to reproduce
Oversized array
contract C {
uint[2**256] x;
}
Error: Array length too large, maximum is 2**256 - 1.
--> test.sol:2:10:
|
2 | uint[2**256] x;
| ^^^^^^
Layout
contract D layout at 2**256 - 1 {
uint x;
}
Error: Contract extends past the end of storage when this base slot value is specified.
--> test.sol:1:22:
|
1 | contract D layout at 2**256 - 1 {
| ^^^^^^^^^^
can I take this ?
One more thing here. #15668 adds a bunch of tests for things at the end of storage, but necessarily places them 1 slot away from the actual end. These tests need to be updated when this gets implemented.
hi, @cameel can i work on this issue
It's not clear why the restriction was added.
A possible reason is that while such an array would fit in storage, its size is not expressible in a 256-bit unsigned integer type. This is a complication for cases that require iteration over arrays of this size. See https://github.com/ethereum/solidity/pull/15984#discussion_r2076311803.
For this reason we may want to keep the restriction on size. We should still allow layouts that overlap the last slot though, at least as long as the variables do not take up the whole storage.