You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Currently, we emit ArrayOutOfBounds error on the IR level, in the compile_array_index.
At that point, we know the size of the array, but not how it was declared.
This means, if the below function with array defined using const generic N is called like, e.g., literal_index_const_generic::<0> we will emit the out-of-bounds error:
This is confusing, because it is not clear at all why would the length be 0.
E.g., in such cases Rust does not emit compile time error, but rather panics at runtime.
Which possible options do we have?
Same as Rust, do not emit any error.
Out-of-bounds errors that don't lead to reverts in smart contract languages are a hairy thing. I don't feel comfortable about compiler knowing that there is an issue in code and ignoring it altogether. With the FuelVM memory model as-is, getting out-of-bounds access to valid memory, and thus no reverts, is likely.
Emit error, but a helpful one.
Unlike Rust, we might for runnable programs and tests emit an out-of-bound error, but to avoid any confusion, we provide an expressive diagnostics that also points to the callsite at which the length is actually defined.
Of course, in an arbitrary case this is tricky, because a literal length can be passed somewhere upper in the call chain, or be declared in a trait impl, etc Considering that we currently do not run IR checks when compiling libraries, we can even have a situation where the root cause of the error is outside of the developer's code.
Inject runtime boundary check
One possibility would be for the compiler to inject runtime boundary check in these places. Still, I would at least expect an explanation saying why. Which likely means emitting a warning, which poses the same complexity and questions as the point 2), except the code will still compile even if the root-cause is not in developer's code and cannot be fixed there.
Currently, we emit
ArrayOutOfBoundserror on the IR level, in thecompile_array_index.At that point, we know the size of the array, but not how it was declared.
This means, if the below function with
arraydefined using const genericNis called like, e.g.,literal_index_const_generic::<0>we will emit the out-of-bounds error:This is confusing, because it is not clear at all why would the length be
0.E.g., in such cases Rust does not emit compile time error, but rather panics at runtime.
Which possible options do we have?
Same as Rust, do not emit any error.
Out-of-bounds errors that don't lead to reverts in smart contract languages are a hairy thing. I don't feel comfortable about compiler knowing that there is an issue in code and ignoring it altogether. With the FuelVM memory model as-is, getting out-of-bounds access to valid memory, and thus no reverts, is likely.
Also, if we just remove the error, we will end up in the same issue, currently still open, with SROA, described in Index out of bounds error wrongly uses const eval of outer variables #7521.
Emit error, but a helpful one.
Unlike Rust, we might for runnable programs and tests emit an out-of-bound error, but to avoid any confusion, we provide an expressive diagnostics that also points to the callsite at which the length is actually defined.
Of course, in an arbitrary case this is tricky, because a literal length can be passed somewhere upper in the call chain, or be declared in a trait impl, etc Considering that we currently do not run IR checks when compiling libraries, we can even have a situation where the root cause of the error is outside of the developer's code.
Inject runtime boundary check
One possibility would be for the compiler to inject runtime boundary check in these places. Still, I would at least expect an explanation saying why. Which likely means emitting a warning, which poses the same complexity and questions as the point 2), except the code will still compile even if the root-cause is not in developer's code and cannot be fixed there.