-
Notifications
You must be signed in to change notification settings - Fork 13.9k
Description
Given code like the following three cases where the user intended to reuse a previously allocated mutable buffer in a loop where the buffer is populated with borrows which affect the lifetime of the buffer itself, the errors are always E0597 "doesn't live long enough" pointing at the intermediary data being used.
fn process_sources(sources: Vec<Source>) {
let mut buffer: Vec<&[u8]> = vec![];
for source in sources {
let data: Vec<u8> = source.fetch_data();
buffer.extend(data.split(splitter));
process_data(&buffer);
buffer.clear();
}
}
error[E0597]: `data` does not live long enough
--> src/lib.rs:5:23
|
4 | let data: Vec<u8> = source.fetch_data();
| ---- binding `data` declared here
5 | buffer.extend(data.split(splitter));
| ------ ^^^^ borrowed value does not live long enough
| |
| borrow later used here
...
8 | }
| - `data` dropped here while still borrowed
fn process_sources(sources: Vec<Source>) {
let mut buffer: Vec<&[u8]> = vec![];
for source in sources {
buffer.clear();
let data: Vec<u8> = source.fetch_data();
buffer.extend(data.split(splitter));
process_data(&buffer);
}
}
error[E0597]: `data` does not live long enough
--> src/lib.rs:6:23
|
4 | buffer.clear();
| ------ borrow later used here
5 | let data: Vec<u8> = source.fetch_data();
| ---- binding `data` declared here
6 | buffer.extend(data.split(splitter));
| ^^^^ borrowed value does not live long enough
7 | process_data(&buffer);
8 | }
| - `data` dropped here while still borrowed
fn process_sources(sources: Vec<Source>) {
let mut buffer: Vec<&[u8]> = vec![];
for source in sources {
let data: Vec<u8> = source.fetch_data();
buffer.extend(data.split(splitter));
process_data(&buffer);
}
}
error[E0597]: `data` does not live long enough
--> src/lib.rs:5:23
|
4 | let data: Vec<u8> = source.fetch_data();
| ---- binding `data` declared here
5 | buffer.extend(data.split(splitter));
| ------ ^^^^ borrowed value does not live long enough
| |
| borrow later used here
6 | process_data(&buffer);
7 | }
| - `data` dropped here while still borrowed
The compiler should detect cases of buffer re-use and explain what's going on, pointing at the buffer
declaration.
Ideally, it should recommend using recycle_vec
(or the potential std API of the same use), or the unsafe
code required to reconstitute the buffer within the loop without reallocation.
Case 1 in https://databento.com/blog/why-we-didnt-rewrite-our-feed-handler-in-rust, additional discussion in https://internals.rust-lang.org/t/same-old-issues-recurring-self-referential-types-generics-less-flexible-than-c-templates/23603