Skip to content

Commit c1c9f4d

Browse files
authored
Merge pull request #4914 from DougGregor/keypath-crash-28061409
2 parents 821cdf3 + d225a21 commit c1c9f4d

File tree

2 files changed

+26
-10
lines changed

2 files changed

+26
-10
lines changed

lib/Sema/TypeCheckExprObjC.cpp

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,8 @@ Optional<Type> TypeChecker::checkObjCKeyPathExpr(DeclContext *dc,
161161

162162
// Local function to perform name lookup for the current index.
163163
auto performLookup = [&](unsigned idx, Identifier componentName,
164-
SourceLoc componentNameLoc) -> LookupResult {
164+
SourceLoc componentNameLoc,
165+
Type &lookupType) -> LookupResult {
165166
if (state == Beginning)
166167
return lookupUnqualified(dc, componentName, componentNameLoc);
167168

@@ -170,7 +171,6 @@ Optional<Type> TypeChecker::checkObjCKeyPathExpr(DeclContext *dc,
170171
// Determine the type in which the lookup should occur. If we have
171172
// a bridged value type, this will be the Objective-C class to
172173
// which it is bridged.
173-
Type lookupType;
174174
if (auto bridgedClass = Context.getBridgedToObjC(dc, currentType))
175175
lookupType = bridgedClass;
176176
else
@@ -210,15 +210,17 @@ Optional<Type> TypeChecker::checkObjCKeyPathExpr(DeclContext *dc,
210210
}
211211

212212
// Look for this component.
213-
LookupResult lookup = performLookup(idx, componentName, componentNameLoc);
213+
Type lookupType;
214+
LookupResult lookup = performLookup(idx, componentName, componentNameLoc,
215+
lookupType);
214216

215217
// If we didn't find anything, try to apply typo-correction.
216218
bool resultsAreFromTypoCorrection = false;
217219
if (!lookup) {
218-
performTypoCorrection(dc, DeclRefKind::Ordinary, currentType,
220+
performTypoCorrection(dc, DeclRefKind::Ordinary, lookupType,
219221
componentName, componentNameLoc,
220-
(currentType ? defaultMemberTypeLookupOptions
221-
: defaultUnqualifiedLookupOptions),
222+
(lookupType ? defaultMemberTypeLookupOptions
223+
: defaultUnqualifiedLookupOptions),
222224
lookup);
223225

224226
if (currentType)
@@ -263,7 +265,7 @@ Optional<Type> TypeChecker::checkObjCKeyPathExpr(DeclContext *dc,
263265
if (resultsAreFromTypoCorrection)
264266
break;
265267

266-
if (currentType)
268+
if (lookupType)
267269
diagnose(componentNameLoc, diag::ambiguous_member_overload_set,
268270
componentName);
269271
else
@@ -325,9 +327,9 @@ Optional<Type> TypeChecker::checkObjCKeyPathExpr(DeclContext *dc,
325327
}
326328

327329
Type newType;
328-
if (currentType && !currentType->isAnyObject()) {
329-
newType = currentType->getTypeOfMember(dc->getParentModule(), type,
330-
this);
330+
if (lookupType && !lookupType->isAnyObject()) {
331+
newType = lookupType->getTypeOfMember(dc->getParentModule(), type,
332+
this);
331333
} else {
332334
newType = type->getDeclaredInterfaceType();
333335
}

test/expr/unary/keypath/keypath.swift

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,16 @@ class C {
3333
var nonObjC: String? // expected-note{{add '@objc' to expose this var to Objective-C}}{{3-3=@objc }}
3434
}
3535

36+
extension NSArray {
37+
@objc class Foo : NSObject {
38+
@objc var propString: String = ""
39+
}
40+
}
41+
42+
extension Array {
43+
typealias Foo = NSArray.Foo
44+
}
45+
3646
func testKeyPath(a: A, b: B) {
3747
// Property
3848
let _: String = #keyPath(A.propB)
@@ -84,6 +94,10 @@ func testKeyPath(a: A, b: B) {
8494

8595
// Property with keyword name.
8696
let _: String = #keyPath(A.repeat)
97+
98+
// Nested type of a bridged type (rdar://problem/28061409).
99+
typealias IntArray = [Int]
100+
let _: String = #keyPath(IntArray.Foo.propString)
87101
}
88102

89103
func testAsStaticString() {

0 commit comments

Comments
 (0)