Inferring the capabilities of the function from the traits of the types of the arguments is similar to tracking effects. The function charges `drop<T>` when `x: T` goes out of scope, which is handled by the trait implementation. If Rust had a proper algebraic effects type system, you would be able to see this directly in the signature of the function (and even more, if the trait impls themselves had their effects tracked, you'd be able to see from the signature of the function the side effects of deallocation of its owned variables, like if `drop<File>` performs `io`).
The closest is linear types but even then drop isn't an effect but also a function you can call to allow not continuing the references
If you try treat memory as an effect you gain the need for several polymorphic effect type functions drop, forget, etc which map a type to the effect row charged by its corresponding Drop, Forget impl. Rust doesn't have that type system obviously.