New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Confusing rescue
syntax edge case
#10660
Comments
This syntax is there so you can do: property rescue : String You can see that for that to compile, we have to allow that syntax. That said, we could probably disallow that syntax when it happens inside method definitions. |
Assignment This works, though: rescue : String = "foo"
p!(rescue) @asterite I'd expect restricting the syntax to specific locations to be somewhat fuzzy. For example, outside of method definitions, it could either be a valid macro argument, but also a mistyped rescue clause. |
Hm, maybe that's not actually true. A mistyped rescue clause can't be in a call argument. So it can probably be determined at syntax level. |
You cannot do this to any keyword even if the variable declaration is legal: rescue : String = "foo"
p!(rescue) # okay
def : String = "foo"
p!(def) # Error: expecting any of these tokens: IDENT, CONST, `, <<, <, <=, ==, ===, !=, =~, !~, >>, >, >=, +, -, *, /, //, !, ~, %, &, |, ^, **, [], []?, []=, <=>, &+, &-, &*, &** (not 'EOF')
begin : String = "foo"
p!(begin) # Error: unterminated call
class : String = "foo"
p!(class) # Error: expecting token 'CONST', not ')' Because of this I'd argue we should disallow using any keyword as the name of a local variable. |
This works with many keywords, actually. Some don't even require any convincing to be parsed as a variable declaration: type = "foo"
p! type
union = "foo"
p! union
forall = "foo"
p! forall
do : String = "foo"
p!(do) Keywords are always context specific. Disallowing any keyword as a variable name in any context would be very restricting and not reasonable I think. It would definitely be a major breaking change. I suppose restricting the use of names that could only be declared via explicit variable declaration (such as |
Discussion
Much like Ruby, Crystal allows
rescue
to have a variable and/or type:But what about this?
Surprise! This doesn't rescue anything. Instead it just declares a local variable named
rescue
.This is very unexpected behavior (at least to me). It doesn't help that
rescue
usually still has the syntax highlighting of a keyword, rather than a variable. This could even be dangerous, if it lets someone slip code past a code review that appears to handle an error but actually doesn't.I propose that this becomes a syntax error. It seems unlikely anyone is purposefully using the current behavior.
The text was updated successfully, but these errors were encountered: