Skip to content

Commit f735f97

Browse files
dingobyejrose-apple
authored andcommitted
[Sema] Fix inappropriate diagnostics of access control for members in private extensions. (#18105)
When a `fileprivate` method is declared in a `private` extension, a warning is raised since access level `fileprivate` is literally higher than `private`. This is not appropriate because extensions are top level declarations, for which `private` and `fileprivate` are equivalent. This patch stops such warnings. Resolves: SR-8306.
1 parent 858155c commit f735f97

File tree

4 files changed

+64
-26
lines changed

4 files changed

+64
-26
lines changed

lib/Sema/TypeCheckAttr.cpp

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1510,15 +1510,21 @@ void AttributeChecker::visitAccessControlAttr(AccessControlAttr *attr) {
15101510
return;
15111511
}
15121512

1513-
auto extAttr = extension->getAttrs().getAttribute<AccessControlAttr>();
1514-
if (extAttr && attr->getAccess() > extAttr->getAccess()) {
1515-
auto diag = TC.diagnose(attr->getLocation(),
1516-
diag::access_control_ext_member_more,
1517-
attr->getAccess(),
1518-
D->getDescriptiveKind(),
1519-
extAttr->getAccess());
1520-
swift::fixItAccess(diag, cast<ValueDecl>(D), extAttr->getAccess());
1521-
return;
1513+
if (auto extAttr =
1514+
extension->getAttrs().getAttribute<AccessControlAttr>()) {
1515+
// Extensions are top level declarations, for which the literally lowest
1516+
// access level `private` is equivalent to `fileprivate`.
1517+
AccessLevel extAccess = std::max(extAttr->getAccess(),
1518+
AccessLevel::FilePrivate);
1519+
if (attr->getAccess() > extAccess) {
1520+
auto diag = TC.diagnose(attr->getLocation(),
1521+
diag::access_control_ext_member_more,
1522+
attr->getAccess(),
1523+
D->getDescriptiveKind(),
1524+
extAttr->getAccess());
1525+
swift::fixItAccess(diag, cast<ValueDecl>(D), extAccess);
1526+
return;
1527+
}
15221528
}
15231529
}
15241530

test/Compatibility/accessibility.swift

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -75,66 +75,82 @@ extension PrivateStruct {
7575

7676
public extension PublicStruct {
7777
public func extMemberPublic() {}
78+
fileprivate func extFuncPublic() {}
7879
private func extImplPublic() {}
7980
}
8081
internal extension PublicStruct {
8182
public func extMemberInternal() {} // expected-warning {{declaring a public instance method in an internal extension}} {{3-9=internal}}
83+
fileprivate func extFuncInternal() {}
8284
private func extImplInternal() {}
8385
}
84-
private extension PublicStruct {
85-
public func extMemberPrivate() {} // expected-warning {{declaring a public instance method in a private extension}} {{3-9=private}}
86-
private func extImplPrivate() {}
87-
}
8886
fileprivate extension PublicStruct {
8987
public func extMemberFilePrivate() {} // expected-warning {{declaring a public instance method in a fileprivate extension}} {{3-9=fileprivate}}
88+
fileprivate func extFuncFilePrivate() {}
9089
private func extImplFilePrivate() {}
9190
}
91+
private extension PublicStruct {
92+
public func extMemberPrivate() {} // expected-warning {{declaring a public instance method in a private extension}} {{3-9=fileprivate}}
93+
fileprivate func extFuncPrivate() {}
94+
private func extImplPrivate() {}
95+
}
9296
public extension InternalStruct { // expected-error {{extension of internal struct cannot be declared public}} {{1-8=}}
9397
public func extMemberPublic() {}
98+
fileprivate func extFuncPublic() {}
9499
private func extImplPublic() {}
95100
}
96101
internal extension InternalStruct {
97102
public func extMemberInternal() {} // expected-warning {{declaring a public instance method in an internal extension}} {{3-9=internal}}
103+
fileprivate func extFuncInternal() {}
98104
private func extImplInternal() {}
99105
}
100106
fileprivate extension InternalStruct {
101107
public func extMemberFilePrivate() {} // expected-warning {{declaring a public instance method in a fileprivate extension}} {{3-9=fileprivate}}
108+
fileprivate func extFuncFilePrivate() {}
102109
private func extImplFilePrivate() {}
103110
}
104111
private extension InternalStruct {
105-
public func extMemberPrivate() {} // expected-warning {{declaring a public instance method in a private extension}} {{3-9=private}}
112+
public func extMemberPrivate() {} // expected-warning {{declaring a public instance method in a private extension}} {{3-9=fileprivate}}
113+
fileprivate func extFuncPrivate() {}
106114
private func extImplPrivate() {}
107115
}
108116
public extension FilePrivateStruct { // expected-error {{extension of fileprivate struct cannot be declared public}} {{1-8=}}
109117
public func extMemberPublic() {}
118+
fileprivate func extFuncPublic() {}
110119
private func extImplPublic() {}
111120
}
112121
internal extension FilePrivateStruct { // expected-error {{extension of fileprivate struct cannot be declared internal}} {{1-10=}}
113122
public func extMemberInternal() {} // expected-warning {{declaring a public instance method in an internal extension}} {{3-9=internal}}
123+
fileprivate func extFuncInternal() {}
114124
private func extImplInternal() {}
115125
}
116126
fileprivate extension FilePrivateStruct {
117127
public func extMemberFilePrivate() {} // expected-warning {{declaring a public instance method in a fileprivate extension}} {{3-9=fileprivate}}
128+
fileprivate func extFuncFilePrivate() {}
118129
private func extImplFilePrivate() {}
119130
}
120131
private extension FilePrivateStruct {
121-
public func extMemberPrivate() {} // expected-warning {{declaring a public instance method in a private extension}} {{3-9=private}}
132+
public func extMemberPrivate() {} // expected-warning {{declaring a public instance method in a private extension}} {{3-9=fileprivate}}
133+
fileprivate func extFuncPrivate() {}
122134
private func extImplPrivate() {}
123135
}
124136
public extension PrivateStruct { // expected-error {{extension of private struct cannot be declared public}} {{1-8=}}
125137
public func extMemberPublic() {}
138+
fileprivate func extFuncPublic() {}
126139
private func extImplPublic() {}
127140
}
128141
internal extension PrivateStruct { // expected-error {{extension of private struct cannot be declared internal}} {{1-10=}}
129142
public func extMemberInternal() {} // expected-warning {{declaring a public instance method in an internal extension}} {{3-9=internal}}
143+
fileprivate func extFuncInternal() {}
130144
private func extImplInternal() {}
131145
}
132146
fileprivate extension PrivateStruct { // expected-error {{extension of private struct cannot be declared fileprivate}} {{1-13=}}
133147
public func extMemberFilePrivate() {} // expected-warning {{declaring a public instance method in a fileprivate extension}} {{3-9=fileprivate}}
148+
fileprivate func extFuncFilePrivate() {}
134149
private func extImplFilePrivate() {}
135150
}
136151
private extension PrivateStruct {
137-
public func extMemberPrivate() {} // expected-warning {{declaring a public instance method in a private extension}} {{3-9=private}}
152+
public func extMemberPrivate() {} // expected-warning {{declaring a public instance method in a private extension}} {{3-9=fileprivate}}
153+
fileprivate func extFuncPrivate() {}
138154
private func extImplPrivate() {}
139155
}
140156

test/SILGen/accessibility_warnings.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ internal extension PublicStruct {
7070
}
7171
private extension PublicStruct {
7272
// CHECK-DAG: sil private @$S22accessibility_warnings12PublicStructV16extMemberPrivate33_5D2F2E026754A901C0FF90C404896D02LLyyF
73-
public func extMemberPrivate() {} // expected-warning {{declaring a public instance method in a private extension}} {{3-9=private}}
73+
public func extMemberPrivate() {} // expected-warning {{declaring a public instance method in a private extension}} {{3-9=fileprivate}}
7474
// CHECK-DAG: sil private @$S22accessibility_warnings12PublicStructV14extImplPrivate33_5D2F2E026754A901C0FF90C404896D02LLyyF
7575
private func extImplPrivate() {}
7676
}
@@ -83,15 +83,15 @@ internal extension InternalStruct {
8383
}
8484
private extension InternalStruct {
8585
// CHECK-DAG: sil private @$S22accessibility_warnings14InternalStructV16extMemberPrivate33_5D2F2E026754A901C0FF90C404896D02LLyyF
86-
public func extMemberPrivate() {} // expected-warning {{declaring a public instance method in a private extension}} {{3-9=private}}
86+
public func extMemberPrivate() {} // expected-warning {{declaring a public instance method in a private extension}} {{3-9=fileprivate}}
8787
// CHECK-DAG: sil private @$S22accessibility_warnings14InternalStructV14extImplPrivate33_5D2F2E026754A901C0FF90C404896D02LLyyF
8888
private func extImplPrivate() {}
8989
}
9090

9191

9292
private extension PrivateStruct {
9393
// CHECK-DAG: sil private @$S22accessibility_warnings13PrivateStruct33_5D2F2E026754A901C0FF90C404896D02LLV09extMemberC0yyF
94-
public func extMemberPrivate() {} // expected-warning {{declaring a public instance method in a private extension}} {{3-9=private}}
94+
public func extMemberPrivate() {} // expected-warning {{declaring a public instance method in a private extension}} {{3-9=fileprivate}}
9595
// CHECK-DAG: sil private @$S22accessibility_warnings13PrivateStruct33_5D2F2E026754A901C0FF90C404896D02LLV07extImplC0yyF
9696
private func extImplPrivate() {}
9797
}

test/Sema/accessibility.swift

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -75,66 +75,82 @@ extension PrivateStruct {
7575

7676
public extension PublicStruct {
7777
public func extMemberPublic() {}
78+
fileprivate func extFuncPublic() {}
7879
private func extImplPublic() {}
7980
}
8081
internal extension PublicStruct {
8182
public func extMemberInternal() {} // expected-warning {{declaring a public instance method in an internal extension}} {{3-9=internal}}
83+
fileprivate func extFuncInternal() {}
8284
private func extImplInternal() {}
8385
}
84-
private extension PublicStruct {
85-
public func extMemberPrivate() {} // expected-warning {{declaring a public instance method in a private extension}} {{3-9=private}}
86-
private func extImplPrivate() {}
87-
}
8886
fileprivate extension PublicStruct {
8987
public func extMemberFilePrivate() {} // expected-warning {{declaring a public instance method in a fileprivate extension}} {{3-9=fileprivate}}
88+
fileprivate func extFuncFilePrivate() {}
9089
private func extImplFilePrivate() {}
9190
}
91+
private extension PublicStruct {
92+
public func extMemberPrivate() {} // expected-warning {{declaring a public instance method in a private extension}} {{3-9=fileprivate}}
93+
fileprivate func extFuncPrivate() {}
94+
private func extImplPrivate() {}
95+
}
9296
public extension InternalStruct { // expected-error {{extension of internal struct cannot be declared public}} {{1-8=}}
9397
public func extMemberPublic() {}
98+
fileprivate func extFuncPublic() {}
9499
private func extImplPublic() {}
95100
}
96101
internal extension InternalStruct {
97102
public func extMemberInternal() {} // expected-warning {{declaring a public instance method in an internal extension}} {{3-9=internal}}
103+
fileprivate func extFuncInternal() {}
98104
private func extImplInternal() {}
99105
}
100106
fileprivate extension InternalStruct {
101107
public func extMemberFilePrivate() {} // expected-warning {{declaring a public instance method in a fileprivate extension}} {{3-9=fileprivate}}
108+
fileprivate func extFuncFilePrivate() {}
102109
private func extImplFilePrivate() {}
103110
}
104111
private extension InternalStruct {
105-
public func extMemberPrivate() {} // expected-warning {{declaring a public instance method in a private extension}} {{3-9=private}}
112+
public func extMemberPrivate() {} // expected-warning {{declaring a public instance method in a private extension}} {{3-9=fileprivate}}
113+
fileprivate func extFuncPrivate() {}
106114
private func extImplPrivate() {}
107115
}
108116
public extension FilePrivateStruct { // expected-error {{extension of fileprivate struct cannot be declared public}} {{1-8=}}
109117
public func extMemberPublic() {}
118+
fileprivate func extFuncPublic() {}
110119
private func extImplPublic() {}
111120
}
112121
internal extension FilePrivateStruct { // expected-error {{extension of fileprivate struct cannot be declared internal}} {{1-10=}}
113122
public func extMemberInternal() {} // expected-warning {{declaring a public instance method in an internal extension}} {{3-9=internal}}
123+
fileprivate func extFuncInternal() {}
114124
private func extImplInternal() {}
115125
}
116126
fileprivate extension FilePrivateStruct {
117127
public func extMemberFilePrivate() {} // expected-warning {{declaring a public instance method in a fileprivate extension}} {{3-9=fileprivate}}
128+
fileprivate func extFuncFilePrivate() {}
118129
private func extImplFilePrivate() {}
119130
}
120131
private extension FilePrivateStruct {
121-
public func extMemberPrivate() {} // expected-warning {{declaring a public instance method in a private extension}} {{3-9=private}}
132+
public func extMemberPrivate() {} // expected-warning {{declaring a public instance method in a private extension}} {{3-9=fileprivate}}
133+
fileprivate func extFuncPrivate() {}
122134
private func extImplPrivate() {}
123135
}
124136
public extension PrivateStruct { // expected-error {{extension of private struct cannot be declared public}} {{1-8=}}
125137
public func extMemberPublic() {}
138+
fileprivate func extFuncPublic() {}
126139
private func extImplPublic() {}
127140
}
128141
internal extension PrivateStruct { // expected-error {{extension of private struct cannot be declared internal}} {{1-10=}}
129142
public func extMemberInternal() {} // expected-warning {{declaring a public instance method in an internal extension}} {{3-9=internal}}
143+
fileprivate func extFuncInternal() {}
130144
private func extImplInternal() {}
131145
}
132146
fileprivate extension PrivateStruct { // expected-error {{extension of private struct cannot be declared fileprivate}} {{1-13=}}
133147
public func extMemberFilePrivate() {} // expected-warning {{declaring a public instance method in a fileprivate extension}} {{3-9=fileprivate}}
148+
fileprivate func extFuncFilePrivate() {}
134149
private func extImplFilePrivate() {}
135150
}
136151
private extension PrivateStruct {
137-
public func extMemberPrivate() {} // expected-warning {{declaring a public instance method in a private extension}} {{3-9=private}}
152+
public func extMemberPrivate() {} // expected-warning {{declaring a public instance method in a private extension}} {{3-9=fileprivate}}
153+
fileprivate func extFuncPrivate() {}
138154
private func extImplPrivate() {}
139155
}
140156

0 commit comments

Comments
 (0)