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
[SR-510] case Foo = {!@#$!@#$}
compiles and drops the case
#43127
Comments
Comment by Jesse Rusak (JIRA) @dduan In the future, it'd be great if you'd assign the bug to yourself before starting work on it so there aren't multiple people trying to solve it. I've actually been working on this as well, and have a branch up here I was about to submit as a PR which solves the same issue in a different way: master...jder:diagnose-static-closures I think your solution might produce duplicate diagnostics in some cases, because parseExpr will emit the passed diagnostic and return nullptr for some errors. For example: enum Foo: Float { Now produces the "error: expected expression after '=' in 'case'" twice. |
Just for the record, when I submitted the PR, the status of this ticket was still "unassigned". That being said, jder (JIRA User), I like your solution better than mine. I'll close my PR. |
Comment by Jesse Rusak (JIRA) Thanks, Daniel. I didn't see your PR when I grabbed the ticket; sorry! |
Comment by Jesse Rusak (JIRA) PR here: #934 |
Comment by Erik Little (JIRA) Just as an aside: The way I came about discovering this bug was trying to concatenate another case with a string literal. Since I assumed the compiler would be able to reason that it was dealing with string literals. enum Test : String {
case First = "some string"
case Second = .First + " another string"
} |
Comment by Jesse Rusak (JIRA) Thanks, nuclearace (JIRA User) – I don't think the compiler currently has any notion of a "compile time constant" like that, though I believe it has been discussed as something desirable to add. |
Comment by Jesse Rusak (JIRA) PR being discussed here: #987 |
When the parser tries to parse an expression as the raw value of a enum case, it simply calls the function that parses all expressions. This function, parseExpr() , accepts a diagnosis from its caller. If it sees anything wrong in the expression, the diagnosis gets issued. parseExpr(), seeing that the expression starts with an "{", will call parseExprClosure() . The latter normally would attempt to parse an closure and complain if anything is wrong. However, if the variable CurLocalContext’s value is nullptr, which can be true in some valid situations, parseExprClosure() will skip the closure parsing entirely, consume the tokens until “}” and set a global error state for the parser. A nullptr gets propagate back up the call stack as the parsing result and parseExpr() never gets a chance to issue the diagnosis passed in for enum case raw value. This had been the cause of this bug: CurLocalContext is set to nullptr for enum raw values. So all we needed is to preempt the call to parseExpr() with a dummy context value. |
Environment
Apple Swift version 2.1.1 (swiftlang-700.1.101.15 clang-700.1.81)
Apple Swift version 2.2-dev (LLVM 3ebdbb2c7e, Clang f66c5bb67b, Swift 54dcd16)
Additional Detail from JIRA
md5: 33eddeb732f3259b9a84f18bc9c2048f
Issue Description:
The following compiles just fine:
but the actual
case Bob
is dropped from the AST entirely, as seen byswiftc -print-ast
:Even more interestingly, it doesn't matter what's inside the brackets. The following behaves identically:
And in fact, you can actually write this
case
anywhere, not just inside of enums:The only requirements seem to be that the characters inside the braces must be valid Swift source characters, so e.g. you can't put an apostrophe in there. And whatever's inside must pass the tokenizer, so e.g. string literals must be valid, and floating-point literals must be as well.
It also appears that the rest of the line past the closing brace is also discarded after tokenizing. Unless there's an open brace, which causes it to emit a few errors about closure expressions. And if this
case
is at the top-level, it actually discards the rest of the file as well, although a few keywords likebreak
andif
can trigger errors:This issue was first discovered by nuclearace (JIRA User), and a lot of the subsequent info was found by @mikeash.
The text was updated successfully, but these errors were encountered: