-
Notifications
You must be signed in to change notification settings - Fork 10.5k
sema: reject enum element call with payloads as compile-time constant #41796
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
Conversation
@swift-ci please smoke test |
@@ -1146,7 +1146,9 @@ bool NotCompileTimeConst::diagnose(const Solution &solution, bool asNote) const | |||
// Referencing an enum element directly is considered a compile-time literal. | |||
if (auto *d = solution.resolveLocatorToDecl(locator).getDecl()) { | |||
if (isa<EnumElementDecl>(d)) { | |||
return true; | |||
if (!d->hasParameterList()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please factor the checks out of the fix, as I mentioned on the precious PR - a fix shouldn’t be created if it’s not going to be diagnosed…
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will do in a follow-up PR! I'm still figuring out how to refactor this code...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I spent some time thinking about this and it's going to be hard to properly detect that argument is non-const because sometimes e.g. leading-dot syntax the overload is resolved long after argument conversion
constraint has been simplified (result gets bound, then base gets bound and only after that the member is resolved). I think one way to archive it might to be add a new flag to a type variable e.g. const required
which is going to get associated with "argument" type variable and get propagated to the base of the chain and from it to the member.
Also note that the check you added here is incorrect because NotCompileTimeConst
would get a base expression as a locator but the leading-dot syntax chain this base belongs to might have more members than just one.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also not that the check you added here is incorrect because NotCompileTimeConst would get a base expression as a locator but the leading-dot syntax chain this base belongs to might have more members than just one.
Thanks! Not sure I understand the situation you are describing here. Could you give a test case?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, something like:
enum E {
case a
case b(Int)
}
using .a.b(42)
is going to get accepted because the the base is just .a
and .b(42)
is not checked.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For this following case:
$cat /tmp/t.swift
enum E {
case a
case b(Int)
}
func foo(_ c: _const E) {
}
foo(.a.b(3))
foo(E.a.b(3))
I got:
$../build/Ninja-RelWithDebInfoAssert/swift-macosx-x86_64/bin/swift-frontend -typecheck /tmp/t.swift
/tmp/t.swift:8:6: error: enum case 'b' cannot be used as an instance member
foo(.a.b(3))
~^
E
/tmp/t.swift:9:7: error: enum case 'b' cannot be used as an instance member
foo(E.a.b(3))
~~^
E
/tmp/t.swift:9:9: error: expect a compile-time constant literal
foo(E.a.b(3))
^
They seem to be rejected.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about this one:
enum E {
case a
case b(Int)
var c: E { .b(42) }
}
func test(_: _const E) {
}
test(.a.c)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah, this one seems to be wrongly accepted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Filed rdar://90210674
rdar://90168664