The other issue is since there is no generic notion of a destructor, it isn't possible to write generic functions that destroy elements. If you call, say, replace_range on a list of strings, it will leak the replaced strings.
That's separate from the destructor for the entire list. It does mean that the code that removes an element from the list has to explicitly invoke the destructor for it - which is in agreement with using "defer" to explicitly invoking destructors for locals.
> The other issue is since there is no generic notion of a destructor, it isn't possible to write generic functions that destroy elements.
But you can have a generic notion of a destructor - that's orthogonal to whether destructors are invoked explicitly. You just have an interface (or trait, or whatever it's called) that exposes a destructor method for a type.
It can, it's just more explicit about it. In a language with destructors, you'd do RAII here by having a list destructor that cleans up each element in turn. In a language with defer, the same destructor becomes a regular function that you'd invoke in the deferred expression.