Some parts of the compiler pipeline perform an early toString() conversion of the arguments of a diagnostic (or, at times, of the whole diagnostic itself). This can be regarded as a bad practice, as it makes it impossible to exploit the info carried by a diagnostic argument at a later point.
Main examples of this practice:
1) Parser: instead of passing the 'expected' token as a diagnostic argument, it first converts the token into a String and then used this string representation of the token as an argument of the diagnostic.
2) Resolve: a lot of resolution diagnostics actually rely upon the fact that some arguments are strings whose format adhere to some rule. E.g. the diagnostic 'cant.apply.symbol' accepts two String arguments corresponding to the argument list of the expected/found method. Those String are formatted inside the code of Resolve (so that parens surrounding the arguments are inserted, and angular brackets for type-parameters are added if needed).
3) Modifiers (such as 'public', 'private', etc.) are often converted to String they have to be passed as arguments on to a diagnostic. It would be better to keep the modifiers as instances of the class Name, so that they can be distinguished from all other ordinary Java Strings (and, eventually, rendered in a different way by a diagnostic formatter).