Skip to content

Commit 49f2330

Browse files
committed
[Type checker] Make sure we wire up all generic parameters for extensions.
Fixes a type checker crash found while working on detangling to metadata.
1 parent 176386c commit 49f2330

File tree

2 files changed

+40
-4
lines changed

2 files changed

+40
-4
lines changed

lib/Sema/TypeChecker.cpp

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,28 @@ static void prepareGenericParamList(GenericParamList *genericParams) {
300300
prepareGenericParamList(outerGenericParams);
301301
}
302302

303+
/// Ensure that the outer generic parameters of the given generic
304+
/// context have been configured.
305+
static void configureOuterGenericParams(const GenericContext *dc) {
306+
auto genericParams = dc->getGenericParams();
307+
if (!genericParams) return;
308+
309+
if (genericParams->getOuterParameters()) return;
310+
311+
DeclContext *outerDC = dc->getParent();
312+
while (!outerDC->isModuleScopeContext()) {
313+
if (auto outerDecl = outerDC->getAsDecl()) {
314+
if (auto outerGenericDC = outerDecl->getAsGenericContext()) {
315+
genericParams->setOuterParameters(outerGenericDC->getGenericParams());
316+
configureOuterGenericParams(outerGenericDC);
317+
return;
318+
}
319+
}
320+
321+
outerDC = outerDC->getParent();
322+
}
323+
}
324+
303325
/// Bind the given extension to the given nominal type.
304326
static void bindExtensionToNominal(ExtensionDecl *ext,
305327
NominalTypeDecl *nominal) {
@@ -313,10 +335,7 @@ static void bindExtensionToNominal(ExtensionDecl *ext,
313335
ext->setGenericParams(genericParams);
314336
} else if (auto genericParams = nominal->getGenericParamsOfContext()) {
315337
// Make sure the generic parameters are set up.
316-
if (auto nominalGenericParams = nominal->getGenericParams()) {
317-
nominalGenericParams->setOuterParameters(
318-
nominal->getDeclContext()->getGenericParamsOfContext());
319-
}
338+
configureOuterGenericParams(nominal);
320339

321340
// Clone the generic parameter list of a generic type.
322341
prepareGenericParamList(genericParams);

test/decl/ext/generic.swift

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,3 +175,20 @@ func foo() {
175175
func foo() -> Element.AssocType {}
176176
}
177177
}
178+
179+
// Deeply nested
180+
protocol P6 {
181+
associatedtype Assoc1
182+
associatedtype Assoc2
183+
}
184+
185+
struct A<T, U, V> {
186+
struct B<W, X, Y> {
187+
struct C<Z: P6> {
188+
}
189+
}
190+
}
191+
192+
extension A.B.C where T == V, X == Z.Assoc2 {
193+
func f() { }
194+
}

0 commit comments

Comments
 (0)