Change InferType() to an abstract method and implement for every ILInstruction.
With this change, we now always have enough information to create a variable of an appropriate type to store the result of evaluating the instruction.
This previously was not the case for instructions producing "other value type", for which the stacktype-based fallback incorrectly produced `object`.
SplitTypeParameterCountFromReflectionName allocated the digits after
the backtick only to feed int.TryParse and discard them, and the
TopLevelTypeName constructor cut the name part twice for generic
types (once at the dot, again at the backtick), dropping the first
cut. Both run for every generic reflection name parsed, e.g. for
typeof-valued attribute arguments and string-switch metadata. The
arity is now parsed in place with a digit loop (netstandard2.0 has
no span int.TryParse) and each final string is cut exactly once.
The digit loop only accepts plain ASCII digits, so suffixes like
`+1 that int.TryParse tolerated are now rejected; such names are not
legal reflection names. New unit tests pin the parse edge cases.
Assisted-by: Claude:claude-fable-5:Claude Code
While support for multi-module assemblies isn't fully working yet; it is clear at this point that we want
to treat each module in a multi-module assembly separately for the purposes of the type system.