Don't classify bridging casts as WillSucceed if the object-to-value cast can fail.

When casting from an object type to a bridged Swift value type, classifyDynamicCast would use the cast classification for the target type's bridged object type, which would be trivially WillSucceed for thinks like NSNumber-to-Int or NSError-to-SomeError, even though the bridging itself could fail. Fixing this fixes SR-2920|rdar://problem/31404281.
This commit is contained in:
Joe Groff
2017-05-11 19:37:58 -07:00
parent e353163b58
commit 4e9851b032
9 changed files with 242 additions and 187 deletions

View File

@@ -217,8 +217,8 @@ bool swift::isError(ModuleDecl *M, CanType Ty) {
M->getASTContext().getProtocol(KnownProtocolKind::Error);
if (errorTypeProto) {
// Find the conformance of the value type to _BridgedToObjectiveC.
// Check whether the type conforms to _BridgedToObjectiveC.
// Find the conformance of the value type to Error.
// Check whether the type conforms to Error.
auto conformance = M->lookupConformance(Ty, errorTypeProto, nullptr);
return conformance.hasValue();
}
@@ -636,9 +636,15 @@ swift::classifyDynamicCast(ModuleDecl *M,
if (Type ObjCTy = M->getASTContext().getBridgedToObjC(M, target)) {
// If the bridged ObjC type is known, check if
// source type can be cast into it.
return classifyDynamicCast(M, source,
auto canCastToBridgedType = classifyDynamicCast(M, source,
ObjCTy->getCanonicalType(),
/* isSourceTypeExact */ false, isWholeModuleOpts);
// Temper our enthusiasm if the bridge from the ObjC type to the target
// value type may fail.
if (canCastToBridgedType == DynamicCastFeasibility::WillSucceed
&& M->getASTContext().isObjCClassWithMultipleSwiftBridgedTypes(ObjCTy))
return DynamicCastFeasibility::MaySucceed;
return canCastToBridgedType;
}
return DynamicCastFeasibility::MaySucceed;
}