-
Notifications
You must be signed in to change notification settings - Fork 10.5k
[Typechecker] Fix a crasher involving RawValue not being Equatable #27050
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 |
@swift-ci please smoke test |
Hah, I found another bug. Consider this example: struct S : ExpressibleByStringLiteral {
init(stringLiteral: String) {}
}
enum E: S {
case a
typealias RawValue = S
init?(rawValue: Int) { self = .a }
var rawValue: Int { 0 }
} This will cause the same crash in the verifier, but can be fixed if you remove the After doing some digging, it appears that this is happening because in We shouldn't be attempting to do this here if we have an explicit witness. In fact, we are correctly detecting the witness mismatch (due to I have tweaked the code to only derive it if we don't explicitly have a declaration, but let me know if you think there's a better way to handle it. I don't know if this needs to be special cased for |
If an enum has an explicit raw type, we should probably ban having the RawRepresentable conformance using a different type. But that's technically source-breaking if anyone does something this wacky. |
Yeah, I wonder how many people are actually doing that. I don't think there's any benefit if an enum inherits from type Anyway, as long as it don't crash the compiler it's probably fine to leave it as is for now :-) (but yeah, maybe we should revisit that in the future). |
Strictly speaking if it's an |
Running a quick test to see if anything's broken and then I'll kick off source compat. @swift-ci please smoke test |
EDIT: Ah, this is because the |
@swift-ci please smoke test |
@swift-ci please smoke test |
@swift-ci please test source compatibility |
@swift-ci please test |
@swift-ci please test source compatibility |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
Failure on macOS is because SwiftSyntax is generating an enum case called I think this is also an improvement, because we already do the same for: enum Foo: RawRepresentable {
typealias RawValue = Int
case rawValue // error: candidate is not a variable
} @slavapestov do you mind giving this PR another look? Do you have any suggestions? The change in |
Wasn't this supposed to be filtered out because cases are static members and not instance members? In your other case there's no way to synthesize a |
I haven't added any filtering logic - at the moment its quite simple as it's only doing a name lookup to see if a declaration already exists before deciding whether we should derive a requirement or not. In this case, there's a lookup to check 'rawValue' but it doesn't check whether its an enum case or an instance property. Perhaps the check needs to be smarter -
What do you think? Is there a better way to do this? |
auto rawValueInit = | ||
DeclName(ctx, DeclBaseName::createConstructor(), {ctx.Id_rawValue}); | ||
auto doesNotHaveRawValue = ED->lookupDirect(ctx.Id_rawValue).empty(); | ||
auto doesNotHaveRawValueInit = ED->lookupDirect(rawValueInit).empty(); |
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.
lookupDirect
isn't necessarily correct anyway, since that won't look into extensions. If you go through the normal qualified lookup path maybe we'll get the synthesis we need anyway.
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.
Hmm I thought it did when I looked at the implementation, but alright, I'll do it the other way!
It's definitely not okay to regress RawRepresentable synthesis when there's a case called |
Sure, let me do this another way then because only name lookup isn't going to work here if we want to fix the above scenario. |
This code was crashing because the
RawValue
did not conform toEquatable
.The diagnostic for this was in
diagnoseConformanceFailure()
but we didn't hit that for this case (because we didn't fail to satisfy theRawValue
requirement), so I have moved it tocheckEnumRawValues()
which seems like a better place for it anyway.Resolves SR-6897.