Skip to content

Commit aef551b

Browse files
authored
Merge pull request #35907 from slavapestov/gsb-unresolved-nested-type-of-concrete-type
GSB: Better handling of unresolved DependentMemberTypes in maybeResolveEquivalenceClass()
2 parents 9de5afd + 5acd795 commit aef551b

File tree

4 files changed

+69
-20
lines changed

4 files changed

+69
-20
lines changed

lib/AST/GenericSignatureBuilder.cpp

Lines changed: 38 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1809,6 +1809,18 @@ static int compareAssociatedTypes(AssociatedTypeDecl *assocType1,
18091809
return 0;
18101810
}
18111811

1812+
static void lookupConcreteNestedType(NominalTypeDecl *decl,
1813+
Identifier name,
1814+
SmallVectorImpl<TypeDecl *> &concreteDecls) {
1815+
SmallVector<ValueDecl *, 2> foundMembers;
1816+
decl->getParentModule()->lookupQualified(
1817+
decl, DeclNameRef(name),
1818+
NL_QualifiedDefault | NL_OnlyTypes | NL_ProtocolMembers,
1819+
foundMembers);
1820+
for (auto member : foundMembers)
1821+
concreteDecls.push_back(cast<TypeDecl>(member));
1822+
}
1823+
18121824
TypeDecl *EquivalenceClass::lookupNestedType(
18131825
GenericSignatureBuilder &builder,
18141826
Identifier name,
@@ -1881,19 +1893,9 @@ TypeDecl *EquivalenceClass::lookupNestedType(
18811893
// FIXME: Shouldn't we always look here?
18821894
if (!bestAssocType && concreteDecls.empty()) {
18831895
Type typeToSearch = concreteType ? concreteType : superclass;
1884-
auto *decl = typeToSearch ? typeToSearch->getAnyNominal() : nullptr;
1885-
if (decl) {
1886-
SmallVector<ValueDecl *, 2> foundMembers;
1887-
decl->getParentModule()->lookupQualified(
1888-
decl, DeclNameRef(name),
1889-
NL_QualifiedDefault | NL_OnlyTypes | NL_ProtocolMembers,
1890-
foundMembers);
1891-
for (auto member : foundMembers) {
1892-
if (auto type = dyn_cast<TypeDecl>(member)) {
1893-
concreteDecls.push_back(type);
1894-
}
1895-
}
1896-
}
1896+
if (typeToSearch)
1897+
if (auto *decl = typeToSearch->getAnyNominal())
1898+
lookupConcreteNestedType(decl, name, concreteDecls);
18971899
}
18981900

18991901
// Infer same-type constraints among same-named associated type anchors.
@@ -3531,8 +3533,6 @@ static Type substituteConcreteType(Type parentType,
35313533
if (parentType->is<ErrorType>())
35323534
return parentType;
35333535

3534-
assert(concreteDecl);
3535-
35363536
auto *dc = concreteDecl->getDeclContext();
35373537

35383538
// Form an unsubstituted type referring to the given type declaration,
@@ -3569,10 +3569,31 @@ ResolvedType GenericSignatureBuilder::maybeResolveEquivalenceClass(
35693569
resolutionKind,
35703570
wantExactPotentialArchetype);
35713571
if (!resolvedBase) return resolvedBase;
3572+
35723573
// If the base is concrete, so is this member.
35733574
if (auto parentType = resolvedBase.getAsConcreteType()) {
3574-
auto concreteType = substituteConcreteType(parentType,
3575-
depMemTy->getAssocType());
3575+
TypeDecl *concreteDecl = depMemTy->getAssocType();
3576+
if (!concreteDecl) {
3577+
// If we have an unresolved dependent member type, perform a
3578+
// name lookup.
3579+
if (auto *decl = parentType->getAnyNominal()) {
3580+
SmallVector<TypeDecl *, 2> concreteDecls;
3581+
lookupConcreteNestedType(decl, depMemTy->getName(), concreteDecls);
3582+
3583+
if (concreteDecls.empty())
3584+
return ResolvedType::forUnresolved(nullptr);
3585+
3586+
auto bestConcreteTypeIter =
3587+
std::min_element(concreteDecls.begin(), concreteDecls.end(),
3588+
[](TypeDecl *type1, TypeDecl *type2) {
3589+
return TypeDecl::compare(type1, type2) < 0;
3590+
});
3591+
3592+
concreteDecl = *bestConcreteTypeIter;
3593+
}
3594+
}
3595+
3596+
auto concreteType = substituteConcreteType(parentType, concreteDecl);
35763597
return ResolvedType::forConcrete(concreteType);
35773598
}
35783599

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) {}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// RUN: not %target-swift-frontend -emit-ir %s
2+
3+
public protocol ProtoDelegate where Self.Manager.Delegate: Self {
4+
associatedtype Manager: ProtoManager
5+
func bind(to: Manager)
6+
}
7+
8+
public protocol ProtoManager where Self.Delegate.Manager: Self {
9+
associatedtype Delegate: ProtoDelegate
10+
var name: String { get }
11+
}

0 commit comments

Comments
 (0)