One proposal for the above, is to allow writing
trait ItemConsumer<T> {
fn consume(&mov self, &mov T);
}
implementations can then write
impl ItemConsumer for MyType {
fn consume(&mov self, t: &mov T){
if condition {
move self;
} else {
move t;
}
}
}
The above desugar to the normal &mut form, but the return type have some additional type:
enum MovingStatus<'a, T> {
Mutated(&'a mut T),
Moved
}
trait ItemConsumer<'a,'b,T> {
fn consume(&'a mut self, &'b mut T) -> (MoveStatus<'a, Self>, MoveStatus<'b, T>,());
}
impl trait ItemStatus<'a,'b,T> for MyType {
fn consume(&'a mut self, t: &'b mut T) -> (MoveStatus<'a, Self>, MoveStatus<'b, T>,()){
if condition {
(Mutated(self),Moved,())
} else {
(Moved, Mutated(t), ())
}
}
}
The following calling site code
let mut consumer:ItemComsumer<i32> = ...
...
let mut i= 10;
consumer.consume(i);
desugar to
let mut consumer:ItemComsumer<i32> = ...
...
let mut i= 10;
match consumer.consume(i) {
(Moved,Moved,_) => { drop(consumer); drop(i) },
(Moved,_,_) => { drop(consumer); }
(_,Moved,_) => { drop(i); }
_ => {}
}
As all the above are just syntactic sugar, and the desugared trait is object safe, the original trait should be object safe as well.
The above code assumes all the values are gone at the same time. We will need more syntactic structure to allow the calling site to check whether the values are alive.