Cann't compile code

Why I cann't compile this?

struct A<'a>{
	x: Option<&'a mut A<'a>>
}
fn main(){
	let mut a=A{x:None};
	let mut b=A{x:Some(&mut a)};
	let mut c=A{x:Some(&mut b)};
}

It looks like you probably hit the unsized type issue, and then tried to work around it by passing a reference instead. Am I right?

I may misunderstand this, but I think the problem is that the lifetime is incoherent, because the outer references can't outlive the inner ones (because they are created later). The solution here is to box the contained struct, rather than passing a reference. I think you may also need to give A ownership of the contained structs. So something like:

struct A {
   x: Option<Box<A>>
}

fn main() {
    let a = A { x: None };
    let b = A { x: Some(Box::new(a)) };
    let c = A { x: Some(Box::new(b)) };
}

Playground link

N. B.: You can make your post more readable by placing triple backticks (```) before and after your code block

1 Like

The problem is that you're requiring all lifetimes to be equal. So b must live as long as a, which it can't because b is dropped before a at the end of the function.

You could use two lifetimes (with an "outlives" relationship), but since the type is recursive I'm not sure it is possible to express it for arbitrary nesting without needing arbitrary many lifetimes in the type.

2 Likes

Your original code works if you change the &mut A references to &A references, because &A is "variant over A", meaning you can pass a longer reference where a shorter one is expected.

It doesn't work for &mut A because mutable references are "invariant", meaning that all the values in your example would need to have the exact same lifetime.

One way to make this work is to declare all the variables in a single let statement. This gives them the exact same scope:

struct A<'a>{
    x: Option<&'a mut A<'a>>
}
fn main(){
    let (mut a, mut b, mut c);
    a=A{x:None};
    b=A{x:Some(&mut a)};
    c=A{x:Some(&mut b)};
}

(playground)

6 Likes

Thank you for reply. I'm beginner in Rust)