This question goes deep into the topic of ownership.
You always have to ask yourself: Who owns what?
In your case, inside the run
function, self
is a non-mutable reference. That means that the self
object is owned by someone else, and we only borrowed it.
That sadly means that we cannot create a Box
out of it, because that would require us to own self
. (Because Box::new()
takes ownership of the object it is given)
So all we can do is pass on the borrowed self
object to the B
object.
Now there is a problem, sadly, which depends on your usecase. Every borrowed object is associated with a lifetime, to make sure the borrow gets returned before the original object gets destroyed. And if you create a B
object that holds a reference to A
, the B
object inherits that lifetime. It's certainly possible to do so, but manual lifetime management is an advanced topic in Rust because it can be frustrating to deal with.
I'd advise you to read a tutorial on how to manage lifetimes in Rust.
Just to demonstrate how this could look like:
use std::marker::PhantomData;
pub trait Tester {}
pub struct A<T: Tester> {
_x: PhantomData<T>,
}
pub struct B<'a, T: Tester> {
pub a: &'a A<T>,
}
impl<T> A<T>
where
T: Tester,
{
pub fn run(&self) {
let to_add = B { a: self };
}
}
Ignore the PhantomData
, that's just a dummy to make a struct compile that has an unused generic.
The to_add
object now has the lifetime of the &self
, so if you try to store it somewhere externally or pass it into a thread or something similar, it will tell you that this creates a problem with its lifetime. But of course that all depends on your usecase.
type A struct {
b *B
}
type B struct {
a *A
}
This construct, in Rust, is almost impossible. It's called a self-referencial data structure and cannot be managed by Rusts borrow checker. In its simpler form, you can use Arc
/Rc
to each other, which will create a memory leak (which is somewhat solveable with Weak
, but again, many thoughts have to be put into who owns it then). In its more complicated form, you need to use raw pointers, Pin
and unsafe
.