Hacker News new | ask | show | jobs
by Ericson2314 2226 days ago
I've been complaining for a long time that `Drop` is fundamentally wrong. Rust's "just write a new function" fixed C++'s "construction is mutation of location", but Rust's Drop makes the same mistakes as C++: destruction needs to be for consuming data, not borrowing it and mutating it.

Now, we can't just do

  drop<T>(T)
because of DSTs, so we we'll need a new type of consuming reference. And the dual to that, an initializing reference, would also solve the problem of creating DSTs with preallocated memory.

Now both could use MaybeUninit, but it would be better to just have types that vary with the CFG, so one can insure that no matter how one get to point b, the memory is now initialized.

1 comments

> but Rust's Drop makes the same mistakes as C++: destruction needs to be for consuming data, not borrowing it and mutating it.

but Rust's drop isn't for that purpose. It's not for the actual cleanup of the struct and its children it is for additional cleanup before the children are deleted. So it has to be mutable. The compiler synthesizes the "delete children" code.

(I don't understand your point about drop<T>)

> It's not for the actual cleanup of the struct and its children it is for additional cleanup

I think that purpose is the tail wagging the dog, an explanation of the current method rather than an actual requirement.

The simpler thing to do is just have drop on the aggregate calls drop on the fields, just as new on the aggregate can call new on the fields.

This does not seem simpler to me, this seems easier to mess up. The most common use case is dropping all fields.

Furthermore, you still have to special-case Drop because now you have to support destructive destructuring for Drop types because it isn't allowed anywhere else.

And plus, if you forget to do this, the failure mode is a stack overflow.

The current design is absolutely based on practical requirements here, it is not a retroactive justification. This is by and large how destructors work, for good reason.

> (I don't understand your point about drop<T>)

Ah I meant to write the function signature:

> fn drop<T>(T);

contrasted with the:

> fn drop<T>(&mut T);

that we have today