Storing something in a struct alongside its "owner"?

I mess around with rust every once in a while, and often run into issues where I want a struct to hold both some sort of system, and things created by that system that must not outlive it.

Most recently, using TextureCreator and Texture from the sdl3 crate put me in this situation:

struct State<'a> {
    canvas: WindowCanvas,
    tc: TextureCreator<WindowContext>,
    textures: Vec<Texture<'a>>, // textures must live as long as `tc`.
    // ...
}

Seems easy, right? Simple enough concept, I store a thing and the resources I used to create it, it's inherently obvious that they cannot outlive each other.

Now that I have my structure, I want to make a simple method to load textures.. and the borrow checker starts tormenting me!

For example, this initial approach does not work, insisting that the newly-added texture will not outlive self:

impl<'a> State<'a> {
    fn load_texture(&mut self, name: &str) -> Option<usize> {
        // ... omitted: load a texture, etc.
        self.textures.push(tex);
        // ... omitted: rest of the function
    }
}

I can resolve this by changing the self argument to &'a mut self... but then my main method seems convinced that I have taken an undying, infinite mutable reference to my state structure that lasts until the end of time.

Structurally, what do I do about this? I've seen suggestions to keep the "owning" thing (in this case the TextureCreator) and "owned" thing (Textures) in wholly different structures, never to meet, but.. that seems super messy, probably resulting in having to pass the two structures separately through tons of functions. I want to store "all the context" in one struct for a reason, and it seems silly to split it to avoid a situation that doesn't even seem self-referential in a way that matters.

Well-designed Rust libraries should avoid putting their callers in this situation. (Therefore, it follows that sdl3 is not a well-designed Rust library.)

The simplest angle on this problem, when possible, is to make your TextureCreator owned by some function, such as main(), which doesn't return until the program is exiting or at least until the window is closed. This is essentially “wholly different structures” in disguise.

If you have no alternative, you can use one of the “self-referential struct” libraries like ouroboros or self_cell. But these come with their own restrictions, because they’re doing something that Rust wasn’t designed to be able to do (yet).

Thank you. I ended up going with the main function owning the TextureCreator itself, and my context structure simply keeping a mutable reference to it with lifetime 'a.

i don't have any experience with sdl3,
but yoke - Rust may solve this while keeping TextureCreator inside the struct,
the downside is that you'd need to put TextureCreator into a Box (the thing being borrowed from needs to be StableDeref) and wrap the textures (including the Vec) into a newtype that derives Yokable (which only cares about variance, not what traits the fields implement).

...mgghhhhh I love yoke, but I do dislike people using Box for self-referential structs. Sure, it runs fine under Tree Borrows and isn't currently miscompiled (as far as I know), but it is still technically undefined behavior, and Miri reports as much under Stacked Borrows.