Reignbeaux
Reignbeaux

Reputation: 1383

PathBuf does not live long enough

I'm trying to get the following code working in a build script:

use std::path::PathBuf;
use std::env;
use std::ffi::AsOsStr;

fn main() {
    let mut string = env::var("CARGO_MANIFEST_DIR").unwrap();
    let mut main_dir = PathBuf::new(string);
    main_dir.push("src/dependencies");

    let test_str = main_dir.as_os_str(); // test_str gets the same lifetime as main_dir

    let second_test = test_str.to_str();

    let last_test = second_test.unwrap();
    panic!(&last_test);
}

I get the following errors:

<anon>:10:24: 10:32 error: `main_dir` does not live long enough
<anon>:10         let test_str = main_dir.as_os_str(); // test_str gets the same lifetime as main_dir
                                 ^~~~~~~~
note: reference must be valid for the static lifetime...
<anon>:7:48: 16:6 note: ...but borrowed value is only valid for the block suffix following statement 1 at 7:47
<anon>:7         let mut main_dir = PathBuf::new(string);
<anon>:8         main_dir.push("src/dependencies");
<anon>:9     
<anon>:10         let test_str = main_dir.as_os_str(); // test_str gets the same lifetime as main_dir
<anon>:11     
<anon>:12         let second_test = test_str.to_str();
          ...
<anon>:15:17: 15:26 error: `last_test` does not live long enough
<anon>:15         panic!(&last_test);
                          ^~~~~~~~~
<std macros>:1:1: 12:62 note: in expansion of panic!
<anon>:15:9: 15:28 note: expansion site
note: reference must be valid for the static lifetime...
<anon>:14:45: 16:6 note: ...but borrowed value is only valid for the block suffix following statement 5 at 14:44
<anon>:14         let last_test = second_test.unwrap();
<anon>:15         panic!(&last_test);
<anon>:16     }
error: aborting due to 2 previous errors

I'm literally saving every value in an own variable. So how is this possible to not outlive the statement? I know that there is "into_os_string" as well, but why is my approach not working?

I'm really trying to understand the whole lifetime thing, but it's very difficult. Maybe someone could quickly go through my example and tell me what happens with the lifetimes in each statement and why it's not working? That'd help me a lot

Upvotes: 3

Views: 764

Answers (1)

Shepmaster
Shepmaster

Reputation: 431549

Commenting out lines of code, we can find that it is the panic! line that fails. The first argument of panic! is supposed to be a formatting string, which must have the 'static lifetime, as it's actually compiled.

A small example that replicates this is:

let s = "Foo".to_string();
panic!(&s);

But for some reason, this example has a much better error message, one that points to &s.

For your example, you can just change the panic! line to:

panic!("{}", last_test);

Upvotes: 4

Related Questions