@@ -2362,6 +2362,7 @@ ConstraintSystem::matchTupleTypes(TupleType *tuple1, TupleType *tuple2,
2362
2362
case ConstraintKind::DynamicCallableApplicableFunction:
2363
2363
case ConstraintKind::BindOverload:
2364
2364
case ConstraintKind::CheckedCast:
2365
+ case ConstraintKind::SubclassOf:
2365
2366
case ConstraintKind::ConformsTo:
2366
2367
case ConstraintKind::TransitivelyConformsTo:
2367
2368
case ConstraintKind::Defaultable:
@@ -2534,6 +2535,7 @@ static bool matchFunctionRepresentations(FunctionType::ExtInfo einfo1,
2534
2535
case ConstraintKind::DynamicCallableApplicableFunction:
2535
2536
case ConstraintKind::BindOverload:
2536
2537
case ConstraintKind::CheckedCast:
2538
+ case ConstraintKind::SubclassOf:
2537
2539
case ConstraintKind::ConformsTo:
2538
2540
case ConstraintKind::TransitivelyConformsTo:
2539
2541
case ConstraintKind::Defaultable:
@@ -2948,6 +2950,7 @@ ConstraintSystem::matchFunctionTypes(FunctionType *func1, FunctionType *func2,
2948
2950
case ConstraintKind::DynamicCallableApplicableFunction:
2949
2951
case ConstraintKind::BindOverload:
2950
2952
case ConstraintKind::CheckedCast:
2953
+ case ConstraintKind::SubclassOf:
2951
2954
case ConstraintKind::ConformsTo:
2952
2955
case ConstraintKind::TransitivelyConformsTo:
2953
2956
case ConstraintKind::Defaultable:
@@ -6255,6 +6258,7 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
6255
6258
case ConstraintKind::BindOverload:
6256
6259
case ConstraintKind::BridgingConversion:
6257
6260
case ConstraintKind::CheckedCast:
6261
+ case ConstraintKind::SubclassOf:
6258
6262
case ConstraintKind::ConformsTo:
6259
6263
case ConstraintKind::TransitivelyConformsTo:
6260
6264
case ConstraintKind::Defaultable:
@@ -7314,6 +7318,99 @@ ConstraintSystem::simplifyConstructionConstraint(
7314
7318
return SolutionKind::Solved;
7315
7319
}
7316
7320
7321
+ ConstraintSystem::SolutionKind ConstraintSystem::simplifySubclassOfConstraint(
7322
+ Type type,
7323
+ Type classType,
7324
+ ConstraintLocatorBuilder locator,
7325
+ TypeMatchOptions flags) {
7326
+ if (!classType->getClassOrBoundGenericClass())
7327
+ return SolutionKind::Error;
7328
+
7329
+ // Dig out the fixed type to which this type refers.
7330
+ type = getFixedTypeRecursive(type, flags, /*wantRValue=*/true);
7331
+ if (shouldAttemptFixes() && type->isPlaceholder()) {
7332
+ // If the type associated with this subclass check is a "hole" in the
7333
+ // constraint system, let's consider this check a success without recording
7334
+ // a fix, because it's just a consequence of the other failure, e.g.
7335
+ //
7336
+ // func foo<T: NSObject>(_: T) {}
7337
+ // foo(Foo.bar) <- if `Foo` doesn't have `bar` there is
7338
+ // no reason to complain the subclass.
7339
+ return SolutionKind::Solved;
7340
+ }
7341
+
7342
+ auto formUnsolved = [&](bool activate = false) {
7343
+ // If we're supposed to generate constraints, do so.
7344
+ if (flags.contains(TMF_GenerateConstraints)) {
7345
+ auto *conformance = Constraint::create(
7346
+ *this, ConstraintKind::SubclassOf, type, classType,
7347
+ getConstraintLocator(locator));
7348
+
7349
+ addUnsolvedConstraint(conformance);
7350
+ if (activate)
7351
+ activateConstraint(conformance);
7352
+
7353
+ return SolutionKind::Solved;
7354
+ }
7355
+
7356
+ return SolutionKind::Unsolved;
7357
+ };
7358
+
7359
+ // If we hit a type variable without a fixed type, we can't
7360
+ // solve this yet.
7361
+ if (type->isTypeVariableOrMember())
7362
+ return formUnsolved();
7363
+
7364
+ // SubclassOf constraints are generated when opening a generic
7365
+ // signature with a RequirementKind::Superclass requirement, so
7366
+ // we must handle pack types on the left by splitting up into
7367
+ // smaller constraints.
7368
+ if (auto *packType = type->getAs<PackType>()) {
7369
+ for (unsigned i = 0, e = packType->getNumElements(); i < e; ++i) {
7370
+ addConstraint(ConstraintKind::SubclassOf, packType->getElementType(i),
7371
+ classType, locator.withPathElement(LocatorPathElt::PackElement(i)));
7372
+ }
7373
+
7374
+ return SolutionKind::Solved;
7375
+ }
7376
+
7377
+ // A class-constrained existential like 'C & P' does not satisfy an
7378
+ // AnyObject requirement, if 'P' is not self-conforming.
7379
+ //
7380
+ // While matchSuperclassTypes() will still match here because 'C & P'
7381
+ // satisfies a Subtype constraint with 'C', 'C & P' cannot satisfy a
7382
+ // superclass requirement in a generic signature, so rule that out here.
7383
+ if (type->satisfiesClassConstraint()) {
7384
+ // If we have an exact match of class declarations, ensure the
7385
+ // generic arguments match.
7386
+ if (type->getClassOrBoundGenericClass() ==
7387
+ classType->getClassOrBoundGenericClass()) {
7388
+ auto result = matchTypes(type, classType, ConstraintKind::Bind,
7389
+ flags, locator);
7390
+ if (!result.isFailure())
7391
+ return SolutionKind::Solved;
7392
+
7393
+ // Otherwise, ensure the left hand side is a proper subclass of the
7394
+ // right hand side.
7395
+ } else {
7396
+ auto result = matchSuperclassTypes(type, classType, flags, locator);
7397
+ if (!result.isFailure())
7398
+ return SolutionKind::Solved;
7399
+ }
7400
+ }
7401
+
7402
+ // Record a fix if we didn't match one of the two cases above.
7403
+ if (shouldAttemptFixes()) {
7404
+ if (auto *fix = fixRequirementFailure(*this, type, classType, locator)) {
7405
+ if (recordFix(fix))
7406
+ return SolutionKind::Error;
7407
+ return SolutionKind::Solved;
7408
+ }
7409
+ }
7410
+
7411
+ return SolutionKind::Error;
7412
+ }
7413
+
7317
7414
ConstraintSystem::SolutionKind ConstraintSystem::simplifyConformsToConstraint(
7318
7415
Type type,
7319
7416
Type protocol,
@@ -7375,6 +7472,21 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyConformsToConstraint(
7375
7472
if (type->isTypeVariableOrMember())
7376
7473
return formUnsolved();
7377
7474
7475
+ // ConformsTo constraints are generated when opening a generic
7476
+ // signature with a RequirementKind::Conformance requirement, so
7477
+ // we must handle pack types on the left by splitting up into
7478
+ // smaller constraints.
7479
+ if (auto *packType = type->getAs<PackType>()) {
7480
+ for (unsigned i = 0, e = packType->getNumElements(); i < e; ++i) {
7481
+ addConstraint(ConstraintKind::ConformsTo, packType->getElementType(i),
7482
+ protocol->getDeclaredInterfaceType(),
7483
+ locator.withPathElement(LocatorPathElt::PackElement(i)));
7484
+ }
7485
+
7486
+ return SolutionKind::Solved;
7487
+ }
7488
+
7489
+
7378
7490
auto *loc = getConstraintLocator(locator);
7379
7491
7380
7492
/// Record the given conformance as the result, adding any conditional
@@ -13551,6 +13663,9 @@ ConstraintSystem::addConstraintImpl(ConstraintKind kind, Type first,
13551
13663
return simplifyOpenedExistentialOfConstraint(first, second,
13552
13664
subflags, locator);
13553
13665
13666
+ case ConstraintKind::SubclassOf:
13667
+ return simplifySubclassOfConstraint(first, second, locator, subflags);
13668
+
13554
13669
case ConstraintKind::ConformsTo:
13555
13670
case ConstraintKind::LiteralConformsTo:
13556
13671
case ConstraintKind::SelfObjectOfProtocol:
@@ -14029,6 +14144,13 @@ ConstraintSystem::simplifyConstraint(const Constraint &constraint) {
14029
14144
constraint.getOverloadUseDC());
14030
14145
return SolutionKind::Solved;
14031
14146
14147
+ case ConstraintKind::SubclassOf:
14148
+ return simplifySubclassOfConstraint(
14149
+ constraint.getFirstType(),
14150
+ constraint.getSecondType(),
14151
+ constraint.getLocator(),
14152
+ /*flags*/ None);
14153
+
14032
14154
case ConstraintKind::ConformsTo:
14033
14155
case ConstraintKind::LiteralConformsTo:
14034
14156
case ConstraintKind::SelfObjectOfProtocol:
@@ -14049,7 +14171,7 @@ ConstraintSystem::simplifyConstraint(const Constraint &constraint) {
14049
14171
case ConstraintKind::CheckedCast: {
14050
14172
auto result = simplifyCheckedCastConstraint(constraint.getFirstType(),
14051
14173
constraint.getSecondType(),
14052
- None,
14174
+ /*flags*/ None,
14053
14175
constraint.getLocator());
14054
14176
// NOTE: simplifyCheckedCastConstraint() may return Unsolved, e.g. if the
14055
14177
// subexpression's type is unresolved. Don't record the fix until we
0 commit comments