@@ -4041,10 +4041,8 @@ CheckedCastKind TypeChecker::typeCheckCheckedCast(Type fromType,
4041
4041
}
4042
4042
4043
4043
// Check for casts between specific concrete types that cannot succeed.
4044
- ConstraintSystem cs (*this , dc, ConstraintSystemOptions ());
4045
-
4046
- if (auto toElementType = cs.isArrayType (toType)) {
4047
- if (auto fromElementType = cs.isArrayType (fromType)) {
4044
+ if (auto toElementType = ConstraintSystem::isArrayType (toType)) {
4045
+ if (auto fromElementType = ConstraintSystem::isArrayType (fromType)) {
4048
4046
switch (typeCheckCheckedCast (*fromElementType, *toElementType,
4049
4047
CheckedCastContextKind::None, dc,
4050
4048
SourceLoc (), nullptr , SourceRange ())) {
@@ -4066,8 +4064,8 @@ CheckedCastKind TypeChecker::typeCheckCheckedCast(Type fromType,
4066
4064
}
4067
4065
}
4068
4066
4069
- if (auto toKeyValue = cs. isDictionaryType (toType)) {
4070
- if (auto fromKeyValue = cs. isDictionaryType (fromType)) {
4067
+ if (auto toKeyValue = ConstraintSystem:: isDictionaryType (toType)) {
4068
+ if (auto fromKeyValue = ConstraintSystem:: isDictionaryType (fromType)) {
4071
4069
bool hasCoercion = false ;
4072
4070
enum { NoBridging, BridgingCoercion }
4073
4071
hasBridgingConversion = NoBridging;
@@ -4130,8 +4128,8 @@ CheckedCastKind TypeChecker::typeCheckCheckedCast(Type fromType,
4130
4128
}
4131
4129
}
4132
4130
4133
- if (auto toElementType = cs. isSetType (toType)) {
4134
- if (auto fromElementType = cs. isSetType (fromType)) {
4131
+ if (auto toElementType = ConstraintSystem:: isSetType (toType)) {
4132
+ if (auto fromElementType = ConstraintSystem:: isSetType (fromType)) {
4135
4133
switch (typeCheckCheckedCast (*fromElementType, *toElementType,
4136
4134
CheckedCastContextKind::None, dc,
4137
4135
SourceLoc (), nullptr , SourceRange ())) {
@@ -4254,9 +4252,9 @@ CheckedCastKind TypeChecker::typeCheckCheckedCast(Type fromType,
4254
4252
bool toExistentialMetatype = false ;
4255
4253
bool fromExistentialMetatype = false ;
4256
4254
if (auto toMetatype = toType->getAs <AnyMetatypeType>()) {
4257
- toExistentialMetatype = toMetatype->is <ExistentialMetatypeType>();
4258
4255
if (auto fromMetatype = fromType->getAs <AnyMetatypeType>()) {
4259
- fromExistentialMetatype = fromMetatype->is <ExistentialMetatypeType>();
4256
+ toExistentialMetatype = toType->is <ExistentialMetatypeType>();
4257
+ fromExistentialMetatype = fromType->is <ExistentialMetatypeType>();
4260
4258
toType = toMetatype->getInstanceType ();
4261
4259
fromType = fromMetatype->getInstanceType ();
4262
4260
}
@@ -4266,23 +4264,43 @@ CheckedCastKind TypeChecker::typeCheckCheckedCast(Type fromType,
4266
4264
bool fromArchetype = fromType->is <ArchetypeType>();
4267
4265
bool toExistential = toType->isExistentialType ();
4268
4266
bool fromExistential = fromType->isExistentialType ();
4267
+
4268
+ bool toRequiresClass;
4269
+ if (toType->isExistentialType ())
4270
+ toRequiresClass = toType->getExistentialLayout ().requiresClass ();
4271
+ else
4272
+ toRequiresClass = toType->mayHaveSuperclass ();
4273
+
4274
+ bool fromRequiresClass;
4275
+ if (fromType->isExistentialType ())
4276
+ fromRequiresClass = fromType->getExistentialLayout ().requiresClass ();
4277
+ else
4278
+ fromRequiresClass = fromType->mayHaveSuperclass ();
4269
4279
4270
- // If we're doing a metatype cast, it can only be existential if we're
4271
- // casting to/from the existential metatype. 'T.self as P.Protocol'
4272
- // can only succeed if T is exactly the type P, so is a concrete cast,
4273
- // whereas 'T.self as P.Type' succeeds for types conforming to the protocol
4274
- // P, and is an existential cast.
4280
+ // Casts between protocol metatypes only succeed if the type is existential.
4275
4281
if (metatypeCast) {
4276
- toExistential &= toExistentialMetatype;
4277
- fromExistential &= fromExistentialMetatype ;
4282
+ if ( toExistential || fromExistential)
4283
+ return failed () ;
4278
4284
}
4279
4285
4286
+ // Casts from an existential metatype to a protocol metatype always fail,
4287
+ // except when the existential type is 'Any'.
4288
+ if (fromExistentialMetatype &&
4289
+ !fromType->isAny () &&
4290
+ !toExistentialMetatype &&
4291
+ toExistential)
4292
+ return failed ();
4293
+
4280
4294
// Casts to or from generic types can't be statically constrained in most
4281
4295
// cases, because there may be protocol conformances we don't statically
4282
4296
// know about.
4283
- if (toExistential || fromExistential || fromArchetype || toArchetype) {
4297
+ if (toExistential || fromExistential || fromArchetype || toArchetype ||
4298
+ toRequiresClass || fromRequiresClass) {
4284
4299
// Cast to and from AnyObject always succeed.
4285
- if (toType->isAnyObject () || fromType->isAnyObject ())
4300
+ if (!metatypeCast &&
4301
+ !fromExistentialMetatype &&
4302
+ !toExistentialMetatype &&
4303
+ (toType->isAnyObject () || fromType->isAnyObject ()))
4286
4304
return CheckedCastKind::ValueCast;
4287
4305
4288
4306
// A cast from an existential type to a concrete type does not succeed. For
@@ -4316,18 +4334,6 @@ CheckedCastKind TypeChecker::typeCheckCheckedCast(Type fromType,
4316
4334
}
4317
4335
}
4318
4336
4319
- bool toRequiresClass;
4320
- if (toType->isExistentialType ())
4321
- toRequiresClass = toType->getExistentialLayout ().requiresClass ();
4322
- else
4323
- toRequiresClass = toType->mayHaveSuperclass ();
4324
-
4325
- bool fromRequiresClass;
4326
- if (fromType->isExistentialType ())
4327
- fromRequiresClass = fromType->getExistentialLayout ().requiresClass ();
4328
- else
4329
- fromRequiresClass = fromType->mayHaveSuperclass ();
4330
-
4331
4337
// If neither type is class-constrained, anything goes.
4332
4338
if (!fromRequiresClass && !toRequiresClass)
4333
4339
return CheckedCastKind::ValueCast;
@@ -4373,44 +4379,29 @@ CheckedCastKind TypeChecker::typeCheckCheckedCast(Type fromType,
4373
4379
return CheckedCastKind::ValueCast;
4374
4380
4375
4381
// Compare superclass bounds.
4376
- if (typesSatisfyConstraint (toSuperclass, fromSuperclass,
4377
- /* openArchetypes=*/ true ,
4378
- ConstraintKind::Subtype, dc))
4382
+ if (fromSuperclass->isBindableToSuperclassOf (toSuperclass))
4379
4383
return CheckedCastKind::ValueCast;
4380
4384
4381
4385
// An upcast is also OK.
4382
- if (typesSatisfyConstraint (fromSuperclass, toSuperclass,
4383
- /* openArchetypes=*/ true ,
4384
- ConstraintKind::Subtype, dc))
4386
+ if (toSuperclass->isBindableToSuperclassOf (fromSuperclass))
4385
4387
return CheckedCastKind::ValueCast;
4386
4388
}
4387
4389
}
4388
4390
4389
- if (cs.isAnyHashableType (toType) || cs.isAnyHashableType (fromType)) {
4391
+ if (ConstraintSystem::isAnyHashableType (toType) ||
4392
+ ConstraintSystem::isAnyHashableType (fromType)) {
4390
4393
return CheckedCastKind::ValueCast;
4391
4394
}
4392
4395
4393
4396
// If the destination type can be a supertype of the source type, we are
4394
4397
// performing what looks like an upcast except it rebinds generic
4395
4398
// parameters.
4396
- if (!metatypeCast &&
4397
- typesSatisfyConstraint (fromType, toType,
4398
- /* openArchetypes=*/ true ,
4399
- ConstraintKind::Subtype, dc)) {
4399
+ if (fromType->isBindableTo (toType))
4400
4400
return CheckedCastKind::ValueCast;
4401
- }
4402
-
4403
- // If the destination type can be a subtype of the source type, we have
4404
- // a downcast.
4405
- if (typesSatisfyConstraint (toType, fromType,
4406
- /* openArchetypes=*/ true ,
4407
- ConstraintKind::Subtype, dc)) {
4408
- return CheckedCastKind::ValueCast;
4409
- }
4410
4401
4411
4402
// Objective-C metaclasses are subclasses of NSObject in the ObjC runtime,
4412
4403
// so casts from NSObject to potentially-class metatypes may succeed.
4413
- if (auto nsObject = cs. TC . getNSObjectType (dc)) {
4404
+ if (auto nsObject = getNSObjectType (dc)) {
4414
4405
if (fromType->isEqual (nsObject)) {
4415
4406
if (auto toMeta = toType->getAs <MetatypeType>()) {
4416
4407
if (toMeta->getInstanceType ()->mayHaveSuperclass ()
0 commit comments