From the paper:
The most straightforward approach is unaware cancellation, where a task has no opportunity to
react to being cancelled. This approach is taken by Rust in both Tokio and Smol. In Rust, cancellation
essentially means never executing a coroutine again after it has yielded. With a direct handle on
the coroutine, this simply means not polling the coroutine, or explicitly dropping it.
Maybe I'm misunderstanding this, but at least with Tokio, aborting a task causes it to be stopped and dropped at the next await point. Also, in Rust, the conventional way to cancel a future is to drop it.
By dropping the future, you are signaling to it that it has been canceled. A future can respond to this by implementing Drop, which gives it an opportunity to do whatever it wants (usually some kind of cleanup but it can go as far as making blocking database calls if it wants to).
Sure, some other languages work by throwing some kind of exception that bubbles up, or you can check a cancellation token or abort signal or whatever to see if the task is canceled. Using Drop is just another way to accomplish the same thing.