Let's say I have a struct with a reference in it, and another struct with a reference to that struct, something like this:
struct Image<'a> {
pixel_data: &'a mut Vec<u8>,
size: (i32, i32),
}
struct SubImage<'a> {
image: &'a mut Image<'a>,
offset: (i32, i32),
size: (i32, i32),
}
The structs have nearly identical interfaces, the difference being that SubImage
adjusts position parameters based on its offset before forwarding to the corresponding functions of the contained Image
reference. I would like these structs to be mostly interchangeable, but I can't seem to figure out how to get lifetimes right. Originally, I was just using Image
, and could pass around objects simply, without ever mucking about with lifetime specifiers:
fn main() {
let mut pixel_data: Vec<u8> = Vec::new();
let mut image = Image::new(&mut pixel_data, (1280, 720));
render(&mut image);
}
fn render(image: &mut Image) {
image.rect_fill(0, 0, 10, 10);
}
Then I created SubImage
, and wanted to do things like this:
fn render2(image: &mut Image) {
let mut sub = SubImage {
image: image, // line 62
offset: (100, 100),
size: (600, 400),
};
sub.rect_fill(0, 0, 10, 10);
}
This, however, causes a compiler error:
main.rs:62:16: 62:21 error: cannot infer an appropriate lifetime for automatic coercion due to conflicting requirements
The compiler's suggestion is to change the signature to this:
fn render2<'a>(image: &'a mut Image<'a>)
However, that just pushes the problem up to the function which called render2
, and took a &mut Image
. And this is quite annoying, as the function calls go a few layers deep, and I didn't have to do any of this when I was just using the Image
class (which also has a reference), and adjusting the offsets inline.
So first of all, I don't even understand why this is necessary (admittedly my understanding of rust lifetimes is limited). And secondly (my main question), is there anything I can do to SubImage
to make these explicit lifetimes not necessary?