Marry Christmas to you all.
There are two different motivations lead to this proposal. One is in this existing proposal:
Me, and the author of the post above wanted to have a way to say "this object cannot be dropped unless you have done the check that it is a good time to drop it".
My precise challenge is that the object may have active reference leaked so it may not in a safe status to be dropped. To write unsafe code correctly, we have to check the status to ensure the object does not have active references.
One possible solution is like the proposal suggested, introduce a "NoDrop" marker trait, but I have another idea here. This lead to my second motivation.
Sometimes the IDE can help you generate some stub code like the following:
impl MyTrait for MyType {
fn my_method() { todo!() }
}
This is usually a good start. The problem is that the compiler don't prevent you from calling it before you implement it. Then if you have a whole set of such things (just give a real life example, you are implementing a serde
serializer, and there are 20 methods to implement), and forgot one of them, you have to wait for the test to figure out you have missed something.
The proposal
I propose to have an attribute #[do_not_call]
to annotate the methods that are not ready to be called, or designed not to be called. In this way, to achieve the "NoDrop" requirement we write
impl Drop for MyType {
#[do_not_call]
fn drop(&mut self){}
}
This should prevent the following:
- Any explicit call to the
drop
method that need to be generated, includes closures that were not called - Writing any code that will need a drop clue on an object of
MyType
being generated - Turning the object into a
dyn Drop
since this prevents the compiler to check if adrop
call will reach the implementation - Obtaining the
fn
pointer
Except the second point (which specific to the Drop
trait), the other points applies to all other such annotated methods.
However this annotation should not:
- prevent access via unsafe code
- prevent the trait bound checks being successful
- prevent other type of objects of the same trait being turned into trait object
Optionally, we can allow custom error messages
impl MyTrait for MyType {
#[do_not_call("This is not yet implemented")]
fn my_method() { todo!() }
}