(1/2) One problem with zero-cost abstractions (I'm primarily thinking about #Rust, but other things qualify too — e.g. macros and inline functions in C) is that they are hard to reverse engineer (that includes writing a decompiler). By definition, abstractions are zero-cost when high-level semantics get compiled away and don't result in a different code compared to a manual low-level implementation.
(2/2) Furthermore, some things in higher-level languages are "descriptive not prescriptive", e.g. Rust lifetime specifiers and Java generics (that work via type erase at compile time), that only serve to enforce internal invariants of the high-level code and so don't influence the generated machine code at all.
That also makes me think a comparison to Java generics may help people grok lifetimes, because a common confusion among Rust beginners is
"what do these <'a> &'a things in function signatures actually _do_?"
The answer is that they, much like Java generics, don't change/influence what your code compiles to, but let/help you enforce type/memory safety.