Quantcast
Channel: Active questions tagged return-value - Stack Overflow
Viewing all articles
Browse latest Browse all 203

Tell the Rust compiler that a returned value doesn't hold the reference provided in the constructing function

$
0
0

I have some structs containing some data that look like this:

struct A {    // Some data}struct B<'s> {    a: &'s mut A    c: C<'s>}impl<'s> B<'s> {    fn new(a: &'s mut A, d: &'s D) -> B<'s> {        let c = C::new(d);        B { a, c }    }    fn extract_c(self) -> C<'s> {        self.c    }}// A smart pointer provided by a librarystruct C<'s> {    d: &'s D,    // Other fields holding some data, not referencing A}struct D {    // Some other data not referencing A in any way (provided by a library)}

I also have functions that that create and modify said structs like this:

fn modify(b: &mut B) {    // Modifies b.a and b.c}fn construct_c<'s>(a: &'s mut A, d: &'s D) -> C<'s> {    let mut b = B::new(a, d); // C is created in B::new    modify(&mut b);    b.extract_c()}

I want to use construct_c somewhere else such that I can make another reference to A after obtaining the result from the call, like this:

fn main() {    let mut a = A::new();    let d = D::new();    let c = construct_c(&mut a, &d);  // First mutable borrow of `a`    println!("{a}");   // Second borrow of `a`    let result = do_sth_with_c(c);  // Move of `c`    do_sth_with_a(a);    // Some other code...}

However, when I try to do that, the compiler says that when I call do_sth_with_c, I am using the first mutable borrow of a, even though c doesn't hold the reference to a provided to construct_c.

When I removed println!("{a}"); and do_sth_with_a the code compiles, but I really need to print that information and do it before calling do_sth_with_c. Is there a way to tell the compiler that C knows nothing about the reference to a and that it is safe to make new references after calling construct_c?

EDIT 1:When I substituted all the references &mut A with Rc<RefCell<A>> the code compiles. But is there another way without using Rc and RefCell?

EDIT 2:Following this answer, introducing another lifetime to B seems to resolve the issue.

How B changed:

struct B<'a, 's> {    a: &'a mut A,    c: C<'s>,}// All functions that use `B` need to be updated as well

Viewing all articles
Browse latest Browse all 203

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>