Skip to content

Commit 201c460

Browse files
committed
AST: Fix crash in getContextSubstitutions() when a class has a malformed superclass type
It is possible for getSuperclassDecl() to return a non-null type, while getSuperclass() returns an ErrorType. In this case, getContextSubstitutions() could crash because the walk of the superclass chain via getSuperclass() might not find the context class. Instead of crashing in asserts builds, let getContextSubstitutions() silently build an invalid substitution map here, just as it does in no-asserts builds.
1 parent 284fbf9 commit 201c460

File tree

2 files changed

+16
-2
lines changed

2 files changed

+16
-2
lines changed

lib/AST/Type.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3572,8 +3572,6 @@ TypeBase::getContextSubstitutions(const DeclContext *dc,
35723572
if (auto *ownerClass = dyn_cast<ClassDecl>(ownerNominal))
35733573
baseTy = baseTy->getSuperclassForDecl(ownerClass);
35743574

3575-
assert(ownerNominal == baseTy->getAnyNominal());
3576-
35773575
// Gather all of the substitutions for all levels of generic arguments.
35783576
auto genericSig = dc->getGenericSignatureOfContext();
35793577
if (!genericSig)
@@ -3583,6 +3581,9 @@ TypeBase::getContextSubstitutions(const DeclContext *dc,
35833581
unsigned n = params.size();
35843582

35853583
while (baseTy && n > 0) {
3584+
if (baseTy->is<ErrorType>())
3585+
break;
3586+
35863587
// For a bound generic type, gather the generic parameter -> generic
35873588
// argument substitutions.
35883589
if (auto boundGeneric = baseTy->getAs<BoundGenericType>()) {

test/decl/circularity.swift

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ extension SIMD3 where SIMD3.Scalar == Float {
5959
// Test case with circular overrides
6060
protocol P {
6161
associatedtype A
62+
// expected-note@-1 {{protocol requires nested type 'A'; do you want to add it?}}
6263
func run(a: A)
6364
}
6465

@@ -71,3 +72,15 @@ class C2: C1, P {
7172
// expected-error@-1 {{circular reference}}
7273
// expected-note@-2 2{{through reference here}}
7374
}
75+
76+
// Another crash to the above
77+
open class G1<A> {
78+
open func run(a: A) {}
79+
}
80+
81+
class C3: G1<A>, P {
82+
// expected-error@-1 {{type 'C3' does not conform to protocol 'P'}}
83+
// expected-error@-2 {{use of undeclared type 'A'}}
84+
override func run(a: A) {}
85+
// expected-error@-1 {{method does not override any method from its superclass}}
86+
}

0 commit comments

Comments
 (0)