In C++, if there weren't automatic destructor calls, you could still clean things up manually with a pseudo-destructor call, x.~T(), where T is the type of x.
In C, there are no (user-defined) generics, so you always know the concrete type of x, so you know whether it needs to have a destructor called and what the name of that destructor is.
In Zig, how would generic code create an instance of a generic type T that may or may not need to have a destructor called, ie. how do you know if you need to use defer and what the deferred expression should be? How would tooling be able to check that destructors were called if there is no special way of marking that a destructor exists?