Issues with self-borrowing methods w/ lifetime parameters

Hi there, I was learning rust by writing some real code, so I was trying to use clang-rs library in one of my projects, and I tried to start with building a wrapper. Here are the few lines of code that I started with:

use clang::Clang;
use clang::Index;
use clang::TranslationUnit;
use clang::Parser;
use clang::Unsaved;
use clang::Entity;

pub struct SolutionAnalyzer<'i> {
    index: Index<'i>,
    parser: Option<Parser<'i>>,
    tu: Option<TranslationUnit<'i>>
}

impl<'i> SolutionAnalyzer<'i> {
    pub fn new(cl:&Clang) -> SolutionAnalyzer {
        SolutionAnalyzer {
            index: Index::new(&cl, false, false),
            parser: None,
            tu: None
        }
    }

    pub fn parse_string(&'i mut self, content:&str) -> Option<Entity> {
        let src_files = [Unsaved::new("tmp_src.cpp", content),];
        self.parser = Some(self.index.parser("tmp_src.cpp"));
        self.tu = self.parser.as_mut().unwrap().unsaved(&src_files).parse().ok();
        match self.tu {
            Some(ref unit) => Some(unit.get_entity()),
            None => None
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;


    #[test]
    fn accepts_simple_c_program() {
        let cl = Clang::new().unwrap();
        let mut analyzer = SolutionAnalyzer::new(&cl);
        let simple_c_program = "int main() {return 0;}";
        let result = analyzer.parse_string(&simple_c_program);
        assert!(result.is_some());
    }

}

However when I was trying to run the test the compiler is constantly complaining about my analyzer in my test function:

error[E0597]: `analyzer` does not live long enough
  --> src/backend/solution_analyzer.rs:44:22
   |
44 |         let result = analyzer.parse_string(&simple_c_program);
   |                      ^^^^^^^^ borrowed value does not live long enough
45 |         assert!(result.is_some());
46 |     }
   |     -
   |     |
   |     `analyzer` dropped here while still borrowed
   |     borrow might be used here, when `analyzer` is dropped and runs the destructor for type `backend::solution_analyzer::SolutionAnalyzer<'_>`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0597`.
error: could not compile `partlibspec`.
warning: build failed, waiting for other jobs to finish...
error: build failed

I just can't make sense of these errors, should not my analyzer in test function outlives result? If that is the case, which borrow there actually is causing the error?

Or is it the 'i parameter I put at the &'i mut self borrow causing the problems? But to my understanding, I've bound that 'i parameter with the lifetime of the struct itself through impl<'i> so that should not be the issue, am I correct?

On the other hand, I tried to simplify the code here before shooting for a post, but a similar code structure in this playground actually works, so could this be anything related to clang-rs library?

Since 'i is the lifetime of your cl variable, calling it with a mutable borrow that lasts for the entire 'i lifetime means that your borrow of analyzer must outlive the cl variable, but since analyzer is defined last, it is dropped before cl is dropped and thus also before your borrow ends.

So yes, you don't want 'i on your mutable borrow of self.

Removing 'i on the mutable borrow actually creates some other problems but I realized that these are actually more related to the topic of self-referential structs in rust so it might not be in the scope of this problem anymore. Marking last reply as solution.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.