Yet another lifetime question: value dropped here while still borrowed


Time for Yet Another Lifetime Question! This time using @alexcrichton excellent libgit2 bindings.

My code:

extern crate git2;
extern crate tempdir;

fn main() {

   let git_dir = tempdir::TempDir::new("git").unwrap();
   let repo = git2::Repository::init(&git_dir).unwrap();

   let revwalk = repo.revwalk().unwrap();
   for oid in revwalk {
        let commit: git2::Commit = repo.find_commit(oid.unwrap()).unwrap();
        let tree: git2::Tree = commit.tree().unwrap();

        if let Some(_) = tree.get_name("foo") {
            // nothing
   }  // line 17
} // line 18

My error:

  --> src/
14 |         if let Some(_) = tree.get_name("foo") {
   |                          ^^^^ borrowed value does not live long enough
17 |    } // line 17
   |    - `tree` dropped here while still borrowed
   = note: values in a scope are dropped in the opposite order they are created

My confusion:

tree.get_name() will return something that will borrow from tree, so I expect that tree will be borrowed for the duration of the if let block. But that block closes on line 16. So why is tree still borrowed on line 17?

I’m slightly annoyed that rust isn’t telling me what has borrowed tree, but maybe that’s because that thing can’t be named?



I believe this is the same thing as mentioned here and in the linked reddit thread there.