0

I need to call a function with a lifetime specified on self from a static context like

impl  <'w> World<'w> {
    pub fn test_with_lifetime(&'w mut self) {
        println!("test with lifetime");
    }

    pub fn test(&mut self) {
        println!("test");
    }
}

pub fn main(){
    let mut world:World = World::new();

    let world_rc:Rc<RefCell<World<'static>>> = Rc::new(RefCell::new(world));

    let world_in_closure = Rc::clone(&world_rc);


    let bx = Box::new(move ||{

        if let Ok(mut borrowed_world) = world_in_closure.try_borrow_mut() {
            borrowed_world.test_with_lifetime();
        }
    });

    (bx)();
        
}

and if fails with 'borrowed value does not live long enough...' error.

So I have two questions:

  • what's difference between &self and &'w self in function definition? Don't they both effectively mean that object lives in the caller's context?

  • is there a way to make it compile?

playground

user656449
  • 2,950
  • 2
  • 30
  • 43
  • If the way to make it compile includes changing the `test_with_lifetimes()`'s signature, then yes. If not, what are you constraints? – Chayim Friedman Oct 17 '22 at 19:09
  • the test_with_lifetimes should include lifetime for self, otherwise I can't make other parts which are not included here compiled. The full picture is quite messy but in nutshell it's yet another attempt to approach cycled structures. – user656449 Oct 17 '22 at 19:34
  • Yes. Usually when you need this lifetime it is for self-referential structs. In short, it is just not going to work. – Chayim Friedman Oct 17 '22 at 19:35
  • If you ask why the function signatures are different, I can give an answer. If not, I'm going to close this as a duplicate of the ubiquitous [Why can't I store a value and a reference to that value in the same struct?](https://stackoverflow.com/questions/32300132/why-cant-i-store-a-value-and-a-reference-to-that-value-in-the-same-struct). – Chayim Friedman Oct 17 '22 at 19:37
  • yep, I'd of course appreciate if you could answer at least first question :) – user656449 Oct 17 '22 at 19:38

1 Answers1

0

pub fn test(&mut self) is not a shortcut of pub fn test(&'w mut self). Rather, it is a shortcut for pub fn test<'a>(&'a mut self).

The difference is where the lifetime is defined: 'w is a part of the type. It is decided by the one who create the instance. And by taking &'w mut self, you usually mean that this function can be called zero (if the instance does not live as long as 'w) or one (if it does) times. More than that it cannot, because because 'w is contained within the type it must be shorter than or equal to the lifetime of the instance. And after you call it with 'w one time, it is mutably borrowed for the rest of its life.

pub fn test<'a>(&'a mut self), on the other hand, means that the caller of the function decides about the lifetime. It can be (and usually is) as short as the whole call, and doesn't need to be the whole instance's lifetime.

Chayim Friedman
  • 47,971
  • 5
  • 48
  • 77