This resulted in a codegen error in C++ mode, because the generic
types were not defined in modules where calls requiring downcasts
were used (generating a downcast forces the inclusion of the full
definition of the involved types).
During the instantiation of a generic type A, some other generic
type B may be instantiated multiple times with different parameters.
We can think about each instantiation as a function call that should
temporary bind the parameter names to concrete types. The problem
with the existing implementation in semtypinst was that it was
performing this binding within a shared global table. In this sense,
it was executing the code as a programming language featuring only
global variables. In such a language, re-entrant functions cannot be
defined properly and hence this was leading to problems with similar
types. The solution is simple - just like we need to introduce stack
frames to handle re-entrant functions, we introduce a stack of type
bindings that are pushed and popped during the generic instantiations.
A more efficient implementation is possible by restoring the old
lifting ot tyGenericInvocation to tyGenericInst in liftTypeParam,
but this fix will suffice for now.
fixes#5087fixes#5602fixes#5641fixes#5570
Fixed the dot operator when used within return types (see tgenericdotrettype)
Fixed the matching of generic concepts aliases used with the implicit generics style
Previously it was not possible to use template arguments in template body as
the symbols were not resolved correctly leading to Error: undeclared
identifier: 'XX', eg.:
template defaultOf[T](t: T): expr = (var d: T; d)
echo defaultOf(1) #<- invalid identifier, but should output 0