You may be able to use a stack-allocated vector-like type (from heapless or smallvec or similiar).
But isn't this a problem in other languages (specifically C and C++) as well? If you have a working solution (or design) in another language, we can help you translate it to rust.
This just means that you need to implement a "heap" manually. Allocate a fixed-size buffer on the stack at runtime or in a properly synchronized static at compile time. Then use an implementation of Box/Arc which use a separate buffer instead of the global heap. The unstable Allocator API is intended for that use case, and all collections support it. However, the Allocator API is still subject to change, so you're probably better off using a custom fork of Box/Arc which implement similar functionality, like bumpalo does. heapless is a popular choice in embedded dev, but I haven't personally worked with it, so can't comment on its subtleties.
Of course, all of the above is valid assuming you have an upper bound on the size of your recursive structure, but you should have it anyway.