Created from PR.
Motivation
-
It allows to avoid required wrapper structs. It is ugly and wrapper structs don’t derive traits automatically.
Before:
use std::cell::UnsafeCell;
use std::rc::Rc;
struct Entity {
}
impl Entity {
fn process(&mut self) {
}
}
#[derive(Clone)]
struct EntityWrapper(Rc<UnsafeCell<Entity>>);
impl EntityWrapper {
fn entity_mut(&self) -> &mut Entity {
unsafe {
&mut *self.0.get()
}
}
}
After:
use std::cell::UnsafeCell;
use std::rc::Rc;
struct Entity {
}
impl Entity {
fn process(&mut self) {
}
fn entity_mut(self: &Rc<UnsafeCell<Self>>) -> &mut Self {
unsafe {
&mut *self.get()
}
}
}
- Allows to express unavailable right now things. Write GC-like code without GC.
use std::cell::UnsafeCell;
use std::rc::Rc;
struct Sound {
}
impl Sound {
fn play(&self) {
// Implementation details
}
fn play_with_continuation<F>(&self, continuation: F)
where F: FnOnce()
{
// Implementation details
continuation();
}
}
struct Game {
first_sound: Sound,
second_sound: Sound,
}
impl Game {
fn mut_self(self: &Rc<UnsafeCell<Self>>) -> &mut Self {
unsafe {
&mut *self.get()
}
}
fn play_sounds(self: &Rc<UnsafeCell<Self>>) {
self.mut_self().first_sound.play_with_continuation(move || {
self.mut_self().second_sound.play();
});
}
}
Detailed design
Allow self
be any type that parameterized with Self
:
* Rc<Self>.
* Iterator<Item=Self>.
Drawbacks
- More complex method resolving strategy.
- Requirement to make improvement to rustdoc.
Alternatives
Don’t do it.
Unresolved questions
- What to do with cases like:
- Disallow.
- Allow, but require use UFCS.
impl SomeStruct {
fn len(self: &Vec<Self>) -> usize {
// Implementation details
}
}