hunterboerner
hunterboerner

Reputation: 1274

Reference must be valid for the lifetime 'a as defined on the block at

I am getting a lifetime error and cannot understand what the problem is. The code that's causing the error is:

fn fetch_git_repo<'a>(repo_info: &RepoInfo) -> &'a TempDir {
    let q: TempDir = TempDir::new("temp_git_clone_dir").ok().unwrap();
    //let path: &str = dir.path().to_str().unwrap();

    let status = Command::new("git").arg("clone").arg(q.path().to_str().unwrap())
        .arg(&repo_info.repo_url).status().unwrap_or_else(|e| {
            panic!("Failed to run git clone: {}", e)
        });

    if !status.success() {
        panic!("Git clone failed!");
    }

    &q
}

And the error itself is:

test.rs:88:6: 88:7 error: `q` does not live long enough
test.rs:88     &q
                          ^
test.rs:75:60: 89:2 note: reference must be valid for the lifetime 'a as defined on the block at 75:59...
test.rs:75 fn fetch_git_repo<'a>(repo_info: &RepoInfo) -> &'a TempDir {
test.rs:76     let q: TempDir = TempDir::new("temp_git_clone_dir").ok().unwrap();
test.rs:77     //let path: &str = dir.path().to_str().unwrap();
test.rs:78 
test.rs:79     let status = Command::new("git").arg("clone").arg("")
test.rs:80         .arg(&repo_info.repo_url).status().unwrap_or_else(|e| {
                     ...
test.rs:76:70: 89:2 note: ...but borrowed value is only valid for the block suffix following statement 0 at 76:69
test.rs:76     let q: TempDir = TempDir::new("temp_git_clone_dir").ok().unwrap();
test.rs:77     //let path: &str = dir.path().to_str().unwrap();
test.rs:78 
test.rs:79     let status = Command::new("git").arg("clone").arg("")
test.rs:80         .arg(&repo_info.repo_url).status().unwrap_or_else(|e| {
test.rs:81             panic!("Failed to run git clone: {}", e)

What's the problem with this function?

Upvotes: 1

Views: 1988

Answers (2)

hunterboerner
hunterboerner

Reputation: 1274

I fixed this by directly returning the TempDir.

fn fetch_git_repo(repo_info: &RepoInfo) -> TempDir {
    let z = TempDir::new("temp_git_clone_dir").unwrap();
    let q = z.path().to_str().unwrap().to_string();

    println!("{:?}", z.path());
    // omitted

    z
}

Upvotes: 0

fjh
fjh

Reputation: 13081

You're creating q in your function and then try to return a reference to it from your function. Since q ceases to exist at the end of your function, the return value would be a dangling reference, which is why the compiler won't let you do that.

btw. you can see that something dodgy is going on from your function signature. The lifetime of the returned reference ('a) isn't actually tied to anything (e.g. to the lifetime of a function argument), which indicates that this is probably not going to work.

Upvotes: 4

Related Questions