Skip to content

Commit 7bc5088

Browse files
committed
Sema: Check declaration attributes before checking members
This simplifies matters if checking an attribute adds members to the nominal type or extension.
1 parent f858309 commit 7bc5088

File tree

4 files changed

+25
-49
lines changed

4 files changed

+25
-49
lines changed

lib/Sema/TypeCheckAttr.cpp

-25
Original file line numberDiff line numberDiff line change
@@ -1884,9 +1884,6 @@ SynthesizeMainFunctionRequest::evaluate(Evaluator &evaluator,
18841884
return nullptr;
18851885
}
18861886

1887-
SourceFile *file = cast<SourceFile>(declContext->getModuleScopeContext());
1888-
assert(file);
1889-
18901887
// Create a function
18911888
//
18921889
// func $main() {
@@ -1954,28 +1951,6 @@ SynthesizeMainFunctionRequest::evaluate(Evaluator &evaluator,
19541951

19551952
iterableDeclContext->addMember(func);
19561953

1957-
// This function must be type-checked. Why? Consider the following scenario:
1958-
//
1959-
// protocol AlmostMainable {}
1960-
// protocol ReallyMainable {}
1961-
// extension AlmostMainable where Self : ReallyMainable {
1962-
// static func main() {}
1963-
// }
1964-
// @main struct Main : AlmostMainable {}
1965-
//
1966-
// Note in particular that Main does not conform to ReallyMainable.
1967-
//
1968-
// In this case, resolveValueMember will find the function main in the
1969-
// extension, and so, since there is one candidate, the function $main will
1970-
// accordingly be formed as usual:
1971-
//
1972-
// func $main() {
1973-
// return Main.main()
1974-
// }
1975-
//
1976-
// Of course, this function's body does not type-check.
1977-
file->DelayedFunctions.push_back(func);
1978-
19791954
return func;
19801955
}
19811956

lib/Sema/TypeCheckDeclPrimary.cpp

+11-10
Original file line numberDiff line numberDiff line change
@@ -1797,13 +1797,13 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
17971797
checkGenericParams(ED);
17981798

17991799
// Check for circular inheritance of the raw type.
1800-
(void)ED->hasCircularRawValue();
1800+
(void) ED->hasCircularRawValue();
1801+
1802+
TypeChecker::checkDeclAttributes(ED);
18011803

18021804
for (Decl *member : ED->getMembers())
18031805
visit(member);
18041806

1805-
TypeChecker::checkDeclAttributes(ED);
1806-
18071807
checkInheritanceClause(ED);
18081808

18091809
checkAccessControl(ED);
@@ -1845,13 +1845,13 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
18451845

18461846
installCodingKeysIfNecessary(SD);
18471847

1848+
TypeChecker::checkDeclAttributes(SD);
1849+
18481850
for (Decl *Member : SD->getMembers())
18491851
visit(Member);
18501852

18511853
TypeChecker::checkPatternBindingCaptures(SD);
18521854

1853-
TypeChecker::checkDeclAttributes(SD);
1854-
18551855
checkInheritanceClause(SD);
18561856

18571857
checkAccessControl(SD);
@@ -1974,6 +1974,8 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
19741974
// Force creation of an implicit destructor, if any.
19751975
(void) CD->getDestructor();
19761976

1977+
TypeChecker::checkDeclAttributes(CD);
1978+
19771979
for (Decl *Member : CD->getEmittedMembers())
19781980
visit(Member);
19791981

@@ -2084,8 +2086,6 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
20842086
}
20852087
}
20862088

2087-
TypeChecker::checkDeclAttributes(CD);
2088-
20892089
checkInheritanceClause(CD);
20902090

20912091
checkAccessControl(CD);
@@ -2105,12 +2105,12 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
21052105
// Check for circular inheritance within the protocol.
21062106
(void)PD->hasCircularInheritedProtocols();
21072107

2108+
TypeChecker::checkDeclAttributes(PD);
2109+
21082110
// Check the members.
21092111
for (auto Member : PD->getMembers())
21102112
visit(Member);
21112113

2112-
TypeChecker::checkDeclAttributes(PD);
2113-
21142114
checkAccessControl(PD);
21152115

21162116
checkInheritanceClause(PD);
@@ -2428,14 +2428,15 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
24282428

24292429
checkGenericParams(ED);
24302430

2431+
TypeChecker::checkDeclAttributes(ED);
2432+
24312433
for (Decl *Member : ED->getMembers())
24322434
visit(Member);
24332435

24342436
TypeChecker::checkPatternBindingCaptures(ED);
24352437

24362438
TypeChecker::checkConformancesInContext(ED);
24372439

2438-
TypeChecker::checkDeclAttributes(ED);
24392440
checkAccessControl(ED);
24402441

24412442
checkExplicitAvailability(ED);

test/Compatibility/accessibility.swift

+7-7
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ private extension PublicStruct {
107107
private func extImplPrivate() {}
108108
}
109109
public extension InternalStruct { // expected-error {{extension of internal struct cannot be declared public}} {{1-8=}}
110-
public func extMemberPublic() {} // expected-warning {{'public' modifier is redundant for instance method declared in a public extension}} {{3-10=}}
110+
public func extMemberPublic() {}
111111
fileprivate func extFuncPublic() {}
112112
private func extImplPublic() {}
113113
}
@@ -127,12 +127,12 @@ private extension InternalStruct {
127127
private func extImplPrivate() {}
128128
}
129129
public extension FilePrivateStruct { // expected-error {{extension of fileprivate struct cannot be declared public}} {{1-8=}}
130-
public func extMemberPublic() {} // expected-warning {{'public' modifier is redundant for instance method declared in a public extension}} {{3-10=}}
130+
public func extMemberPublic() {}
131131
fileprivate func extFuncPublic() {}
132132
private func extImplPublic() {}
133133
}
134134
internal extension FilePrivateStruct { // expected-error {{extension of fileprivate struct cannot be declared internal}} {{1-10=}}
135-
public func extMemberInternal() {} // expected-warning {{'public' modifier conflicts with extension's default access of 'internal'}} {{none}}
135+
public func extMemberInternal() {}
136136
fileprivate func extFuncInternal() {}
137137
private func extImplInternal() {}
138138
}
@@ -147,18 +147,18 @@ private extension FilePrivateStruct {
147147
private func extImplPrivate() {}
148148
}
149149
public extension PrivateStruct { // expected-error {{extension of private struct cannot be declared public}} {{1-8=}}
150-
public func extMemberPublic() {} // expected-warning {{'public' modifier is redundant for instance method declared in a public extension}} {{3-10=}}
150+
public func extMemberPublic() {}
151151
fileprivate func extFuncPublic() {}
152152
private func extImplPublic() {}
153153
}
154154
internal extension PrivateStruct { // expected-error {{extension of private struct cannot be declared internal}} {{1-10=}}
155-
public func extMemberInternal() {} // expected-warning {{'public' modifier conflicts with extension's default access of 'internal'}} {{none}}
155+
public func extMemberInternal() {}
156156
fileprivate func extFuncInternal() {}
157157
private func extImplInternal() {}
158158
}
159159
fileprivate extension PrivateStruct { // expected-error {{extension of private struct cannot be declared fileprivate}} {{1-13=}}
160-
public func extMemberFilePrivate() {} // expected-warning {{'public' modifier conflicts with extension's default access of 'fileprivate'}} {{none}}
161-
fileprivate func extFuncFilePrivate() {} // expected-warning {{'fileprivate' modifier is redundant for instance method declared in a fileprivate extension}} {{3-15=}}
160+
public func extMemberFilePrivate() {}
161+
fileprivate func extFuncFilePrivate() {}
162162
private func extImplFilePrivate() {}
163163
}
164164
private extension PrivateStruct {

test/Sema/accessibility.swift

+7-7
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ private extension PublicStruct {
106106
private func extImplPrivate() {}
107107
}
108108
public extension InternalStruct { // expected-error {{extension of internal struct cannot be declared public}} {{1-8=}}
109-
public func extMemberPublic() {} // expected-warning {{'public' modifier is redundant for instance method declared in a public extension}} {{3-10=}}
109+
public func extMemberPublic() {}
110110
fileprivate func extFuncPublic() {}
111111
private func extImplPublic() {}
112112
}
@@ -126,12 +126,12 @@ private extension InternalStruct {
126126
private func extImplPrivate() {}
127127
}
128128
public extension FilePrivateStruct { // expected-error {{extension of fileprivate struct cannot be declared public}} {{1-8=}}
129-
public func extMemberPublic() {} // expected-warning {{'public' modifier is redundant for instance method declared in a public extension}} {{3-10=}}
129+
public func extMemberPublic() {}
130130
fileprivate func extFuncPublic() {}
131131
private func extImplPublic() {}
132132
}
133133
internal extension FilePrivateStruct { // expected-error {{extension of fileprivate struct cannot be declared internal}} {{1-10=}}
134-
public func extMemberInternal() {} // expected-warning {{'public' modifier conflicts with extension's default access of 'internal'}} {{none}}
134+
public func extMemberInternal() {}
135135
fileprivate func extFuncInternal() {}
136136
private func extImplInternal() {}
137137
}
@@ -146,18 +146,18 @@ private extension FilePrivateStruct {
146146
private func extImplPrivate() {}
147147
}
148148
public extension PrivateStruct { // expected-error {{extension of private struct cannot be declared public}} {{1-8=}}
149-
public func extMemberPublic() {} // expected-warning {{'public' modifier is redundant for instance method declared in a public extension}} {{3-10=}}
149+
public func extMemberPublic() {}
150150
fileprivate func extFuncPublic() {}
151151
private func extImplPublic() {}
152152
}
153153
internal extension PrivateStruct { // expected-error {{extension of private struct cannot be declared internal}} {{1-10=}}
154-
public func extMemberInternal() {} // expected-warning {{'public' modifier conflicts with extension's default access of 'internal'}} {{none}}
154+
public func extMemberInternal() {}
155155
fileprivate func extFuncInternal() {}
156156
private func extImplInternal() {}
157157
}
158158
fileprivate extension PrivateStruct { // expected-error {{extension of private struct cannot be declared fileprivate}} {{1-13=}}
159-
public func extMemberFilePrivate() {} // expected-warning {{'public' modifier conflicts with extension's default access of 'fileprivate'}} {{none}}
160-
fileprivate func extFuncFilePrivate() {} // expected-warning {{'fileprivate' modifier is redundant for instance method declared in a fileprivate extension}} {{3-15=}}
159+
public func extMemberFilePrivate() {}
160+
fileprivate func extFuncFilePrivate() {}
161161
private func extImplFilePrivate() {}
162162
}
163163
private extension PrivateStruct {

0 commit comments

Comments
 (0)