@@ -2366,6 +2366,7 @@ ConstraintSystem::matchTupleTypes(TupleType *tuple1, TupleType *tuple2,
2366
2366
case ConstraintKind::DynamicCallableApplicableFunction:
2367
2367
case ConstraintKind::BindOverload:
2368
2368
case ConstraintKind::CheckedCast:
2369
+ case ConstraintKind::SubclassOf:
2369
2370
case ConstraintKind::ConformsTo:
2370
2371
case ConstraintKind::TransitivelyConformsTo:
2371
2372
case ConstraintKind::Defaultable:
@@ -2538,6 +2539,7 @@ static bool matchFunctionRepresentations(FunctionType::ExtInfo einfo1,
2538
2539
case ConstraintKind::DynamicCallableApplicableFunction:
2539
2540
case ConstraintKind::BindOverload:
2540
2541
case ConstraintKind::CheckedCast:
2542
+ case ConstraintKind::SubclassOf:
2541
2543
case ConstraintKind::ConformsTo:
2542
2544
case ConstraintKind::TransitivelyConformsTo:
2543
2545
case ConstraintKind::Defaultable:
@@ -2952,6 +2954,7 @@ ConstraintSystem::matchFunctionTypes(FunctionType *func1, FunctionType *func2,
2952
2954
case ConstraintKind::DynamicCallableApplicableFunction:
2953
2955
case ConstraintKind::BindOverload:
2954
2956
case ConstraintKind::CheckedCast:
2957
+ case ConstraintKind::SubclassOf:
2955
2958
case ConstraintKind::ConformsTo:
2956
2959
case ConstraintKind::TransitivelyConformsTo:
2957
2960
case ConstraintKind::Defaultable:
@@ -6259,6 +6262,7 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
6259
6262
case ConstraintKind::BindOverload:
6260
6263
case ConstraintKind::BridgingConversion:
6261
6264
case ConstraintKind::CheckedCast:
6265
+ case ConstraintKind::SubclassOf:
6262
6266
case ConstraintKind::ConformsTo:
6263
6267
case ConstraintKind::TransitivelyConformsTo:
6264
6268
case ConstraintKind::Defaultable:
@@ -7320,6 +7324,99 @@ ConstraintSystem::simplifyConstructionConstraint(
7320
7324
return SolutionKind::Solved;
7321
7325
}
7322
7326
7327
+ ConstraintSystem::SolutionKind ConstraintSystem::simplifySubclassOfConstraint(
7328
+ Type type,
7329
+ Type classType,
7330
+ ConstraintLocatorBuilder locator,
7331
+ TypeMatchOptions flags) {
7332
+ if (!classType->getClassOrBoundGenericClass())
7333
+ return SolutionKind::Error;
7334
+
7335
+ // Dig out the fixed type to which this type refers.
7336
+ type = getFixedTypeRecursive(type, flags, /*wantRValue=*/true);
7337
+ if (shouldAttemptFixes() && type->isPlaceholder()) {
7338
+ // If the type associated with this subclass check is a "hole" in the
7339
+ // constraint system, let's consider this check a success without recording
7340
+ // a fix, because it's just a consequence of the other failure, e.g.
7341
+ //
7342
+ // func foo<T: NSObject>(_: T) {}
7343
+ // foo(Foo.bar) <- if `Foo` doesn't have `bar` there is
7344
+ // no reason to complain the subclass.
7345
+ return SolutionKind::Solved;
7346
+ }
7347
+
7348
+ auto formUnsolved = [&](bool activate = false) {
7349
+ // If we're supposed to generate constraints, do so.
7350
+ if (flags.contains(TMF_GenerateConstraints)) {
7351
+ auto *conformance = Constraint::create(
7352
+ *this, ConstraintKind::SubclassOf, type, classType,
7353
+ getConstraintLocator(locator));
7354
+
7355
+ addUnsolvedConstraint(conformance);
7356
+ if (activate)
7357
+ activateConstraint(conformance);
7358
+
7359
+ return SolutionKind::Solved;
7360
+ }
7361
+
7362
+ return SolutionKind::Unsolved;
7363
+ };
7364
+
7365
+ // If we hit a type variable without a fixed type, we can't
7366
+ // solve this yet.
7367
+ if (type->isTypeVariableOrMember())
7368
+ return formUnsolved();
7369
+
7370
+ // SubclassOf constraints are generated when opening a generic
7371
+ // signature with a RequirementKind::Superclass requirement, so
7372
+ // we must handle pack types on the left by splitting up into
7373
+ // smaller constraints.
7374
+ if (auto *packType = type->getAs<PackType>()) {
7375
+ for (unsigned i = 0, e = packType->getNumElements(); i < e; ++i) {
7376
+ addConstraint(ConstraintKind::SubclassOf, packType->getElementType(i),
7377
+ classType, locator.withPathElement(LocatorPathElt::PackElement(i)));
7378
+ }
7379
+
7380
+ return SolutionKind::Solved;
7381
+ }
7382
+
7383
+ // A class-constrained existential like 'C & P' does not satisfy an
7384
+ // AnyObject requirement, if 'P' is not self-conforming.
7385
+ //
7386
+ // While matchSuperclassTypes() will still match here because 'C & P'
7387
+ // satisfies a Subtype constraint with 'C', 'C & P' cannot satisfy a
7388
+ // superclass requirement in a generic signature, so rule that out here.
7389
+ if (type->satisfiesClassConstraint()) {
7390
+ // If we have an exact match of class declarations, ensure the
7391
+ // generic arguments match.
7392
+ if (type->getClassOrBoundGenericClass() ==
7393
+ classType->getClassOrBoundGenericClass()) {
7394
+ auto result = matchTypes(type, classType, ConstraintKind::Bind,
7395
+ flags, locator);
7396
+ if (!result.isFailure())
7397
+ return SolutionKind::Solved;
7398
+
7399
+ // Otherwise, ensure the left hand side is a proper subclass of the
7400
+ // right hand side.
7401
+ } else {
7402
+ auto result = matchSuperclassTypes(type, classType, flags, locator);
7403
+ if (!result.isFailure())
7404
+ return SolutionKind::Solved;
7405
+ }
7406
+ }
7407
+
7408
+ // Record a fix if we didn't match one of the two cases above.
7409
+ if (shouldAttemptFixes()) {
7410
+ if (auto *fix = fixRequirementFailure(*this, type, classType, locator)) {
7411
+ if (recordFix(fix))
7412
+ return SolutionKind::Error;
7413
+ return SolutionKind::Solved;
7414
+ }
7415
+ }
7416
+
7417
+ return SolutionKind::Error;
7418
+ }
7419
+
7323
7420
ConstraintSystem::SolutionKind ConstraintSystem::simplifyConformsToConstraint(
7324
7421
Type type,
7325
7422
Type protocol,
@@ -7381,6 +7478,21 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyConformsToConstraint(
7381
7478
if (type->isTypeVariableOrMember())
7382
7479
return formUnsolved();
7383
7480
7481
+ // ConformsTo constraints are generated when opening a generic
7482
+ // signature with a RequirementKind::Conformance requirement, so
7483
+ // we must handle pack types on the left by splitting up into
7484
+ // smaller constraints.
7485
+ if (auto *packType = type->getAs<PackType>()) {
7486
+ for (unsigned i = 0, e = packType->getNumElements(); i < e; ++i) {
7487
+ addConstraint(ConstraintKind::ConformsTo, packType->getElementType(i),
7488
+ protocol->getDeclaredInterfaceType(),
7489
+ locator.withPathElement(LocatorPathElt::PackElement(i)));
7490
+ }
7491
+
7492
+ return SolutionKind::Solved;
7493
+ }
7494
+
7495
+
7384
7496
auto *loc = getConstraintLocator(locator);
7385
7497
7386
7498
/// Record the given conformance as the result, adding any conditional
@@ -13557,6 +13669,9 @@ ConstraintSystem::addConstraintImpl(ConstraintKind kind, Type first,
13557
13669
return simplifyOpenedExistentialOfConstraint(first, second,
13558
13670
subflags, locator);
13559
13671
13672
+ case ConstraintKind::SubclassOf:
13673
+ return simplifySubclassOfConstraint(first, second, locator, subflags);
13674
+
13560
13675
case ConstraintKind::ConformsTo:
13561
13676
case ConstraintKind::LiteralConformsTo:
13562
13677
case ConstraintKind::SelfObjectOfProtocol:
@@ -14035,6 +14150,13 @@ ConstraintSystem::simplifyConstraint(const Constraint &constraint) {
14035
14150
constraint.getOverloadUseDC());
14036
14151
return SolutionKind::Solved;
14037
14152
14153
+ case ConstraintKind::SubclassOf:
14154
+ return simplifySubclassOfConstraint(
14155
+ constraint.getFirstType(),
14156
+ constraint.getSecondType(),
14157
+ constraint.getLocator(),
14158
+ /*flags*/ None);
14159
+
14038
14160
case ConstraintKind::ConformsTo:
14039
14161
case ConstraintKind::LiteralConformsTo:
14040
14162
case ConstraintKind::SelfObjectOfProtocol:
@@ -14055,7 +14177,7 @@ ConstraintSystem::simplifyConstraint(const Constraint &constraint) {
14055
14177
case ConstraintKind::CheckedCast: {
14056
14178
auto result = simplifyCheckedCastConstraint(constraint.getFirstType(),
14057
14179
constraint.getSecondType(),
14058
- None,
14180
+ /*flags*/ None,
14059
14181
constraint.getLocator());
14060
14182
// NOTE: simplifyCheckedCastConstraint() may return Unsolved, e.g. if the
14061
14183
// subexpression's type is unresolved. Don't record the fix until we
0 commit comments