Heap integrity / reachability is a dynamic property of a running program, and so all the static solutions basically end up as half-measures. (I imagine this would include using macros, though I don't know exactly what you mean),
FWIW this is my experience - https://www.oilshell.org/blog/2023/01/garbage-collector.html
Take it with however many grains of salt, but I heard many static solutions proposed, and they're all "wrong" for the simple reasons in theory of computation.
Also, Rust's static memory management inherently clashes a bit with dynamic memory management. That's also a fundamental thing, and you can have a bazillion mechanisms to ameloriate it for some cases (which may be valuable), but the problem will still be there no matter what.
Rust already has precise heap allocations with Box and Rc/Arc without the need for GC. GC implies uncomputed heap allocation liveness deferring work until later.