Skip to content

Don't fix access of an 'open' override in a 'public' extension #22188

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

Merged
merged 3 commits into from
Jan 29, 2019

Conversation

jrose-apple
Copy link
Contributor

@jrose-apple jrose-apple commented Jan 28, 2019

This is reasonable to diagnose with a warning, but dropping the 'open' down to 'public' isn't the right fix, because now it's not a valid override. The declaration has to get moved to another extension instead, or the extension has to not set a default access level.

This turned out to be a source compat issue because the same logic that emits the fix-it also updates the access of the member, which then resulted in "must be as accessible as the declaration it overrides" in the same build. It's not immediately clear what caused this; probably something's just being validated in a different order than it was before. The change makes sense either way.

rdar://problem/47557376
rdar://problem/28493971

@jrose-apple
Copy link
Contributor Author

@dingobye, you'd also be a good person to review, since you made changes here recently!

@swift-ci Please test

@jrose-apple
Copy link
Contributor Author

@swift-ci Please test source compatibility

open override func method() {}
}
public extension OverrideInExtensionSub {
open override func accessWarning() {} // expected-warning {{'open' modifier conflicts with extension's default access of 'public'}}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@brentdax How does this sound? It's still vague about how it's going to be treated for now, but at least it sounds like a problem.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Much better!

@jrose-apple
Copy link
Contributor Author

[waiting for the previous tests to finish before starting more tests, since the only thing that changed was the diagnostic message]

// (which can happen with Objective-C extensions). That can lead to a
// diagnostic fight between this and "declaration must be as accessible
// as the declaration it overrides".
if (!D->getAttrs().hasAttribute<OverrideAttr>()) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apart from override, there might be other cases where fixit is inappropriate.

Here is an example I can figure out so Far:

public protocol Proto {
  func foo()
}

public struct S : Proto {
}

internal extension S {
  public func foo() {}        // fixit suggests removing 'public', but it fights against 'type_witness_not_accessible_proto' which suggests adding 'public' to foo()  :-/
}

Copy link
Contributor Author

@jrose-apple jrose-apple Jan 29, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hrm. Maybe it'd be better to just remove the fix-it altogether. It's hard to tell whether something's trying to satisfy a requirement. What do you all think?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree! It is always better to be quiet than misleading.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We will still have the fighting cases for now in the error cases, but, well…that's not a regression.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, that is an orthogonal issue. 'type_witness_not_accessible_proto' keeps warning even though foo() is already declared public.

Before: declaring a public instance method in a private extension
After: 'public' modifier conflicts with extension's default access of
       'private'
This is reasonable to diagnose with a warning, but dropping the 'open'
down to 'public' isn't the right fix, because now it's not a valid
override. The declaration has to get moved to another extension instead,
or the extension has to not set a default access level.

This turned out to be a source compat issue because the same logic
that emits the fix-it also updates the access of the member, which
then resulted in "must be as accessible as the declaration it
overrides" in the /same/ build. It's not immediately clear what caused
this; probably something's just being validated in a different order
than it was before. The change makes sense either way.

Stepping back, it's weird that a warning would change how the compiler
saw the code, and while we could check for 'override' explicitly, we
can't know if the member might be satisfying a protocol requirement.
Better to just not guess at the right answer here.

rdar://problem/47557376&28493971
Warnings should not result in early exits because we might end up
missing an error!
@jrose-apple
Copy link
Contributor Author

@swift-ci Please test

@jrose-apple
Copy link
Contributor Author

@swift-ci Please test source compatibility

@swift-ci
Copy link
Contributor

Build failed
Swift Test Linux Platform
Git Sha - bf66ab2ab0be00320d89254f8791d9f6266344a9

@swift-ci
Copy link
Contributor

Build failed
Swift Test OS X Platform
Git Sha - bf66ab2ab0be00320d89254f8791d9f6266344a9

Copy link
Contributor

@dingobye dingobye left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@jrose-apple jrose-apple merged commit de93ba0 into swiftlang:master Jan 29, 2019
@jrose-apple jrose-apple deleted the open-your-heart branch January 29, 2019 18:45
jrose-apple added a commit to jrose-apple/swift that referenced this pull request Jan 29, 2019
Don't fix access of an 'open' override in a 'public' extension

rdar://problem/47557376&28493971
(cherry picked from commit de93ba0)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants