There are postponed RFCs for &move
. The idea of this is to let the function receives a &move T
reference have the right to drop the object.
If T
is Sized
, there is a way of doing it in today’s Rust:
fn drop_a_value<T>(obj: &mut Option<T>)
where
T: Sized
{
*obj = None;
}
This does not help when we want to use trait objects, because they are not Sized
.
So I am thinking instead of introducing something like &move
, we can actually make &mut Option<dyn Trait>
a proper trait object, and allow it to be a method receiver:
impl MyTrait for Whatever {
fn my_method(self: &mut Option<Self>,...) ...
...
}
Of cause, this method will need to check whether self
is Some
otherwise it will panic
. But the magic here is that when we write the following:
let foo: &mut Option<dyn Foo> = &mut Some(ConcretFoo::new());
we first construct an object of type ConcretFoo
, and then create a Option<ConcretFoo>
variant Some
. Then construct a vtable from ConcretFoo
's Foo
implementation, to put in the fat pointer foo
.
If we write
let foo: &mut Option<dyn Foo> = &mut (None as Option<ConcretFoo>)
It will create a None
variant, and then use the vtable for ConcretFoo
for the fat reference. Technically this is a “bare” vtable for a specific trait implementation, because it does not point to a real object.
The last case is
let foo: &mut Option<dyn Foo> = &mut None;
Intuitively, this will use the implementation of Foo
for !
, because there is no further constraint on the concret type can exist except that it must implement Foo
.
All above should be the same when use assignment. So the concret type the trait object points to will vary.
For consistancy, I would like to see &Option<dyn Trait>
can do the same thing.