Skip to content

Commit c61896f

Browse files
authored
Merge pull request #35485 from slavapestov/fix-crash-with-invalid-superclass-5.4
Sema: Fix a couple of crash-on-invalid problems with class inheritance [5.4]
2 parents 9121e41 + a934fa1 commit c61896f

File tree

4 files changed

+48
-10
lines changed

4 files changed

+48
-10
lines changed

lib/Sema/CodeSynthesis.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,12 @@ Expr *swift::buildSelfReference(VarDecl *selfDecl,
6262
selfTy = metaTy->getInstanceType();
6363
}
6464
selfTy = selfTy->getSuperclass();
65+
if (!selfTy) {
66+
// Error recovery path. We end up here if getSuperclassDecl() succeeds
67+
// but getSuperclass() fails (because, for instance, a generic parameter
68+
// of a generic nominal type cannot be resolved).
69+
selfTy = ErrorType::get(ctx);
70+
}
6571
if (isMetatype)
6672
selfTy = MetatypeType::get(selfTy);
6773

@@ -70,7 +76,7 @@ Expr *swift::buildSelfReference(VarDecl *selfDecl,
7076

7177
// If no conversion type was specified, or we're already at that type, we're
7278
// done.
73-
if (!convertTy || convertTy->isEqual(selfTy))
79+
if (!convertTy || convertTy->isEqual(selfTy) || selfTy->is<ErrorType>())
7480
return superRef;
7581

7682
// Insert the appropriate expr to handle the upcast.

lib/Sema/TypeCheckNameLookup.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -151,12 +151,12 @@ namespace {
151151
auto conformance = DC->getParentModule()->lookupConformance(
152152
conformingType, foundProto);
153153
if (conformance.isInvalid()) {
154-
// If there's no conformance, we have an existential
155-
// and we found a member from one of the protocols, and
156-
// not a class constraint if any.
157-
assert(foundInType->isExistentialType() || foundInType->hasError());
158-
if (foundInType->isExistentialType())
154+
if (foundInType->isExistentialType()) {
155+
// If there's no conformance, we have an existential
156+
// and we found a member from one of the protocols, and
157+
// not a class constraint if any.
159158
addResult(found);
159+
}
160160
return;
161161
}
162162

lib/Sema/TypeCheckStorage.cpp

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -717,10 +717,16 @@ static Expr *buildStorageReference(AccessorDecl *accessor,
717717
// Adjust the self type of the access to refer to the relevant superclass.
718718
auto *baseClass = override->getDeclContext()->getSelfClassDecl();
719719
selfTypeForAccess = selfTypeForAccess->getSuperclassForDecl(baseClass);
720-
subs =
721-
selfTypeForAccess->getContextSubstitutionMap(
722-
accessor->getParentModule(),
723-
baseClass);
720+
721+
// Error recovery path. We get an ErrorType here if getSuperclassForDecl()
722+
// fails (because, for instance, a generic parameter of a generic nominal
723+
// type cannot be resolved).
724+
if (!selfTypeForAccess->is<ErrorType>()) {
725+
subs =
726+
selfTypeForAccess->getContextSubstitutionMap(
727+
accessor->getParentModule(),
728+
baseClass);
729+
}
724730

725731
storage = override;
726732

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// RUN: not %target-swift-frontend -emit-ir %s
2+
3+
public protocol Ungulate {
4+
func eat()
5+
}
6+
7+
public class Horse<T> : Ungulate {
8+
public var saddle: AnyObject? = nil
9+
10+
public func eat() {}
11+
}
12+
13+
public struct Hay {}
14+
15+
// Here, ClassDecl::getSuperclassDecl() will find the 'Horse' class, but
16+
// ClassDecl::getSuperclass() will return ErrorType because the generic
17+
// argument 'DoesNotExist' cannot be resolved.
18+
public class Pony : Horse<DoesNotExist> {
19+
public override var saddle: AnyObject? {
20+
didSet {}
21+
}
22+
23+
public func eat(_: Hay) {
24+
eat()
25+
}
26+
}

0 commit comments

Comments
 (0)