-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Description
What it does
This lint warns unintentional large temporary values which may cause an overflowed stack.
Taking this function definition:
const LENGTH: usize = 1048576;
fn foo(buf: &[u8; LENGTH]) {
let _a = buf;
}
On the signature, a thin ref &[u8; LENGTH]
ensures the argument passed in should have exactly this size. Out of the function, array.try_into().unwrap()
can be used as an assertion to the array size. However,
fn main() {
let buf = vec![0_u8; LENGTH];
// No! equivalent to: foo(&<[u8; LENGTH]>::try_from(buf).unwrap())
foo(&buf.try_into().unwrap());
}
One may carelessly write a function call like above (I searched and found many occurrences like this on GitHub). Note, it will create a [u8; LENGTH]
temporary value that is then referenced and passed to the function. This temporary value may cause an overflowed stack.
In this case above, due to different stack size limit on the two platforms, it runs smoothly on Linux but Stack overflow encounters on Windows. This may be tricky somehow.
Advantage
- Avoid unneeded stack temporary values and potential stack overflow errors.
Drawbacks
No response
Example
let buf: Vec<T> = ...
foo(&buf.try_into().unwrap());
Could be written as:
let buf: Vec<T> = ...
foo(<&[T; LENGTH]>::try_from(&buf[..]).unwrap());
Or,
let buf: Vec<T> = ...
foo((&buf[..]).try_into().unwrap());
Comparison with existing lints
We have large_stack_arrays
lint but this is unable to detect such cases.
Additional Context
No response