Skip to content

Commit 0cfded0

Browse files
committed
Fix two issues with typealiases in protocol extensions (#20654)
- The GenericSignatureBuilder assumed it didn't have to look in protocol extensions to resolve member types. - Serialization was incorrectly filtering out such typealiases when trying to resolve a cross-module reference to one. rdar://problem/46103190 (cherry picked from commit 1f25ea5)
1 parent 0b634f1 commit 0cfded0

File tree

7 files changed

+50
-9
lines changed

7 files changed

+50
-9
lines changed

lib/AST/GenericSignatureBuilder.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2031,9 +2031,7 @@ TypeDecl *EquivalenceClass::lookupNestedType(
20312031
ProtocolDecl *proto = conforms.first;
20322032

20332033
// Look for an associated type and/or concrete type with this name.
2034-
auto flags = OptionSet<NominalTypeDecl::LookupDirectFlags>();
2035-
flags |= NominalTypeDecl::LookupDirectFlags::IgnoreNewExtensions;
2036-
for (auto member : proto->lookupDirect(name, flags)) {
2034+
for (auto member : proto->lookupDirect(name)) {
20372035
// If this is an associated type, record whether it is the best
20382036
// associated type we've seen thus far.
20392037
if (auto assocType = dyn_cast<AssociatedTypeDecl>(member)) {

lib/Serialization/Deserialization.cpp

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1414,9 +1414,9 @@ ModuleFile::resolveCrossReference(ModuleDecl *baseModule, uint32_t pathLen) {
14141414
IdentifierID IID;
14151415
IdentifierID privateDiscriminator;
14161416
bool importedFromClang = false;
1417+
bool inProtocolExt = false;
14171418
XRefTypePathPieceLayout::readRecord(scratch, IID, privateDiscriminator,
1418-
/*inProtocolExt*/None,
1419-
importedFromClang);
1419+
inProtocolExt, importedFromClang);
14201420
if (privateDiscriminator)
14211421
goto giveUpFastPath;
14221422

@@ -1446,9 +1446,8 @@ ModuleFile::resolveCrossReference(ModuleDecl *baseModule, uint32_t pathLen) {
14461446
if (nestedType) {
14471447
SmallVector<ValueDecl *, 1> singleValueBuffer{nestedType};
14481448
filterValues(/*expectedTy*/Type(), extensionModule, genericSig,
1449-
/*isType*/true, /*inProtocolExt*/false,
1450-
importedFromClang, /*isStatic*/false, /*ctorInit*/None,
1451-
singleValueBuffer);
1449+
/*isType*/true, inProtocolExt, importedFromClang,
1450+
/*isStatic*/false, /*ctorInit*/None, singleValueBuffer);
14521451
if (!singleValueBuffer.empty()) {
14531452
values.assign({nestedType});
14541453
++NumNestedTypeShortcuts;

lib/Serialization/Serialization.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1894,10 +1894,12 @@ void Serializer::writeCrossReference(const DeclContext *DC, uint32_t pathLen) {
18941894
discriminator = containingFile->getDiscriminatorForPrivateValue(generic);
18951895
}
18961896

1897+
bool isProtocolExt = DC->getParent()->getExtendedProtocolDecl();
1898+
18971899
XRefTypePathPieceLayout::emitRecord(Out, ScratchRecord, abbrCode,
18981900
addDeclBaseNameRef(generic->getName()),
18991901
addDeclBaseNameRef(discriminator),
1900-
/*inProtocolExtension*/false,
1902+
isProtocolExt,
19011903
generic->hasClangNode());
19021904
break;
19031905
}

test/multifile/typealias/one-module/Inputs/library.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,9 @@ public enum Result<T, U>
55
}
66

77
public typealias GenericResult<T> = Result<T, Error>
8+
9+
public protocol Rdar46103190 {}
10+
extension Rdar46103190 {
11+
public typealias Alias = String
12+
public typealias Map<K: Hashable> = [K: Self]
13+
}

test/multifile/typealias/one-module/main.swift

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,18 @@
55

66
func testFunction<T>(withCompletion completion: (Result<T, Error>) -> Void) { }
77
testFunction { (result: GenericResult<Int>) in }
8+
9+
extension Rdar46103190 {
10+
public typealias AnotherAlias = Self.Alias
11+
public typealias StringMap = Map<String>
12+
}
13+
14+
typealias Rdar46103190Alias<R: Rdar46103190> = R.Map<String>
15+
16+
struct Rdar46103190Impl: Rdar46103190 {}
17+
18+
func test46103190() {
19+
let _: String = Rdar46103190Impl.AnotherAlias()
20+
let _: [String: Rdar46103190Impl] = Rdar46103190Impl.StringMap()
21+
let _: [String: Rdar46103190Impl] = Rdar46103190Alias()
22+
}

test/multifile/typealias/two-modules/Inputs/library.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,9 @@ public enum Result<T, U>
55
}
66

77
public typealias GenericResult<T> = Result<T, Error>
8+
9+
public protocol Rdar46103190 {}
10+
extension Rdar46103190 {
11+
public typealias Alias = String
12+
public typealias Map<K: Hashable> = [K: Self]
13+
}

test/multifile/typealias/two-modules/main.swift

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,18 @@ import enum library.Result
1414

1515
func testFunction<T>(withCompletion completion: (Result<T, Error>) -> Void) { }
1616
testFunction { (result: GenericResult<Int>) in }
17+
18+
extension Rdar46103190 {
19+
public typealias AnotherAlias = Self.Alias
20+
public typealias StringMap = Map<String>
21+
}
22+
23+
typealias Rdar46103190Alias<R: Rdar46103190> = R.Map<String>
24+
25+
struct Rdar46103190Impl: Rdar46103190 {}
26+
27+
func test46103190() {
28+
let _: String = Rdar46103190Impl.AnotherAlias()
29+
let _: [String: Rdar46103190Impl] = Rdar46103190Impl.StringMap()
30+
let _: [String: Rdar46103190Impl] = Rdar46103190Alias()
31+
}

0 commit comments

Comments
 (0)