-
Notifications
You must be signed in to change notification settings - Fork 10.5k
[Sema] Disallow override of dynamic Self return with non-dynamic. #12495
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 |
I think this change is correct, however I think it's worth digging a bit deeper here. If I override a method and the override has a completely unrelated return type from the base method, we flag that as an error already. So why is dynamic Self different here? Are we stripping off dynamic Self in the below logic when we go to match the return types? I think it would be better if we ensure that a dynamic Self mismatch is handled just like any other return type mismatch, and then add back the current broken behavior as a special case for when the language version is not 5. |
I see, so adjustFunctionTypeForOverride() substitutes the DynamicSelfType with the concrete Self type, and this happens before we check for matching types. What if it didn't do that? We already allow overrides to return a subtype of the base method eg,
What if Remember that
You're going to end up checking if Similarly, Also this should work too, where the override returns Self but the base method does not:
You should add tests that cover all of these cases in both -swift-version 4 and -swift-version 5 modes. |
@@ -1,4 +1,4 @@ | |||
// RUN: %target-typecheck-verify-swift | |||
// RUN: %target-typecheck-verify-swift -swift-version 5 |
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.
You need to test the old behavior in test/Compatibility/self.swift or similar, too.
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!
test/type/self.swift
Outdated
|
||
// SR-695 | ||
class Mario { | ||
func getFriend() -> Self { return self; } // expected-note{{overridden declaration is here}} |
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.
The semicolon is not needed here
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.
Yep! In my defense, it's copy-pasted from the original issue sample code.
I think you mean
In short, I'm not seeing the win here. :) |
Ok in that case, go ahead and keep your current approach. Please add a comment explaining that dynamic Self is stripped out, so must be checked explicitly, and add test cases for the various cases I talked about above. |
…ubclass unless that subclass is final.
Did those things, thanks! @swift-ci Please smoke test |
... Unless the subclass where the override occurs is final. Because this change causes previously working code to fail to compile, this new diagnostic is only enabled in swift 5 mode.
(There are examples of this pattern in the existing tests, e.g. test/stdlib/TestMeasurement.swift baseUnit(), which continues to build without problems thus serving as tests for the "only swift 5 mode" portion of this change.)
Resolves SR-695.