-
Notifications
You must be signed in to change notification settings - Fork 10.5k
[NameLookup] Swift 4 compatibility hack for cross-module var overloads in generic type extensions #18488
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
[NameLookup] Swift 4 compatibility hack for cross-module var overloads in generic type extensions #18488
Conversation
cc. @jrose-apple & @DougGregor. I know it's pretty late in the release cycle, but would it be possible to cherry pick this to 4.2? |
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.
This change LGTM!
I think we've missed the window for Swift 4.2, particularly with changes that could affect source compatibility. This looks good for master, though, thanks! |
@swift-ci Please test |
Build failed |
That's what I feared – thanks for confirming! Can you confirm whether or not we want cross-module property overloading in the general case for Swift 5 mode (bearing in mind it being potentially source-breaking)? If so, I'm happy to work on that as a follow-up. |
Also looks like the OS X buildbot is failing consistently with:
|
Build failed |
cc @clackary, @shahmishal |
This issue should be resolved, we reverted the commit which caused the issue. |
@swift-ci test |
@hamishknight Maybe this warrants some evolution discussion, if not a full proposal just a thread. I'd like to understand the new rules in 4.2 as well as the compatibility hacks you added to remain compatible with 4.1, and come up with a model that's simple and consistent. It's OK to have minor source breaks in -swift-version 5 mode; we just have to ensure the new behavior makes the most sense going forward. |
lib/AST/NameLookup.cpp
Outdated
// This is due to the fact that in Swift 4, we only gave custom overload | ||
// types to properties in extensions of generic types, otherwise we | ||
// used the null type. | ||
if (!ctx.isSwiftVersionAtLeast(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.
What if we instead said that in Swift 5, all properties get a real overload signature? Why should properties be any different from methods in this regard?
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.
@slavapestov By "real overload signature", do you mean that two properties of different type would always be allowed to overload each other? I'm not mad on this idea, as IMO it would encourage tricky code that relies on overload resolution by "return type", which I believe is something we want to discourage (listed in the API design guidelines under "General conventions" > "Methods can share a base name").
However given that we already allow what would otherwise be re-declarations across module boundaries for both properties and methods, I personally think that it seems reasonable to allow different typed properties to overload across modules (as the shadowing behaviour is otherwise a bit unintuitive).
Though whatever we choose, I agree we should definitely make the behaviour consistent in Swift 5 mode!
@slavapestov Thanks for the suggestion! I'm happy to open to an evolution thread to discuss this change (and the more general behaviour going forwards) in more detail – I'll try and do so before the end of the day. |
Opened an evolution thread: https://forums.swift.org/t/should-we-allow-cross-module-overloading-of-variables-and-properties/15096 |
Just resolved a merge conflict – is this good to merge? I'll file a JIRA to track the Swift 5 mode changes. |
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.
Looks good, can you fix the test case and rebase and then we'll merge?
|
||
func useString(_ str: String) {} | ||
|
||
// In Swift 5, we currently consistently reject cross-module property overloading. |
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 should have test errors that expect errors in that 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.
Thanks Slava, I've gone ahead and made that change.
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.
Did you not push it yet?
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 did push, and it shows up on GitHub for me (HEAD at c54ab4d). Should I re-rebase and try to push again?
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'm looking at this part:
// In Swift 5, we currently consistently reject cross-module property overloading.
// FIX-ME: This seems reasonable to permit.
Is there a test for this behavior?
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.
@slavapestov Apologies, I realise now that the comment isn't particularly well-worded. When I say "reject cross-module property overloading", what I really mean is "properties from this module always shadow properties from the other module, and therefore the other module's properties never show up in the overload set" – which is what the tests in that file are testing.
Your original comment prompted me to add expected-errors in order to ensure the other module's properties didn't show up in the overload set (previously I was just testing that a bare reference wasn't ambiguous).
I'll edit the comment in the test file to clarify things.
c54ab4d
to
be88c40
Compare
…s in generic type extensions In Swift 4, we only gave custom overload types to properties defined in extensions of generic types, using the null type for any other var decl. This meant that a property defined in such an extension would never shadow a property not defined in such an extension. As a result, this permitted cross-module overloads of properties of different types on generic types in certain cases. This patch adds an exception to the shadowing rules for properties defined in generic type extensions under Swift 4 mode. Permitting cross-module property overloads in the general case would also be source breaking (causing ambiguity errors), so this can be handled in a follow-up Swift 5 mode PR if desired. Resolves SR-7341.
be88c40
to
1e764cc
Compare
@swift-ci Please test |
@swift-ci Please test source compatibility |
Build failed |
Build failed |
Thanks Slava! I've filed a JIRA for the Swift 5 mode changes: https://bugs.swift.org/browse/SR-8619. |
@slavapestov Do you think this would be worth cherry picking to the 4.2 branch now that it's taking changes for a potential 4.2.1 release? IMO the risk should be minimal. |
There's no harm in opening a PR; final decision rests with @tkremenek though. |
Opened a 4.2 PR: #19223 |
In Swift 4, we only gave custom overload types to properties defined in extensions of generic types, using the null type for any other var decl. This meant that a property defined in such an extension would never shadow a property not defined in such an extension. As a result, this permitted cross-module overloads of properties of different types on generic types in certain cases.
#15412 changed the overload type logic to produce more consistent overload types, but in doing so inadvertently caused a source breakage by rejecting such cross-module property overloads (as we now always consider the property in the current module to shadow the imported one).
This PR adds an exception to the shadowing rules for properties defined in generic type extensions under Swift 4 mode. Permitting cross-module property overloads in the general case would be source breaking (causing ambiguity errors), so this can be handled in a follow-up Swift 5 mode PR if desired.
In addition, this PR adds a test case for an
AnyObject
lookup ambiguity error introduced by #15412.Resolves SR-7341.