Skip to content

Commit 396c9f2

Browse files
authored
[Parse] Stop ignoring private decls for incremental purposes. (#3352)
We'd really like to say that private decls can't affect other files, but we don't have enough information at parse-time: - Private members of non-private classes still show up in vtables, which affects subclasses and callers in other files. - Private stored properties of non-private structs change the layout of the struct. - Private types may be used in private stored properties, affecting the layout of the containing struct. - Private decls of /any kind/ can be used as the initial value of a stored property without an explicit type. private class Evil { class func defaultAlignment() -> Alignment { return .evil } } public struct Character { // Inferred type here! private var alignment = Evil.defaultAlignment() } To be safe and correct, go back to only ignoring method bodies. https://bugs.swift.org/browse/SR-1030
1 parent 64d998d commit 396c9f2

10 files changed

+173
-39
lines changed

lib/Parse/ParseDecl.cpp

Lines changed: 1 addition & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -170,40 +170,6 @@ namespace {
170170
P.markWasHandled(D);
171171
}
172172
};
173-
174-
/// An RAII type to exclude tokens contributing to private decls from the
175-
/// interface hash of the source file. On destruct, it checks if the set of
176-
/// attributes includes the "private" attribute; if so, it resets the MD5
177-
/// hash of the source file to what it was when the IgnorePrivateDeclTokens
178-
/// instance was created, thus excluding from the interface hash all tokens
179-
/// parsed in the meantime.
180-
struct IgnorePrivateDeclTokens {
181-
Parser &TheParser;
182-
DeclAttributes &Attributes;
183-
Optional<llvm::MD5> SavedHashState;
184-
185-
IgnorePrivateDeclTokens(Parser &P, DeclAttributes &Attrs)
186-
: TheParser(P), Attributes(Attrs) {
187-
// NOTE: It's generally not safe to ignore private decls in nominal
188-
// types. Such private decls may affect the data layout of a class/struct
189-
// or the vtable layout of a class. So only ignore global private decls.
190-
if (TheParser.IsParsingInterfaceTokens &&
191-
TheParser.CurDeclContext->isModuleScopeContext()) {
192-
SavedHashState = TheParser.SF.getInterfaceHashState();
193-
}
194-
}
195-
196-
~IgnorePrivateDeclTokens() {
197-
if (!SavedHashState)
198-
return;
199-
200-
if (auto *attr = Attributes.getAttribute<AbstractAccessibilityAttr>()) {
201-
if (attr->getAccess() == Accessibility::Private) {
202-
TheParser.SF.setInterfaceHashState(*SavedHashState);
203-
}
204-
}
205-
}
206-
};
207173
}
208174

209175
/// \brief Main entrypoint for the parser.
@@ -1905,6 +1871,7 @@ ParserStatus Parser::parseDecl(ParseDeclOptions Flags,
19051871
LastDecl = D;
19061872
Handler(D);
19071873
};
1874+
19081875
ParserPosition BeginParserPosition;
19091876
if (isCodeCompletionFirstPass())
19101877
BeginParserPosition = getParserPosition();
@@ -1917,7 +1884,6 @@ ParserStatus Parser::parseDecl(ParseDeclOptions Flags,
19171884
StructureMarkerKind::Declaration);
19181885

19191886
DeclAttributes Attributes;
1920-
IgnorePrivateDeclTokens IgnoreTokens(*this, Attributes);
19211887
if (Tok.hasComment())
19221888
Attributes.add(new (Context) RawDocCommentAttr(Tok.getCommentRange()));
19231889
bool FoundCCTokenInAttr;
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// RUN: mkdir -p %t
2+
// RUN: %utils/split_file.py -o %t %s
3+
// RUN: %target-swift-frontend -dump-interface-hash %t/a.swift 2> %t/a.hash
4+
// RUN: %target-swift-frontend -dump-interface-hash %t/b.swift 2> %t/b.hash
5+
// RUN: not cmp %t/a.hash %t/b.hash
6+
7+
// BEGIN a.swift
8+
private class C {
9+
func f2() -> Int {
10+
return 0
11+
}
12+
}
13+
14+
// BEGIN b.swift
15+
private class C {
16+
func f2() -> Int {
17+
return 0
18+
}
19+
20+
private var x: Int = 0
21+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// RUN: mkdir -p %t
2+
// RUN: %utils/split_file.py -o %t %s
3+
// RUN: %target-swift-frontend -dump-interface-hash %t/a.swift 2> %t/a.hash
4+
// RUN: %target-swift-frontend -dump-interface-hash %t/b.swift 2> %t/b.hash
5+
// RUN: not cmp %t/a.hash %t/b.hash
6+
7+
// BEGIN a.swift
8+
private enum A {
9+
case x, y
10+
func f2() -> Int {
11+
return 0
12+
}
13+
}
14+
15+
// BEGIN b.swift
16+
private enum A {
17+
case x, y
18+
func f2() -> Int {
19+
return 0
20+
}
21+
22+
var foo: Int { return 0 }
23+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// RUN: mkdir -p %t
2+
// RUN: %utils/split_file.py -o %t %s
3+
// RUN: %target-swift-frontend -dump-interface-hash %t/a.swift 2> %t/a.hash
4+
// RUN: %target-swift-frontend -dump-interface-hash %t/b.swift 2> %t/b.hash
5+
// RUN: not cmp %t/a.hash %t/b.hash
6+
7+
// BEGIN a.swift
8+
enum A {
9+
case x, y
10+
func f2() -> Int {
11+
return 0
12+
}
13+
}
14+
15+
// BEGIN b.swift
16+
enum A {
17+
case x, y
18+
func f2() -> Int {
19+
return 0
20+
}
21+
22+
private var foo: Int { return 0 }
23+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// RUN: mkdir -p %t
2+
// RUN: %utils/split_file.py -o %t %s
3+
// RUN: %target-swift-frontend -dump-interface-hash %t/a.swift 2> %t/a.hash
4+
// RUN: %target-swift-frontend -dump-interface-hash %t/b.swift 2> %t/b.hash
5+
// RUN: not cmp %t/a.hash %t/b.hash
6+
7+
// BEGIN a.swift
8+
struct A {
9+
func f2() -> Int {
10+
return 0
11+
}
12+
}
13+
14+
enum B {
15+
case x, y
16+
func f2() -> Int {
17+
return 0
18+
}
19+
}
20+
21+
// BEGIN b.swift
22+
struct A {
23+
func f2() -> Int {
24+
return 0
25+
}
26+
27+
private func f3() -> Int {
28+
return 1
29+
}
30+
}
31+
32+
enum B {
33+
case x, y
34+
func f2() -> Int {
35+
return 0
36+
}
37+
38+
private func f3() -> Int {
39+
return 1
40+
}
41+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// RUN: mkdir -p %t
2+
// RUN: %utils/split_file.py -o %t %s
3+
// RUN: %target-swift-frontend -dump-interface-hash %t/a.swift 2> %t/a.hash
4+
// RUN: %target-swift-frontend -dump-interface-hash %t/b.swift 2> %t/b.hash
5+
// RUN: not cmp %t/a.hash %t/b.hash
6+
7+
// BEGIN a.swift
8+
private protocol P {
9+
func f2() -> Int
10+
var y: Int { get set }
11+
}
12+
13+
// BEGIN b.swift
14+
private protocol P {
15+
func f2() -> Int
16+
func f3() -> Int
17+
var y: Int { get set }
18+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// RUN: mkdir -p %t
2+
// RUN: %utils/split_file.py -o %t %s
3+
// RUN: %target-swift-frontend -dump-interface-hash %t/a.swift 2> %t/a.hash
4+
// RUN: %target-swift-frontend -dump-interface-hash %t/b.swift 2> %t/b.hash
5+
// RUN: not cmp %t/a.hash %t/b.hash
6+
7+
// BEGIN a.swift
8+
private protocol P {
9+
func f2() -> Int
10+
var y: Int { get set }
11+
}
12+
13+
// BEGIN b.swift
14+
private protocol P {
15+
func f2() -> Int
16+
var x: Int { get set }
17+
var y: Int { get set }
18+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// RUN: mkdir -p %t
2+
// RUN: %utils/split_file.py -o %t %s
3+
// RUN: %target-swift-frontend -dump-interface-hash %t/a.swift 2> %t/a.hash
4+
// RUN: %target-swift-frontend -dump-interface-hash %t/b.swift 2> %t/b.hash
5+
// RUN: not cmp %t/a.hash %t/b.hash
6+
7+
// BEGIN a.swift
8+
struct S {
9+
func f2() -> Int {
10+
return 0
11+
}
12+
13+
var y: Int = 0
14+
}
15+
16+
// BEGIN b.swift
17+
struct S {
18+
func f2() -> Int {
19+
return 0
20+
}
21+
22+
private var x: Int = 0
23+
var y: Int = 0
24+
}

test/InterfaceHash/added_private_struct_property.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
// RUN: not cmp %t/a.hash %t/b.hash
66

77
// BEGIN a.swift
8-
struct S {
8+
private struct S {
99
func f2() -> Int {
1010
return 0
1111
}
@@ -14,11 +14,11 @@ struct S {
1414
}
1515

1616
// BEGIN b.swift
17-
struct S {
17+
private struct S {
1818
func f2() -> Int {
1919
return 0
2020
}
2121

22-
private var x: Int = 0
22+
var x: Int = 0
2323
var y: Int = 0
2424
}

test/InterfaceHash/changed_private_var_type.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// RUN: %utils/split_file.py -o %t %s
33
// RUN: %target-swift-frontend -dump-interface-hash %t/a.swift 2> %t/a.hash
44
// RUN: %target-swift-frontend -dump-interface-hash %t/b.swift 2> %t/b.hash
5-
// RUN: cmp %t/a.hash %t/b.hash
5+
// RUN: not cmp %t/a.hash %t/b.hash
66

77
// BEGIN a.swift
88
private var x: Int

0 commit comments

Comments
 (0)