Skip to content

Commit 63e3a01

Browse files
committed
Memnber Type Lookups Shouldn't Recurse
When member type lookup is rooted at a typealias, it should not be possible for that lookup to see the typealias itself. This prevents recursively trying to resolve the underlying type, which used to be silently ignored when validateDecl bounced the caller back with an error type or a null type. Addresses rdar://56411408
1 parent 7b5dfd6 commit 63e3a01

File tree

3 files changed

+54
-28
lines changed

3 files changed

+54
-28
lines changed

lib/Sema/TypeCheckNameLookup.cpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -430,9 +430,15 @@ LookupTypeResult TypeChecker::lookupMemberType(DeclContext *dc,
430430
for (auto decl : decls) {
431431
auto *typeDecl = cast<TypeDecl>(decl);
432432

433-
auto memberType = typeDecl->getDeclaredInterfaceType();
433+
// HACK: Lookups rooted at a typealias are trying to look for its underlying
434+
// type so they shouldn't also find that same typealias.
435+
if (decl == dyn_cast<TypeAliasDecl>(dc)) {
436+
continue;
437+
}
434438

435439
if (isUnsupportedMemberTypeAccess(type, typeDecl)) {
440+
auto memberType = typeDecl->getDeclaredInterfaceType();
441+
436442
// Add the type to the result set, so that we can diagnose the
437443
// reference instead of just saying the member does not exist.
438444
if (types.insert(memberType->getCanonicalType()).second)
@@ -477,8 +483,8 @@ LookupTypeResult TypeChecker::lookupMemberType(DeclContext *dc,
477483
}
478484

479485
// Substitute the base into the member's type.
480-
memberType = substMemberTypeWithBase(dc->getParentModule(),
481-
typeDecl, type);
486+
auto memberType = substMemberTypeWithBase(dc->getParentModule(),
487+
typeDecl, type);
482488

483489
// If we haven't seen this type result yet, add it to the result set.
484490
if (types.insert(memberType->getCanonicalType()).second)

test/decl/circularity.swift

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
// RUN: %target-typecheck-verify-swift
2+
3+
// N.B. Validating the pattern binding initializer for `pickMe` used to cause
4+
// recursive validation of the VarDecl. Check that we don't regress now that
5+
// this isn't the case.
6+
public struct Cyclic {
7+
static func pickMe(please: Bool) -> Int { return 42 }
8+
public static let pickMe = Cyclic.pickMe(please: true)
9+
}
10+
11+
struct Node {}
12+
struct Parameterized<Value, Format> {
13+
func please<NewValue>(_ transform: @escaping (_ otherValue: NewValue) -> Value) -> Parameterized<NewValue, Format> {
14+
fatalError()
15+
}
16+
}
17+
18+
extension Parameterized where Value == [Node], Format == String {
19+
static var pickMe: Parameterized {
20+
fatalError()
21+
}
22+
}
23+
24+
extension Parameterized where Value == Node, Format == String {
25+
static let pickMe = Parameterized<[Node], String>.pickMe.please { [$0] }
26+
}
27+
28+
enum Loop: Circle {
29+
struct DeLoop { }
30+
}
31+
32+
protocol Circle {
33+
typealias DeLoop = Loop.DeLoop
34+
}
35+
36+
class Base {
37+
static func foo(_ x: Int) {}
38+
}
39+
40+
class Sub: Base {
41+
var foo = { () -> Int in
42+
let x = 42
43+
return foo(1) // expected-error {{variable used within its own initial value}}
44+
}()
45+
}

test/decl/overload.swift

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -609,28 +609,3 @@ enum SR_10084_E_16 {
609609
typealias Z = Int // expected-note {{'Z' previously declared here}}
610610
case Z // expected-error {{invalid redeclaration of 'Z'}}
611611
}
612-
613-
// N.B. Validating the pattern binding initializer for `pickMe` used to cause
614-
// recursive validation of the VarDecl. Check that we don't regress now that
615-
// this isn't the case.
616-
public struct Cyclic {
617-
static func pickMe(please: Bool) -> Int { return 42 }
618-
public static let pickMe = Cyclic.pickMe(please: true)
619-
}
620-
621-
struct Node {}
622-
struct Parameterized<Value, Format> {
623-
func please<NewValue>(_ transform: @escaping (_ otherValue: NewValue) -> Value) -> Parameterized<NewValue, Format> {
624-
fatalError()
625-
}
626-
}
627-
628-
extension Parameterized where Value == [Node], Format == String {
629-
static var pickMe: Parameterized {
630-
fatalError()
631-
}
632-
}
633-
634-
extension Parameterized where Value == Node, Format == String {
635-
static let pickMe = Parameterized<[Node], String>.pickMe.please { [$0] }
636-
}

0 commit comments

Comments
 (0)