How to design to keep types inferrable?

It is not clear to me

  1. Whether you have two, or that was just for the MWE and you have more matrices, or even a large number.
  2. If all of them are of the same type.

If they are the same type, you can use a T<: AbstractVector{<: AbstractMatrix} for mats, which could ideally be a concrete type. This can cope with a large number of matrices.

If they are of a heterogeneous type, but not too many of them, you could use a Tuple.

If solve is inherently not type stable, you could perhaps break it up into functions so that some components are. But I second @jameson’s point: not everything can and need to be type stable to be fast. Occasional high level dynamic dispatch is very useful, eg look at the implementation of \ for matrices. Did you actually benchmark your code and establish that dynamic dispatch is a bottleneck?