Sema: NSValue-to-value-type casts are failable and should be checked.

In Swift 4 mode, no longer consider e.g. 'nsNumber as Int' or 'nsValue as NSRange' to be valid coercions. This would break compatibility with Swift 3, so in Swift 3 mode, accept the coercion, but *also* accept a checked cast without a warning, and raise a migration warning about the unchecked coercion.
This commit is contained in:
Joe Groff
2017-01-09 17:02:05 -08:00
parent 5c0afe93bc
commit c03371afc1
15 changed files with 545 additions and 139 deletions

View File

@@ -2414,7 +2414,7 @@ ConstraintSystem::simplifyCheckedCastConstraint(
};
do {
// Dig out the fixed type to which this type refers.
// Dig out the fixed type this type refers to.
fromType = getFixedTypeRecursive(fromType, flags, /*wantRValue=*/true);
// If we hit a type variable without a fixed type, we can't
@@ -2422,7 +2422,7 @@ ConstraintSystem::simplifyCheckedCastConstraint(
if (fromType->isTypeVariableOrMember())
return formUnsolved();
// Dig out the fixed type to which this type refers.
// Dig out the fixed type this type refers to.
toType = getFixedTypeRecursive(toType, flags, /*wantRValue=*/true);
// If we hit a type variable without a fixed type, we can't
@@ -2512,7 +2512,8 @@ ConstraintSystem::simplifyCheckedCastConstraint(
}
case CheckedCastKind::Coercion:
case CheckedCastKind::BridgingCast:
case CheckedCastKind::BridgingCoercion:
case CheckedCastKind::Swift3BridgingDowncast:
case CheckedCastKind::Unresolved:
llvm_unreachable("Not a valid result");
}
@@ -3397,6 +3398,15 @@ ConstraintSystem::simplifyBridgingConstraint(Type type1,
Type bridgedValueType;
if (auto objcClass = TC.Context.getBridgedToObjC(DC, unwrappedToType,
&bridgedValueType)) {
// Bridging NSNumber to NSValue is one-way, since there are multiple Swift
// value types that bridge to those object types. It requires a checked
// cast to get back.
// We accepted these coercions in Swift 3 mode, so we have to live with
// them (but give a warning) in that language mode.
if (!TC.Context.LangOpts.isSwiftVersion3()
&& TC.isObjCClassWithMultipleSwiftBridgedTypes(objcClass, DC))
return SolutionKind::Error;
// If the bridged value type is generic, the generic arguments
// must either match or be bridged.
// FIXME: This should be an associated type of the protocol.