Skip to content

Commit 896773e

Browse files
Suyash SrijanSuyash Srijan
authored andcommitted
[typechecker] check for casts from existential types to concrete types
1 parent 091fa17 commit 896773e

File tree

1 file changed

+14
-7
lines changed

1 file changed

+14
-7
lines changed

lib/Sema/TypeCheckConstraints.cpp

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4028,8 +4028,7 @@ CheckedCastKind TypeChecker::typeCheckCheckedCast(Type fromType,
40284028
if (toType->isAnyObject() || fromType->isAnyObject())
40294029
return CheckedCastKind::ValueCast;
40304030

4031-
// A checked cast from Swift.Error to a type that does not conform to
4032-
// Swift.Error cannot succeed.
4031+
// A cast from an existential type to a concrete type does not succeed.
40334032
//
40344033
// struct S {}
40354034
// enum FooError: Error { case bar }
@@ -4040,11 +4039,19 @@ CheckedCastKind TypeChecker::typeCheckCheckedCast(Type fromType,
40404039
// print("Caught bar error")
40414040
// }
40424041
// }
4043-
auto exceptionType = getExceptionType(dc, SourceLoc());
4044-
if (fromType->isEqual(exceptionType)) {
4045-
if (!conformsToProtocol(toType, Context.getErrorDecl(), dc,
4046-
ConformanceCheckFlags::InExpression)) {
4047-
return failed();
4042+
if (fromExistential) {
4043+
if (auto NTD = toType->getAnyNominal()) {
4044+
if (NTD->getAllConformances().empty()) {
4045+
return failed();
4046+
}
4047+
4048+
auto protocolDecl =
4049+
dyn_cast_or_null<ProtocolDecl>(fromType->getAnyNominal());
4050+
if (protocolDecl &&
4051+
!conformsToProtocol(toType, protocolDecl, dc,
4052+
ConformanceCheckFlags::InExpression)) {
4053+
return failed();
4054+
}
40484055
}
40494056
}
40504057

0 commit comments

Comments
 (0)