0

I'm trying to read in some external GLSL code into Rust. The reading works properly, but I run into a lifetime issue in the final expression (in the Ok(_) branch)

error: s does not live long enough

fn read_shader_code(string_path: &str) -> &str {
    let path = Path::new(string_path);
    let display = path.display();

    let mut file = match File::open(&path) {
        Err(why) => panic!("Couldn't open {}: {}", display, Error::description(&why)),
        Ok(file) => file,
    };

    let mut s = String::new();
    match file.read_to_string(&mut s) {
        Err(why) => panic!("couldn't read {}: {}", display, Error::description(&why)),
        Ok(_) => &s,
    }
}
Tyler Berry
  • 496
  • 5
  • 5

1 Answers1

2

The string bound to "s" will be deallocated once the function ends ("s" goes out of scope), so you cannot return a reference to its contents outside the function. The best way is to return the string itself:

fn read_shader_code(string_path: &str) -> String {
    let path = Path::new(string_path);
    let display = path.display();

    let mut file = match File::open(&path) {
        Err(why) => panic!("Couldn't open {}: {}", display, Error::description(&why)),
        Ok(file) => file,
    };

    let mut s = String::new();
    match file.read_to_string(&mut s) {
        Err(why) => panic!("couldn't read {}: {}", display, Error::description(&why)),
        Ok(_) => s,
    }
}
eulerdisk
  • 4,299
  • 1
  • 22
  • 21
  • I just tried this actually, and took the reference to the returned String. It works, but is there any other solution that would return an &str? – Tyler Berry Jun 14 '15 at 21:07
  • Well.. you can create the string outside the function and pass it as parameter, so you will have no lifetime problems, but you cannot return a reference to something who live only in the function outside of it. fn read_shader_code(string_path: &str, &mut String buffer) -> &str {} Use buffer for the line buffer instead of s. – eulerdisk Jun 14 '15 at 21:10