The following code sample is a minified version of a problem I have.
trait Offset: Default {}
trait Reader {
type Offset: Offset;
}
impl Offset for usize {}
impl<'a> Reader for &'a [u8] {
type Offset = usize;
}
// OK
// struct Header<R: Reader>(R, usize);
// Bad
struct Header<R: Reader>(R, R::Offset);
impl <R: Reader<Offset=usize>> Header<R> {
fn new(r: R) -> Self {
Header(r, 0)
}
}
fn test<R: Reader>(_: Header<R>, _: Header<R>) {}
fn main() {
let buf1 = [0u8];
let slice1 = &buf1[..];
let header1 = Header::new(slice1);
let buf2 = [0u8];
let slice2 = &buf2[..];
let header2 = Header::new(slice2);
test(header1, header2);
}
I currently have the code working using usize instead of the Offset associated type. I'm trying to generalize my code so it can work with other types for offset. However, adding this associated type has caused lots of existing code to stop compiling with errors like this:
error[E0597]: `buf2` does not live long enough
--> src/main.rs:37:1
|
33 | let slice2 = &buf2[..];
| ---- borrow occurs here
...
37 | }
| ^ `buf2` dropped here while still borrowed
|
= note: values in a scope are dropped in the opposite order they are created
Reversing the order of header1 and buf2 fixes the problem for this example, but I don't want to have to make this change everywhere (and may not be able to), and I don't understand why it is a problem.