Feature #20024
openSyntaxError subclasses
Description
There are many places around the Ruby ecosystem that handle syntax errors in different ways. Some provide highlighting, others provide recovery of some form, still more provide LSP metadata. In order to provide more rich information, most of them switch on the message of the error being returned, as in:
Within ruby/spec, specific error messages are required for these kinds of messages in order to support this implicit interface that syntax errors have a hidden type, which is only expressed through their message. For example:
https://github.com/ruby/spec/blob/c3206f644325c026fc5b700f0ea75ce9bd2e9d02/language/if_spec.rb#L323
https://github.com/ruby/spec/blob/c3206f644325c026fc5b700f0ea75ce9bd2e9d02/language/numbered_parameters_spec.rb#L31
https://github.com/ruby/spec/blob/c3206f644325c026fc5b700f0ea75ce9bd2e9d02/language/pattern_matching_spec.rb#L210
https://github.com/ruby/spec/blob/c3206f644325c026fc5b700f0ea75ce9bd2e9d02/language/rescue_spec.rb#L262
https://github.com/ruby/spec/blob/c3206f644325c026fc5b700f0ea75ce9bd2e9d02/language/yield_spec.rb#L196
It's not clear from these specs or from the parser itself which error messages are permanent/guaranteed versus which are changeable. Either way, relying on the error message itself as opposed to the type of the error is brittle at best.
I would like to suggest instead we implement subclasses on SyntaxError
that would allow tools that depend on specific syntax errors to rescue those subclasses instead of parsing the message. In addition to alleviating the need to parse error messages with regex, this would also allow for the possibility that the error messages could change in the future without breaking external tooling.
Allowing these to change would allow them to be potentially enhanced or changed by other tools - for example by providing recovery information or translating them.
This is particularly important for Prism since we are getting down to individual spec failures and some of the failures are related to the fact that we have messages like "Numbered parameter is already used in outer scope"
where the spec requires /numbered parameter is already used in/
. Even this case-sensitivity is causing failures, which seems like we're testing the wrong thing.