Skip to content

Commit ec3acbf

Browse files
[TypeCheckConstraints] Adjusting logic around generic substitution to check both subtype and supertype
1 parent 8ea2a69 commit ec3acbf

File tree

2 files changed

+12
-9
lines changed

2 files changed

+12
-9
lines changed

lib/Sema/TypeCheckConstraints.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3105,7 +3105,7 @@ CheckedCastKind TypeChecker::typeCheckCheckedCast(Type fromType,
31053105
}
31063106

31073107
// In the context of collection element we just return a value cast
3108-
// becasue there may be situation where this can be convertible
3108+
// because there may be situations where this can be convertible
31093109
// at runtime. e.g.
31103110
//
31113111
// func f(a: [Any], b: [AnyObject]) {
@@ -3568,9 +3568,9 @@ CheckedCastKind TypeChecker::typeCheckCheckedCast(Type fromType,
35683568
// non-final class because it's possible that we might have a subclass
35693569
// that conforms to the protocol.
35703570
//
3571-
// Also, relax the restriction when toType is a stdlib collection type
3571+
// Also, relax the restriction when toType is a stdlib collection
35723572
// (Array, Set, Dictionary) that could have conditional conformances
3573-
// because of custom casting implemented for those types e.g.
3573+
// because of custom casting mechanism implemented for those types e.g.
35743574
//
35753575
// func encodable(_ value: Encodable) {
35763576
// _ = value as! [String : Encodable]
@@ -3651,8 +3651,10 @@ CheckedCastKind TypeChecker::typeCheckCheckedCast(Type fromType,
36513651

36523652
// If it is possible to substitute the generic arguments of source type
36533653
// with the destination generic archetypes, we are performing what looks
3654-
// like an upcast except it rebinds generic parameters.
3655-
if (toType->isBindableTo(fromType))
3654+
// like an upcast except it rebinds generic parameters. Or substitute
3655+
// destination to source generic archetypes, where we are performing
3656+
// what looks like an downcast except it also rebinds generic parameters.
3657+
if (toType->isBindableTo(fromType) || fromType->isBindableTo(toType))
36563658
return CheckedCastKind::ValueCast;
36573659

36583660
// Objective-C metaclasses are subclasses of NSObject in the ObjC runtime,

test/Constraints/casts.swift

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -387,12 +387,13 @@ func tests_SR13088_false_positive_always_fail_casts() {
387387
_ = b as? [String?] // Ok
388388

389389
// SR-13035
390-
func SR13035<SomeError: SR13035Error>(_ mockResult: Result<String, ChildError>, _: Result<String, SomeError>) {
391-
let _ = mockResult as? Result<String, SomeError> // Ok
390+
func SR13035<SomeError: SR13035Error>(_ child: Result<String, ChildError>, _: Result<String, SomeError>) {
391+
let _ = child as? Result<String, SomeError> // Ok
392392
}
393393

394-
func SR13035_1<SomeError: SR13035Error, Child: ChildError>(_ mockResult: Result<String, Child>, _: Result<String, SomeError>) {
395-
let _ = mockResult as? Result<String, SomeError> // Ok
394+
func SR13035_1<SomeError: SR13035Error, Child: ChildError>(_ child: Result<String, Child>, parent: Result<String, SomeError>) {
395+
_ = child as? Result<String, SomeError> // Ok
396+
_ = parent as? Result<String, Child> // OK
396397
}
397398

398399
// SR-11434 and SR-12321

0 commit comments

Comments
 (0)