Skip to content

[Sema] Fix inappropriate diagnostics of access control for member declared in private extensions. #18105

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 1 commit into from
Jul 20, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 15 additions & 9 deletions lib/Sema/TypeCheckAttr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1511,15 +1511,21 @@ void AttributeChecker::visitAccessControlAttr(AccessControlAttr *attr) {
return;
}

auto extAttr = extension->getAttrs().getAttribute<AccessControlAttr>();
if (extAttr && attr->getAccess() > extAttr->getAccess()) {
auto diag = TC.diagnose(attr->getLocation(),
diag::access_control_ext_member_more,
attr->getAccess(),
D->getDescriptiveKind(),
extAttr->getAccess());
swift::fixItAccess(diag, cast<ValueDecl>(D), extAttr->getAccess());
return;
if (auto extAttr =
extension->getAttrs().getAttribute<AccessControlAttr>()) {
// Extensions are top level declarations, for which the literally lowest
// access level `private` is equivalent to `fileprivate`.
AccessLevel extAccess = std::max(extAttr->getAccess(),
AccessLevel::FilePrivate);
if (attr->getAccess() > extAccess) {
auto diag = TC.diagnose(attr->getLocation(),
diag::access_control_ext_member_more,
attr->getAccess(),
D->getDescriptiveKind(),
extAttr->getAccess());
swift::fixItAccess(diag, cast<ValueDecl>(D), extAccess);
return;
}
}
}

Expand Down
30 changes: 23 additions & 7 deletions test/Compatibility/accessibility.swift
Original file line number Diff line number Diff line change
Expand Up @@ -75,66 +75,82 @@ extension PrivateStruct {

public extension PublicStruct {
public func extMemberPublic() {}
fileprivate func extFuncPublic() {}
private func extImplPublic() {}
}
internal extension PublicStruct {
public func extMemberInternal() {} // expected-warning {{declaring a public instance method in an internal extension}} {{3-9=internal}}
fileprivate func extFuncInternal() {}
private func extImplInternal() {}
}
private extension PublicStruct {
public func extMemberPrivate() {} // expected-warning {{declaring a public instance method in a private extension}} {{3-9=private}}
private func extImplPrivate() {}
}
fileprivate extension PublicStruct {
public func extMemberFilePrivate() {} // expected-warning {{declaring a public instance method in a fileprivate extension}} {{3-9=fileprivate}}
fileprivate func extFuncFilePrivate() {}
private func extImplFilePrivate() {}
}
private extension PublicStruct {
public func extMemberPrivate() {} // expected-warning {{declaring a public instance method in a private extension}} {{3-9=fileprivate}}
fileprivate func extFuncPrivate() {}
private func extImplPrivate() {}
}
public extension InternalStruct { // expected-error {{extension of internal struct cannot be declared public}} {{1-8=}}
public func extMemberPublic() {}
fileprivate func extFuncPublic() {}
private func extImplPublic() {}
}
internal extension InternalStruct {
public func extMemberInternal() {} // expected-warning {{declaring a public instance method in an internal extension}} {{3-9=internal}}
fileprivate func extFuncInternal() {}
private func extImplInternal() {}
}
fileprivate extension InternalStruct {
public func extMemberFilePrivate() {} // expected-warning {{declaring a public instance method in a fileprivate extension}} {{3-9=fileprivate}}
fileprivate func extFuncFilePrivate() {}
private func extImplFilePrivate() {}
}
private extension InternalStruct {
public func extMemberPrivate() {} // expected-warning {{declaring a public instance method in a private extension}} {{3-9=private}}
public func extMemberPrivate() {} // expected-warning {{declaring a public instance method in a private extension}} {{3-9=fileprivate}}
fileprivate func extFuncPrivate() {}
private func extImplPrivate() {}
}
public extension FilePrivateStruct { // expected-error {{extension of fileprivate struct cannot be declared public}} {{1-8=}}
public func extMemberPublic() {}
fileprivate func extFuncPublic() {}
private func extImplPublic() {}
}
internal extension FilePrivateStruct { // expected-error {{extension of fileprivate struct cannot be declared internal}} {{1-10=}}
public func extMemberInternal() {} // expected-warning {{declaring a public instance method in an internal extension}} {{3-9=internal}}
fileprivate func extFuncInternal() {}
private func extImplInternal() {}
}
fileprivate extension FilePrivateStruct {
public func extMemberFilePrivate() {} // expected-warning {{declaring a public instance method in a fileprivate extension}} {{3-9=fileprivate}}
fileprivate func extFuncFilePrivate() {}
private func extImplFilePrivate() {}
}
private extension FilePrivateStruct {
public func extMemberPrivate() {} // expected-warning {{declaring a public instance method in a private extension}} {{3-9=private}}
public func extMemberPrivate() {} // expected-warning {{declaring a public instance method in a private extension}} {{3-9=fileprivate}}
fileprivate func extFuncPrivate() {}
private func extImplPrivate() {}
}
public extension PrivateStruct { // expected-error {{extension of private struct cannot be declared public}} {{1-8=}}
public func extMemberPublic() {}
fileprivate func extFuncPublic() {}
private func extImplPublic() {}
}
internal extension PrivateStruct { // expected-error {{extension of private struct cannot be declared internal}} {{1-10=}}
public func extMemberInternal() {} // expected-warning {{declaring a public instance method in an internal extension}} {{3-9=internal}}
fileprivate func extFuncInternal() {}
private func extImplInternal() {}
}
fileprivate extension PrivateStruct { // expected-error {{extension of private struct cannot be declared fileprivate}} {{1-13=}}
public func extMemberFilePrivate() {} // expected-warning {{declaring a public instance method in a fileprivate extension}} {{3-9=fileprivate}}
fileprivate func extFuncFilePrivate() {}
private func extImplFilePrivate() {}
}
private extension PrivateStruct {
public func extMemberPrivate() {} // expected-warning {{declaring a public instance method in a private extension}} {{3-9=private}}
public func extMemberPrivate() {} // expected-warning {{declaring a public instance method in a private extension}} {{3-9=fileprivate}}
fileprivate func extFuncPrivate() {}
private func extImplPrivate() {}
}

Expand Down
6 changes: 3 additions & 3 deletions test/SILGen/accessibility_warnings.swift
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ internal extension PublicStruct {
}
private extension PublicStruct {
// CHECK-DAG: sil private @$S22accessibility_warnings12PublicStructV16extMemberPrivate33_5D2F2E026754A901C0FF90C404896D02LLyyF
public func extMemberPrivate() {} // expected-warning {{declaring a public instance method in a private extension}} {{3-9=private}}
public func extMemberPrivate() {} // expected-warning {{declaring a public instance method in a private extension}} {{3-9=fileprivate}}
// CHECK-DAG: sil private @$S22accessibility_warnings12PublicStructV14extImplPrivate33_5D2F2E026754A901C0FF90C404896D02LLyyF
private func extImplPrivate() {}
}
Expand All @@ -83,15 +83,15 @@ internal extension InternalStruct {
}
private extension InternalStruct {
// CHECK-DAG: sil private @$S22accessibility_warnings14InternalStructV16extMemberPrivate33_5D2F2E026754A901C0FF90C404896D02LLyyF
public func extMemberPrivate() {} // expected-warning {{declaring a public instance method in a private extension}} {{3-9=private}}
public func extMemberPrivate() {} // expected-warning {{declaring a public instance method in a private extension}} {{3-9=fileprivate}}
// CHECK-DAG: sil private @$S22accessibility_warnings14InternalStructV14extImplPrivate33_5D2F2E026754A901C0FF90C404896D02LLyyF
private func extImplPrivate() {}
}


private extension PrivateStruct {
// CHECK-DAG: sil private @$S22accessibility_warnings13PrivateStruct33_5D2F2E026754A901C0FF90C404896D02LLV09extMemberC0yyF
public func extMemberPrivate() {} // expected-warning {{declaring a public instance method in a private extension}} {{3-9=private}}
public func extMemberPrivate() {} // expected-warning {{declaring a public instance method in a private extension}} {{3-9=fileprivate}}
// CHECK-DAG: sil private @$S22accessibility_warnings13PrivateStruct33_5D2F2E026754A901C0FF90C404896D02LLV07extImplC0yyF
private func extImplPrivate() {}
}
Expand Down
30 changes: 23 additions & 7 deletions test/Sema/accessibility.swift
Original file line number Diff line number Diff line change
Expand Up @@ -75,66 +75,82 @@ extension PrivateStruct {

public extension PublicStruct {
public func extMemberPublic() {}
fileprivate func extFuncPublic() {}
private func extImplPublic() {}
}
internal extension PublicStruct {
public func extMemberInternal() {} // expected-warning {{declaring a public instance method in an internal extension}} {{3-9=internal}}
fileprivate func extFuncInternal() {}
private func extImplInternal() {}
}
private extension PublicStruct {
public func extMemberPrivate() {} // expected-warning {{declaring a public instance method in a private extension}} {{3-9=private}}
private func extImplPrivate() {}
}
fileprivate extension PublicStruct {
public func extMemberFilePrivate() {} // expected-warning {{declaring a public instance method in a fileprivate extension}} {{3-9=fileprivate}}
fileprivate func extFuncFilePrivate() {}
private func extImplFilePrivate() {}
}
private extension PublicStruct {
public func extMemberPrivate() {} // expected-warning {{declaring a public instance method in a private extension}} {{3-9=fileprivate}}
fileprivate func extFuncPrivate() {}
private func extImplPrivate() {}
}
public extension InternalStruct { // expected-error {{extension of internal struct cannot be declared public}} {{1-8=}}
public func extMemberPublic() {}
fileprivate func extFuncPublic() {}
private func extImplPublic() {}
}
internal extension InternalStruct {
public func extMemberInternal() {} // expected-warning {{declaring a public instance method in an internal extension}} {{3-9=internal}}
fileprivate func extFuncInternal() {}
private func extImplInternal() {}
}
fileprivate extension InternalStruct {
public func extMemberFilePrivate() {} // expected-warning {{declaring a public instance method in a fileprivate extension}} {{3-9=fileprivate}}
fileprivate func extFuncFilePrivate() {}
private func extImplFilePrivate() {}
}
private extension InternalStruct {
public func extMemberPrivate() {} // expected-warning {{declaring a public instance method in a private extension}} {{3-9=private}}
public func extMemberPrivate() {} // expected-warning {{declaring a public instance method in a private extension}} {{3-9=fileprivate}}
fileprivate func extFuncPrivate() {}
private func extImplPrivate() {}
}
public extension FilePrivateStruct { // expected-error {{extension of fileprivate struct cannot be declared public}} {{1-8=}}
public func extMemberPublic() {}
fileprivate func extFuncPublic() {}
private func extImplPublic() {}
}
internal extension FilePrivateStruct { // expected-error {{extension of fileprivate struct cannot be declared internal}} {{1-10=}}
public func extMemberInternal() {} // expected-warning {{declaring a public instance method in an internal extension}} {{3-9=internal}}
fileprivate func extFuncInternal() {}
private func extImplInternal() {}
}
fileprivate extension FilePrivateStruct {
public func extMemberFilePrivate() {} // expected-warning {{declaring a public instance method in a fileprivate extension}} {{3-9=fileprivate}}
fileprivate func extFuncFilePrivate() {}
private func extImplFilePrivate() {}
}
private extension FilePrivateStruct {
public func extMemberPrivate() {} // expected-warning {{declaring a public instance method in a private extension}} {{3-9=private}}
public func extMemberPrivate() {} // expected-warning {{declaring a public instance method in a private extension}} {{3-9=fileprivate}}
fileprivate func extFuncPrivate() {}
private func extImplPrivate() {}
}
public extension PrivateStruct { // expected-error {{extension of private struct cannot be declared public}} {{1-8=}}
public func extMemberPublic() {}
fileprivate func extFuncPublic() {}
private func extImplPublic() {}
}
internal extension PrivateStruct { // expected-error {{extension of private struct cannot be declared internal}} {{1-10=}}
public func extMemberInternal() {} // expected-warning {{declaring a public instance method in an internal extension}} {{3-9=internal}}
fileprivate func extFuncInternal() {}
private func extImplInternal() {}
}
fileprivate extension PrivateStruct { // expected-error {{extension of private struct cannot be declared fileprivate}} {{1-13=}}
public func extMemberFilePrivate() {} // expected-warning {{declaring a public instance method in a fileprivate extension}} {{3-9=fileprivate}}
fileprivate func extFuncFilePrivate() {}
private func extImplFilePrivate() {}
}
private extension PrivateStruct {
public func extMemberPrivate() {} // expected-warning {{declaring a public instance method in a private extension}} {{3-9=private}}
public func extMemberPrivate() {} // expected-warning {{declaring a public instance method in a private extension}} {{3-9=fileprivate}}
fileprivate func extFuncPrivate() {}
private func extImplPrivate() {}
}

Expand Down