Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RWops does not live long enough #696

Closed
Flaise opened this issue Aug 26, 2017 · 5 comments
Closed

RWops does not live long enough #696

Flaise opened this issue Aug 26, 2017 · 5 comments
Labels

Comments

@Flaise
Copy link
Contributor

Flaise commented Aug 26, 2017

I'm trying to store a mixer::Music instance in a data structure for later retrieval. The data structure expects its contents to have the 'static lifetime because it uses standard library functions like TypeId::of and such that require it. I'm having trouble making it work.

extern crate sdl2;

use std::thread::sleep;
use std::time::Duration;
use sdl2::mixer::{self, LoaderRWops, INIT_OGG, open_audio, allocate_channels, AUDIO_S16LSB, Music};
use sdl2::rwops::RWops;

// I can't omit the 'static constraint because I use standard library functions that require it.
pub trait Data: 'static {
    // details elided
}

pub fn set_data<D: Data>(element: D) {
    // details elided
}

struct MusicData<'a> {
    music: Music<'a>,
    buffer: RWops<'a>,
}

impl Data for MusicData<'static> {}

pub fn init_music(bytes: &'static [u8]) {
    let buffer = RWops::from_bytes(bytes).unwrap();
    let music = buffer.load_music().unwrap();
    set_data(MusicData {music, buffer});
}

fn main() {
    let context = mixer::init(INIT_OGG).unwrap();

    let frequency = 44100;
    let format = AUDIO_S16LSB;
    let channels = 2;
    let chunk_a_size = 1024;
    open_audio(frequency, format, channels, chunk_a_size).unwrap();
    allocate_channels(100);

    init_music(include_bytes!("./test_music.ogg"));

    sleep(Duration::from_secs(10));
}

The compiler gives this error:

error[E0597]: `buffer` does not live long enough
  --> src/bin/test_music.rs:26:17
   |
26 |     let music = buffer.load_music().unwrap();
   |                 ^^^^^^ does not live long enough
27 |     set_data(MusicData {music, buffer});
28 | }
   | - borrowed value only lives until here
   |
   = note: borrowed value must be valid for the static lifetime...

You'll notice that init_music already stipulates that the original source of its data lives for the 'static lifetime and the implementation of the Music and RWops structs look to me like they should take the same lifetime as bytes. The lifetime parameter of MusicData is supposed to specify that buffer lives as long as music. But that's not what the compiler is saying. I'm confused. Can you help?

@Cobrand
Copy link
Member

Cobrand commented Aug 26, 2017

Try to remove your init_music function and put it in he main, and tell me how it goes. It looks like this is more of a Rust lifetime problem than an SDL2 problem.

For questions like this, I'd advise you to ask #rust or #rust-beginners, they will be able to help you much faster than I do :)

@Flaise
Copy link
Contributor Author

Flaise commented Aug 27, 2017

Putting it directly in main() doesn't work - it gives basically the same error.

I spoke with someone on the #rust channel and he explained more about how lifetimes work. Apparently lifetimes aren't transitive like I thought. If the contents of a RWops object has the 'static lifetime, that only means the RWops has itself a lifetime that is not longer than 'static. In this case, it still has a shorter lifetime because its drop() function is called whenever the containing data structure is dropped.

What I need is a Music<'static> instance, which I can get when I use Music::from_file() but what I'm looking for is a way to do it with a &'static [u8]. Is that something that can be done?

@Flaise
Copy link
Contributor Author

Flaise commented Sep 10, 2017

Solved by #704.

@Flaise Flaise closed this as completed Sep 10, 2017
@Flaise
Copy link
Contributor Author

Flaise commented Sep 21, 2017

Any idea when #704 will be published to crates.io?

@Cobrand
Copy link
Member

Cobrand commented Sep 21, 2017 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants