From f4b5516a2f2a61baa2e3f357400a9dad56b3c35a Mon Sep 17 00:00:00 2001 From: Emil Lundberg Date: Wed, 13 Feb 2019 01:01:18 +0100 Subject: [PATCH 1/2] Relax self-borrow lifetime in Branch.upstream() The following code currently does not compile: ```rust fn get_upstreams<'repo>(repo: &'repo git2::Repository) -> Vec<(git2::Branch<'repo>, Option>)> { repo .branches(None) // pub fn branches(&self, filter: Option) -> Result .unwrap() // git2::Branches<'a>: Iterator, git2::BranchType), git2::Error>> .flatten() // Iterator, git2::BranchType)> .map(|(branch, _): (git2::Branch<'repo>, _)| { let upstream: Option> = branch .upstream() // pub fn upstream<'a>(&'a self) -> Result, Error> .ok(); (branch, upstream) }) // Iterator, git2::Branch<'repo>)> .collect() } ``` Error: ``` error[E0597]: `branch` does not live long enough --> src/config/data/project.rs:49:55 | 49 | let upstream: Option> = branch.upstream().ok(); | ^^^^^^ borrowed value does not live long enough ... 58 | }) | - borrowed value only lives until here | note: borrowed value must be valid for the lifetime 'repo as defined on the method body at 39:30... --> src/config/data/project.rs:39:30 | 39 | fn local_branches_internal<'repo>(&self, repo: &'repo git2::Repository) -> Result, Option>)>, git2::Error> { ``` This is because the `.upstream()` method is declared with the same self-borrow lifetime as the return value: ```rust pub fn upstream<'a>(&'a self) -> Result, Error> { /* ... */ } ``` which means that the `.upstream()` call is still borrowing `self` even after it returns, even though it returns an owned value and not a reference. Relaxing the self-borrow lifetime allows the above code sample to compile successfully. The lifetime of the (maybe) returned upstream `Branch` will also be that of the repository, but otherwise unrelated to the lifetime of the `Branch` that constructed it. --- src/branch.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/branch.rs b/src/branch.rs index 3f035ed0d3..ee95b7e411 100644 --- a/src/branch.rs +++ b/src/branch.rs @@ -73,7 +73,7 @@ impl<'repo> Branch<'repo> { /// Return the reference supporting the remote tracking branch, given a /// local branch reference. - pub fn upstream<'a>(&'a self) -> Result, Error> { + pub fn upstream<'a>(&self) -> Result, Error> { let mut ret = ptr::null_mut(); unsafe { try_call!(raw::git_branch_upstream(&mut ret, &*self.get().raw())); From 85449f10ba4c5d6dddf54721036dc7d3526def12 Mon Sep 17 00:00:00 2001 From: Emil Lundberg Date: Wed, 22 May 2019 19:01:01 +0200 Subject: [PATCH 2/2] Make Branch.upstream return 'repo instead of arbitrary lifetime --- src/branch.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/branch.rs b/src/branch.rs index ee95b7e411..81485f0fd6 100644 --- a/src/branch.rs +++ b/src/branch.rs @@ -73,7 +73,7 @@ impl<'repo> Branch<'repo> { /// Return the reference supporting the remote tracking branch, given a /// local branch reference. - pub fn upstream<'a>(&self) -> Result, Error> { + pub fn upstream(&self) -> Result, Error> { let mut ret = ptr::null_mut(); unsafe { try_call!(raw::git_branch_upstream(&mut ret, &*self.get().raw()));