Skip to content

Commit 8bd5ddc

Browse files
authored
Merge pull request #6234 from slavapestov/swift-3-mode-typealias-hack
Sema: Add simulation of buggy Swift 3 typealias accessibility checking
2 parents 505b6f4 + 9fba89b commit 8bd5ddc

File tree

5 files changed

+98
-40
lines changed

5 files changed

+98
-40
lines changed

lib/Sema/TypeCheckDecl.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1139,6 +1139,7 @@ static void recordSelfContextType(AbstractFunctionDecl *func) {
11391139
namespace {
11401140

11411141
class AccessScopeChecker {
1142+
ASTContext &Context;
11421143
const SourceFile *File;
11431144
TypeChecker::TypeAccessScopeCacheMap &Cache;
11441145

@@ -1147,7 +1148,9 @@ class AccessScopeChecker {
11471148

11481149
AccessScopeChecker(const DeclContext *useDC,
11491150
decltype(TypeChecker::TypeAccessScopeCache) &caches)
1150-
: File(useDC->getParentSourceFile()), Cache(caches[File]),
1151+
: Context(useDC->getASTContext()),
1152+
File(useDC->getParentSourceFile()),
1153+
Cache(caches[File]),
11511154
Scope(AccessScope::getPublic()) {}
11521155

11531156
bool visitDecl(ValueDecl *VD) {
@@ -1161,6 +1164,12 @@ class AccessScopeChecker {
11611164
return true;
11621165
}
11631166

1167+
// Simulation for Swift 3 bug.
1168+
if (isa<TypeAliasDecl>(VD) &&
1169+
VD->getInterfaceType()->hasTypeParameter() &&
1170+
Context.isSwiftVersion3())
1171+
return true;
1172+
11641173
auto cached = Cache.find(VD);
11651174
if (cached != Cache.end()) {
11661175
Scope = Scope->intersectWith(cached->second);
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// RUN: %target-typecheck-verify-swift -swift-version 3
2+
3+
public protocol P {
4+
associatedtype Element
5+
6+
func f() -> Element
7+
}
8+
9+
struct S<T> : P {
10+
func f() -> T { while true {} }
11+
}
12+
13+
public struct G<T> {
14+
typealias A = S<T>
15+
16+
public func foo<U : P>(u: U) where U.Element == A.Element {}
17+
}
18+
19+
public final class ReplayableGenerator<S: Sequence> : IteratorProtocol {
20+
typealias Sequence = S
21+
public typealias Element = Sequence.Iterator.Element
22+
23+
public func next() -> Element? {
24+
return nil
25+
}
26+
}
27+
28+
struct Generic<T> {
29+
fileprivate typealias Dependent = T
30+
}
31+
32+
var x: Generic<Int>.Dependent = 3
33+
34+
func internalFuncWithFileprivateAlias() -> Generic<Int>.Dependent {
35+
return 3
36+
}
37+
38+
private func privateFuncWithFileprivateAlias() -> Generic<Int>.Dependent {
39+
return 3
40+
}
41+
42+
var y = privateFuncWithFileprivateAlias()

test/Sema/accessibility.swift

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -637,21 +637,3 @@ internal struct AssocTypeOuterProblem2 {
637637
fileprivate typealias Assoc = Int // expected-error {{type alias 'Assoc' must be as accessible as its enclosing type because it matches a requirement in protocol 'AssocTypeProto'}} {{5-16=internal}}
638638
}
639639
}
640-
641-
// This code was accepted in Swift 3
642-
public protocol P {
643-
associatedtype Element
644-
645-
func f() -> Element
646-
}
647-
648-
struct S<T> : P {
649-
func f() -> T { while true {} }
650-
}
651-
652-
public struct G<T> {
653-
typealias A = S<T> // expected-note {{type declared here}}
654-
655-
public func foo<U : P>(u: U) where U.Element == A.Element {}
656-
// expected-error@-1 {{instance method cannot be declared public because its generic requirement uses an internal type}}
657-
}

test/Sema/accessibility_private.swift

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -210,24 +210,3 @@ fileprivate struct SR2579 {
210210
private var outerProperty = Inner().innerProperty // expected-warning {{property should not be declared in this context because its type 'SR2579.Inner.InnerPrivateType' uses a private type}}
211211
var outerProperty2 = Inner().innerProperty // expected-warning {{property should be declared private because its type 'SR2579.Inner.InnerPrivateType' uses a private type}}
212212
}
213-
214-
// FIXME: Dependent member lookup of typealiases is not subject
215-
// to accessibility checking.
216-
struct Generic<T> {
217-
fileprivate typealias Dependent = T
218-
}
219-
220-
var x: Generic<Int>.Dependent = 3
221-
// expected-error@-1 {{variable must be declared private or fileprivate because its type uses a fileprivate type}}
222-
223-
func internalFuncWithFileprivateAlias() -> Generic<Int>.Dependent {
224-
// expected-error@-1 {{function must be declared private or fileprivate because its result uses a fileprivate type}}
225-
return 3
226-
}
227-
228-
private func privateFuncWithFileprivateAlias() -> Generic<Int>.Dependent {
229-
return 3
230-
}
231-
232-
// FIXME: No error here
233-
var y = privateFuncWithFileprivateAlias()
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// RUN: %target-typecheck-verify-swift -swift-version 4
2+
3+
public protocol P {
4+
associatedtype Element
5+
6+
func f() -> Element
7+
}
8+
9+
struct S<T> : P {
10+
func f() -> T { while true {} }
11+
}
12+
13+
public struct G<T> {
14+
typealias A = S<T> // expected-note {{type declared here}}
15+
16+
public func foo<U : P>(u: U) where U.Element == A.Element {}
17+
// expected-error@-1 {{instance method cannot be declared public because its generic requirement uses an internal type}}
18+
}
19+
20+
public final class ReplayableGenerator<S: Sequence> : IteratorProtocol {
21+
typealias Sequence = S // expected-note {{type declared here}}
22+
public typealias Element = Sequence.Iterator.Element // expected-error {{type alias cannot be declared public because its underlying type uses an internal type}}
23+
24+
public func next() -> Element? {
25+
return nil
26+
}
27+
}
28+
29+
// FIXME: Dependent member lookup of typealiases is not subject
30+
// to accessibility checking.
31+
struct Generic<T> {
32+
fileprivate typealias Dependent = T
33+
}
34+
35+
var x: Generic<Int>.Dependent = 3 // expected-error {{variable must be declared private or fileprivate because its type uses a fileprivate type}}
36+
37+
func internalFuncWithFileprivateAlias() -> Generic<Int>.Dependent { // expected-error {{function must be declared private or fileprivate because its result uses a fileprivate type}}
38+
return 3
39+
}
40+
41+
private func privateFuncWithFileprivateAlias() -> Generic<Int>.Dependent {
42+
return 3
43+
}
44+
45+
// FIXME: No error here
46+
var y = privateFuncWithFileprivateAlias()

0 commit comments

Comments
 (0)