I never tried Zig, but can’t you, instead defer the actual resource release, replace it with one which crash at compile time? This is a naive suggestion based on lousy inferences of features that seems highlighted in Zig, comptime and deffer.
compile time may help for some stuff but if you’re passing pointers to a function, you don’t know what will happen there. You might get a use after free or a double free.
Like with all languages, if you’re leaving default safety up to programmer convention, the programmer will let you down eventually. Rust, swift and any language where raw pointers are the exception not the rule (any GC, ref counted or borrowing language really), they all switch the defaults around so that you’re not dealing with memory management yourself unless you absolutely want to.