I have a problem with lifetimes of Cell
(UnsafeCell
/RefCell
/...) references. From my understanding this code should compile:
fn test1<'a, 'b: 'a>(x: Cell<&'b u32>) {
let x2: Cell<&'a u32> = x;
}
But it produces an error:
error[E0308]: mismatched types
--> src/main.rs:4:29
|
4 | let x2: Cell<&'a u32> = x;
| ^ lifetime mismatch
|
= note: expected type `std::cell::Cell<&'a u32>`
found type `std::cell::Cell<&'b u32>`
note: the lifetime 'a as defined on the function body at 3:1...
--> src/main.rs:3:1
|
3 | / fn test1<'a, 'b: 'a>(x: Cell<&'b u32>) {
4 | | let x2: Cell<&'a u32> = x;
5 | | }
| |_^
note: ...does not necessarily outlive the lifetime 'b as defined on the function body at 3:1
--> src/main.rs:3:1
|
3 | / fn test1<'a, 'b: 'a>(x: Cell<&'b u32>) {
4 | | let x2: Cell<&'a u32> = x;
5 | | }
| |_^
I think :
in <>
is not well-known operator but I found it in some RFC when trying to resolve my problem.
I should be able to make a Cell
with shorter lifetime out of one with longer. When I replace Cell
type with some dummy wrapper everything works fine, so from my experiments it seems Cell
(UnsafeCell
etc) is treated specially when dealing with reference lifetimes.
This is not my original problem. I wanted to have some shared state between multiple structures - one main struct with RefCell
and child structs with reference to RefCell
but I cant get borrow checker happy without borrowing self for lifetime of entire object. See:
struct A<'a> {
x: RefCell<&'a u32>,
}
impl<'a> A<'a> {
fn new(x: &'a u32) -> A<'a> {
A { x: RefCell::new(x) }
}
fn foo(&self) -> B<'a> {
B { x: &self.x }
}
}
struct B<'a> {
x: &'a RefCell<&'a u32>,
}
If I add lifetime 'a
to self
in foo
, it compiles but then fails for this code:
let fs = A::new(&x);
{
fs.foo();
}
let fs2 = fs;
Error: error[E0505]: cannot move out of fs
because it is borrowed
Is some other method to implement shared state between objects? I'm using a single thread so theres no synchronization problem for now.