Why does the following code compiles?
I would expect the Rust compiler to tell me
"borrowed value does not live long enough" when setting the reference
(store.barber.set(Some(&barber));
Since barber has a shorter lifetime than shop.
use core::cell::Cell;
struct Shop<'a> {
barber: Cell<Option<&'a Barber<'a>>>,
}
struct Barber<'a> {
shop: Cell<Option<&'a Shop<'a>>>,
}
fn main() {
let shop = Shop { barber: Cell::new(None) };
{
let barber = Barber { shop: Cell::new(Some(&shop))};
shop.barber.set(Some(&barber));
}
}
My assumption is confirmed by @jmb with his answer (here).
The code example comes from here. But why the whole thing works or where my misunderstanding lies is still unclear to me.
Edit/Enlightenment
The code which I commented to on @Netwaves answer.
In case the link don't work anymore and also to clarify the question.
The inner scope was just to make the lifetime more clear.
A usage would look more like this:
use core::cell::Cell;
struct Shop<'a> {
barber: Cell<Option<&'a Barber<'a>>>,
shop_state: Cell<bool>,
}
impl<'a> Shop<'a> {
fn change_barber_state(&self) {
self.barber.get().unwrap().change_state();
}
fn change_state(&self) {
self.shop_state.set(!self.shop_state.get());
}
}
struct Barber<'a> {
shop: Cell<Option<&'a Shop<'a>>>,
barber_state: Cell<bool>,
}
impl<'a> Barber<'a> {
fn change_state(&self) {
self.barber_state.set(!self.barber_state.get());
}
fn change_shop_state(&self) {
self.shop.get().unwrap().change_state();
}
}
fn main() {
let shop = Shop {
barber: Cell::new(None),
shop_state: Cell::new(false),
};
let barber = Barber {
shop: Cell::new(Some(&shop)),
barber_state: Cell::new(false),
};
shop.barber.set(Some(&barber));
println!("{:?}", barber.barber_state);
println!("{:?}", shop.shop_state);
shop.change_barber_state();
barber.change_shop_state();
println!("{:?}", barber.barber_state);
println!("{:?}", shop.shop_state);
}
Is the lifetime the same through the same scope?
I thought the lifetime is also given by freeing the resources, which happens in reverse order to the declaration. Or is this only relevant if the drop trait is implemented?