Support Rc<RefCell<T>> as receiver type

I want to have below design, it only return User a Rc<RefCell> object, then user operate on that object by API provided by T

struct MyStruct {
     val: u8,
     relate: Opition<Rc<RefCell<MyStruct>>>
}

impl MyStruct {
    fn new() -> Rc<RefCell<Self>> {} // always return Rc<RefCell<T>>
    
    fn something_to_compute(self: &Rc<RefCell<Self>>) {} // does not support by compiler now
}

I would like to compiler to support Rc<RefCell> as receiver, and I think it can be done by coerce to &*self.borrow() in this case.

You can move the RefCell into MyStruct if it never makes sense to not have it without RefCell.

Yes, we can do that as you mentioned, but it takes more boilerplates to inside the api codes. See the example of my idea below, compare the the codes in getter and setter. If there is no subtle safety issue to do this in compiler, I would like to write a RFC for this. So would like to discuss the details

put RefCell inside struct

assume support receiver of Rc<RefCell<T>>

There is an existing arbitrary-self-types feature that expands what can be used as a receiver more, but it requires—recursively—that the receiver deref to Self or is a raw pointer of Self, which RefCell doesn’t satisfy. Note that this doesn't do any deref automatically, even if it were extended to support your proposed signature you would need to *self.borrow(); in the body still.

Hi, do you have a link to the RFC

There is no RFC, just a tracking issue, which doesn't actually describe much about it:

You can change self by other name, such as this.

As for me, this is very strange to have self: Wrapper<Self>

Issue can be found here:

I agree with all comments about not to implement this "feature". I strongly believe, that using of self: Wrapper<Self> comes from bad api design.

In your code, you have wrapper and you says, that this is only way to create this struct. This is true, but struct must not to know about its container. This is mistake.

You can fix this by creating MyStructManager, that creates Rc<RefCell<>> and can preform special operations over container wrapper. But I think, that this is not what you really want

P.S. Last update is about 2017 year on arbitary_self_types branch

You can also store a Weak<RefCell<T>> using Rc::new_cyclic and upgrade it when necessary. But this wastes a word of storage.

from user perspective, use the name “this“ still requires calling syntax T::something, instead of T.something

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.