Skip to content

Commit 646397a

Browse files
authored
Merge pull request swiftlang#39965 from slavapestov/parent-of-concrete-is-concrete
AST: GenericEnvironment::getOrCreateArchetypeFromInterfaceType() needs to handle case where parent of concrete anchor is concrete
2 parents 94d824a + 215fbf1 commit 646397a

File tree

2 files changed

+47
-37
lines changed

2 files changed

+47
-37
lines changed

lib/AST/GenericEnvironment.cpp

Lines changed: 19 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -119,11 +119,7 @@ GenericEnvironment::getOrCreateArchetypeFromInterfaceType(Type depType) {
119119

120120
auto requirements = genericSig->getLocalRequirements(depType);
121121

122-
// FIXME: With the RequirementMachine, we will always have an anchor.
123-
if (requirements.concreteType && !requirements.anchor) {
124-
if (requirements.concreteType->is<ErrorType>())
125-
return requirements.concreteType;
126-
122+
if (requirements.concreteType) {
127123
return mapTypeIntoContext(requirements.concreteType,
128124
conformanceLookupFn);
129125
}
@@ -140,9 +136,7 @@ GenericEnvironment::getOrCreateArchetypeFromInterfaceType(Type depType) {
140136
if (auto depMemTy = requirements.anchor->getAs<DependentMemberType>()) {
141137
parentArchetype =
142138
getOrCreateArchetypeFromInterfaceType(depMemTy->getBase())
143-
->getAs<ArchetypeType>();
144-
if (!parentArchetype)
145-
return ErrorType::get(depMemTy);
139+
->castTo<ArchetypeType>();
146140

147141
auto name = depMemTy->getName();
148142
if (auto type = parentArchetype->getNestedTypeIfKnown(name))
@@ -156,39 +150,27 @@ GenericEnvironment::getOrCreateArchetypeFromInterfaceType(Type depType) {
156150
addMapping(genericParam, ErrorType::get(ctx));
157151
}
158152

159-
Type result;
160-
161-
// If this equivalence class is mapped to a concrete type, produce that
162-
// type.
163-
if (requirements.concreteType) {
164-
result = mapTypeIntoContext(requirements.concreteType,
165-
conformanceLookupFn);
166-
} else {
167-
// Substitute into the superclass.
168-
Type superclass = requirements.superclass;
169-
if (superclass && superclass->hasTypeParameter()) {
170-
superclass = mapTypeIntoContext(superclass,
171-
conformanceLookupFn);
172-
if (superclass->is<ErrorType>())
173-
superclass = Type();
174-
}
175-
176-
if (parentArchetype) {
177-
auto *depMemTy = requirements.anchor->castTo<DependentMemberType>();
178-
result = NestedArchetypeType::getNew(ctx, parentArchetype, depMemTy,
179-
requirements.protos, superclass,
180-
requirements.layout);
181-
} else {
182-
result = PrimaryArchetypeType::getNew(ctx, this, genericParam,
183-
requirements.protos, superclass,
184-
requirements.layout);
185-
}
153+
// Substitute into the superclass.
154+
Type superclass = requirements.superclass;
155+
if (superclass && superclass->hasTypeParameter()) {
156+
superclass = mapTypeIntoContext(superclass,
157+
conformanceLookupFn);
158+
if (superclass->is<ErrorType>())
159+
superclass = Type();
186160
}
187161

188-
// Cache the new archetype for future lookups.
189-
if (auto depMemTy = requirements.anchor->getAs<DependentMemberType>()) {
162+
Type result;
163+
164+
if (parentArchetype) {
165+
auto *depMemTy = requirements.anchor->castTo<DependentMemberType>();
166+
result = NestedArchetypeType::getNew(ctx, parentArchetype, depMemTy,
167+
requirements.protos, superclass,
168+
requirements.layout);
190169
parentArchetype->registerNestedType(depMemTy->getName(), result);
191170
} else {
171+
result = PrimaryArchetypeType::getNew(ctx, this, genericParam,
172+
requirements.protos, superclass,
173+
requirements.layout);
192174
addMapping(genericParam, result);
193175
}
194176

test/Generics/rdar84734584.swift

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// RUN: %target-typecheck-verify-swift
2+
3+
protocol P1 {
4+
associatedtype T1
5+
}
6+
7+
protocol P2 {
8+
associatedtype T2 : P1
9+
}
10+
11+
struct S1 : P1 {
12+
typealias T1 = S2
13+
}
14+
15+
struct S2 {}
16+
17+
func foo<X1: P2, X2: P1>(_: X1, _: X2)
18+
where X2.T1 == S2 { }
19+
20+
func bar<X1: P2, X2: P1>(x: X1, u: X2, uu: X2.T1)
21+
where X1.T2 == S1, X2.T1: P1, X2.T1.T1 == S2 {
22+
// this call should type-check successfully
23+
foo(x, uu)
24+
25+
// so should this
26+
let _: S2.Type = X2.T1.T1.self
27+
let _: S2.Type = X1.T2.T1.self
28+
}

0 commit comments

Comments
 (0)