Lazy type resolution for untyped

Note: An unresolved expression is an expression for which no symbol lookups and no type checking have been performed.

Since templates and macros that are not declared as immediate participate in overloading resolution it’s essential to have a way to pass unresolved expressions to a template or macro. This is what the meta-type untyped accomplishes:

  1. template rem(x: untyped) = discard
  2. rem unresolvedExpression(undeclaredIdentifier)

A parameter of type untyped always matches any argument (as long as there is any argument passed to it).

But one has to watch out because other overloads might trigger the argument’s resolution:

  1. template rem(x: untyped) = discard
  2. proc rem[T](x: T) = discard
  3. # undeclared identifier: 'unresolvedExpression'
  4. rem unresolvedExpression(undeclaredIdentifier)

untyped and varargs[untyped] are the only metatype that are lazy in this sense, the other metatypes typed and typedesc are not lazy.