gftea
April 22, 2023, 9:05am
1
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.
bjorn3
April 22, 2023, 12:54pm
2
You can move the RefCell
into MyStruct
if it never makes sense to not have it without RefCell
.
gftea
April 22, 2023, 3:00pm
3
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.
gftea
April 22, 2023, 7:48pm
5
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:
opened 08:52PM - 26 Sep 17 UTC
T-lang
B-unstable
C-tracking-issue
F-arbitrary_self_types
S-tracking-needs-summary
T-types
S-types-deferred
Tracking issue for `#![feature(arbitrary_self_types)]`.
This needs an RFC bef… ore stabilization, and also requires the following issues to be handled:
- [ ] figure out the object safety situation
- [ ] figure out the handling of inference variables behind raw pointers
- [ ] decide whether we want safe virtual raw pointer methods
## Object Safety
See https://github.com/rust-lang/rust/issues/27941#issuecomment-332157526
## Handling of inference variables
Calling a method on `*const _` could now pick impls of the form
```Rust
impl RandomType {
fn foo(*const Self) {}
}
```
Because method dispatch wants to be "limited", this won't really work, and as with the existing situation on `&_` we should be emitting an "the type of this value must be known in this context" error.
This feels like fairly standard inference breakage, but we need to check the impact of this before proceeding.
## Safe virtual raw pointer methods
e.g. this is UB, so we might want to force the call `<dyn Foo as Foo>::bar` to be unsafe somehow - e.g. by not allowing `dyn Foo` to be object safe unless `bar` was an `unsafe fn`
```Rust
trait Foo {
fn bar(self: *const Self);
}
fn main() {
// creates a raw pointer with a garbage vtable
let foo: *const dyn Foo = unsafe { mem::transmute([0usize, 0x1000usize]) };
// and call it
foo.bar(); // this is UB
}
```
However, even today you could UB in safe code with `mem::size_of_val(foo)` on the above code, so this might not be actually a problem.
## More information
There's no reason the `self` syntax has to be restricted to `&T`, `&mut T` and `Box<T>`, we should allow for more types there, e.g.
```Rust
trait MyStuff {
fn do_async_task(self: Rc<Self>);
}
impl MyStuff for () {
fn do_async_task(self: Rc<Self>) {
// ...
}
}
Rc::new(()).do_async_stuff();
```
This doesn't have an RFC, but we want to experiment on this without one.
See #27941.
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:
opened 08:52PM - 26 Sep 17 UTC
T-lang
B-unstable
C-tracking-issue
F-arbitrary_self_types
S-tracking-needs-summary
T-types
S-types-deferred
Tracking issue for `#![feature(arbitrary_self_types)]`.
This needs an RFC bef… ore stabilization, and also requires the following issues to be handled:
- [ ] figure out the object safety situation
- [ ] figure out the handling of inference variables behind raw pointers
- [ ] decide whether we want safe virtual raw pointer methods
## Object Safety
See https://github.com/rust-lang/rust/issues/27941#issuecomment-332157526
## Handling of inference variables
Calling a method on `*const _` could now pick impls of the form
```Rust
impl RandomType {
fn foo(*const Self) {}
}
```
Because method dispatch wants to be "limited", this won't really work, and as with the existing situation on `&_` we should be emitting an "the type of this value must be known in this context" error.
This feels like fairly standard inference breakage, but we need to check the impact of this before proceeding.
## Safe virtual raw pointer methods
e.g. this is UB, so we might want to force the call `<dyn Foo as Foo>::bar` to be unsafe somehow - e.g. by not allowing `dyn Foo` to be object safe unless `bar` was an `unsafe fn`
```Rust
trait Foo {
fn bar(self: *const Self);
}
fn main() {
// creates a raw pointer with a garbage vtable
let foo: *const dyn Foo = unsafe { mem::transmute([0usize, 0x1000usize]) };
// and call it
foo.bar(); // this is UB
}
```
However, even today you could UB in safe code with `mem::size_of_val(foo)` on the above code, so this might not be actually a problem.
## More information
There's no reason the `self` syntax has to be restricted to `&T`, `&mut T` and `Box<T>`, we should allow for more types there, e.g.
```Rust
trait MyStuff {
fn do_async_task(self: Rc<Self>);
}
impl MyStuff for () {
fn do_async_task(self: Rc<Self>) {
// ...
}
}
Rc::new(()).do_async_stuff();
```
This doesn't have an RFC, but we want to experiment on this without one.
See #27941.
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.
gftea
April 23, 2023, 6:10pm
9
from user perspective, use the name “this“ still requires calling syntax T::something, instead of T.something
system
Closed
July 22, 2023, 6:10pm
10
This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.