One idea I’ve been toying around with is some kind of general solver (i.e. SMT)-based shape inference. It’s unfortunately not that easy to propagate shapes in the general case - broadcasting is one significant example. However, there are lots of other annoying examples as well.
For example, torch.cat([a, b]) results in a shape that’s dynamic with the shapes of both a and b.
A solver-based shape inference would allow you to query whether a shape 1. could be dynamic, and 2. if it were dynamic, what the constraints on its shape would be.