Skip to content

Commit 53cfe01

Browse files
authored
Merge pull request swiftlang#35910 from slavapestov/gsb-unresolved-nested-type-of-concrete-type-5.4
GSB: Better handling of unresolved DependentMemberTypes in maybeResolveEquivalenceClass() [5.4]
2 parents 1a690fc + 797a057 commit 53cfe01

File tree

3 files changed

+58
-20
lines changed

3 files changed

+58
-20
lines changed

lib/AST/GenericSignatureBuilder.cpp

Lines changed: 38 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1821,6 +1821,18 @@ static int compareAssociatedTypes(AssociatedTypeDecl *assocType1,
18211821
return 0;
18221822
}
18231823

1824+
static void lookupConcreteNestedType(NominalTypeDecl *decl,
1825+
Identifier name,
1826+
SmallVectorImpl<TypeDecl *> &concreteDecls) {
1827+
SmallVector<ValueDecl *, 2> foundMembers;
1828+
decl->getParentModule()->lookupQualified(
1829+
decl, DeclNameRef(name),
1830+
NL_QualifiedDefault | NL_OnlyTypes | NL_ProtocolMembers,
1831+
foundMembers);
1832+
for (auto member : foundMembers)
1833+
concreteDecls.push_back(cast<TypeDecl>(member));
1834+
}
1835+
18241836
TypeDecl *EquivalenceClass::lookupNestedType(
18251837
GenericSignatureBuilder &builder,
18261838
Identifier name,
@@ -1893,19 +1905,9 @@ TypeDecl *EquivalenceClass::lookupNestedType(
18931905
// FIXME: Shouldn't we always look here?
18941906
if (!bestAssocType && concreteDecls.empty()) {
18951907
Type typeToSearch = concreteType ? concreteType : superclass;
1896-
auto *decl = typeToSearch ? typeToSearch->getAnyNominal() : nullptr;
1897-
if (decl) {
1898-
SmallVector<ValueDecl *, 2> foundMembers;
1899-
decl->getParentModule()->lookupQualified(
1900-
decl, DeclNameRef(name),
1901-
NL_QualifiedDefault | NL_OnlyTypes | NL_ProtocolMembers,
1902-
foundMembers);
1903-
for (auto member : foundMembers) {
1904-
if (auto type = dyn_cast<TypeDecl>(member)) {
1905-
concreteDecls.push_back(type);
1906-
}
1907-
}
1908-
}
1908+
if (typeToSearch)
1909+
if (auto *decl = typeToSearch->getAnyNominal())
1910+
lookupConcreteNestedType(decl, name, concreteDecls);
19091911
}
19101912

19111913
// Infer same-type constraints among same-named associated type anchors.
@@ -3560,8 +3562,6 @@ static Type substituteConcreteType(Type parentType,
35603562
if (parentType->is<ErrorType>())
35613563
return parentType;
35623564

3563-
assert(concreteDecl);
3564-
35653565
auto *dc = concreteDecl->getDeclContext();
35663566

35673567
// Form an unsubstituted type referring to the given type declaration,
@@ -3598,10 +3598,31 @@ ResolvedType GenericSignatureBuilder::maybeResolveEquivalenceClass(
35983598
resolutionKind,
35993599
wantExactPotentialArchetype);
36003600
if (!resolvedBase) return resolvedBase;
3601+
36013602
// If the base is concrete, so is this member.
36023603
if (auto parentType = resolvedBase.getAsConcreteType()) {
3603-
auto concreteType = substituteConcreteType(parentType,
3604-
depMemTy->getAssocType());
3604+
TypeDecl *concreteDecl = depMemTy->getAssocType();
3605+
if (!concreteDecl) {
3606+
// If we have an unresolved dependent member type, perform a
3607+
// name lookup.
3608+
if (auto *decl = parentType->getAnyNominal()) {
3609+
SmallVector<TypeDecl *, 2> concreteDecls;
3610+
lookupConcreteNestedType(decl, depMemTy->getName(), concreteDecls);
3611+
3612+
if (concreteDecls.empty())
3613+
return ResolvedType::forUnresolved(nullptr);
3614+
3615+
auto bestConcreteTypeIter =
3616+
std::min_element(concreteDecls.begin(), concreteDecls.end(),
3617+
[](TypeDecl *type1, TypeDecl *type2) {
3618+
return TypeDecl::compare(type1, type2) < 0;
3619+
});
3620+
3621+
concreteDecl = *bestConcreteTypeIter;
3622+
}
3623+
}
3624+
3625+
auto concreteType = substituteConcreteType(parentType, concreteDecl);
36053626
return ResolvedType::forConcrete(concreteType);
36063627
}
36073628

validation-test/compiler_crashers_2/rdar56398071.swift renamed to validation-test/compiler_crashers_2_fixed/rdar56398071.swift

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
// RUN: not --crash %target-swift-frontend -primary-file %s -emit-silgen
2-
3-
// REQUIRES: asserts
1+
// RUN: %target-swift-frontend -primary-file %s -emit-ir
42

53
public protocol WrappedSignedInteger: SignedInteger where Stride == Int {
64
typealias WrappedInteger = Int
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// RUN: %target-swift-frontend -emit-ir %s
2+
3+
public struct LowerModel {
4+
public typealias Index = Int
5+
}
6+
7+
public protocol LowerChildA {
8+
typealias Model = LowerModel
9+
typealias ModelIndex = Model.Index
10+
}
11+
12+
public protocol LowerChildB {
13+
typealias Model = LowerModel
14+
typealias ModelIndex = Model.Index
15+
}
16+
17+
public protocol Parent: LowerChildA & LowerChildB {}
18+
19+
public func foo<T : Parent>(_: T, _: T.Model, _: T.ModelIndex) {}

0 commit comments

Comments
 (0)