I'm reading the code of rust-sdl2 and there's this Texture
struct:
pub struct Texture<'r> {
raw: *mut sys::SDL_Texture,
_marker: PhantomData<&'r ()>,
}
How do I know where the 'r
lifetime comes from?
If the struct was declared like this, then Rust would be able to automatically ensure memory safety:
pub struct Texture<'r> {
raw: &'r mut sys::SDL_Texture,
}
Since the SDL_Texture
is managed outside of Rust code this isn't possible because a raw pointer is needed. The lifetime on the Texture
is there to add a memory-safe abstraction around an unsafe data structure.
The crate manages the creation of Texture
s, and ensures that the lifetimes are always "correct". The lifetime is there to ensure that the texture does not outlive the inner SDL_Texture
, which is only referenced by raw pointer.
You cannot create a Texture
yourself, except by unsafe functions. If you were to call TextureCreator::raw_create_texture
you'd have to meet all requirements on that lifetime yourself. Instead, the safe method create_texture
constructs a Texture
, while guaranteeing memory safety.
The type signature of create_texture
is:
pub fn create_texture<F>(
&self,
format: F,
access: TextureAccess,
width: u32,
height: u32,
) -> Result<Texture, TextureValueError>
where
F: Into<Option<PixelFormatEnum>>,
Some lifetimes are elided. According to Rust's lifetime elision rules, this can be written more explicitly as:
pub fn create_texture<'r, F>(
&'r self,
format: F,
access: TextureAccess,
width: u32,
height: u32,
) -> Result<Texture<'r>, TextureValueError>
where
F: Into<Option<PixelFormatEnum>>,
The lifetime annotations express a referential dependency between self
and the Texture
. The returned Texture
is therefore not allowed to outlive the TextureCreator
.