@@ -11718,63 +11718,6 @@ bool ConstraintSystem::resolveClosure(TypeVariableType *typeVar,
11718
11718
return !generateConstraints(AnyFunctionRef{closure}, closure->getBody());
11719
11719
}
11720
11720
11721
- bool ConstraintSystem::resolveKeyPath(TypeVariableType *typeVar,
11722
- Type contextualType,
11723
- ConstraintLocatorBuilder locator) {
11724
- auto *keyPathLocator = typeVar->getImpl().getLocator();
11725
- auto *keyPath = castToExpr<KeyPathExpr>(keyPathLocator->getAnchor());
11726
-
11727
- if (keyPath->hasSingleInvalidComponent()) {
11728
- assignFixedType(typeVar, contextualType);
11729
- return true;
11730
- }
11731
-
11732
- auto objectTy = contextualType->lookThroughAllOptionalTypes();
11733
- {
11734
- auto &ctx = getASTContext();
11735
- // `AnyKeyPath` and `PartialKeyPath` represent type-erased versions of
11736
- // `KeyPath<T, V>`.
11737
- //
11738
- // In situations where `AnyKeyPath` or `PartialKeyPath` cannot be used
11739
- // directly i.e. passing an argument to a parameter represented by a
11740
- // `AnyKeyPath` or `PartialKeyPath`, let's attempt a `KeyPath` binding which
11741
- // would then be converted to a `AnyKeyPath` or `PartialKeyPath` since there
11742
- // is a subtype relationship between them.
11743
- if (objectTy->isAnyKeyPath()) {
11744
- auto root = getKeyPathRootType(keyPath);
11745
- auto value = getKeyPathValueType(keyPath);
11746
-
11747
- contextualType =
11748
- BoundGenericType::get(ctx.getKeyPathDecl(), Type(), {root, value});
11749
- } else if (objectTy->isPartialKeyPath()) {
11750
- auto rootTy = objectTy->castTo<BoundGenericType>()->getGenericArgs()[0];
11751
- // Since partial key path is an erased version of `KeyPath`, the value
11752
- // type would never be used, which means that binding can use
11753
- // type variable generated for a result of key path expression.
11754
- auto valueTy = getKeyPathValueType(keyPath);
11755
-
11756
- contextualType = BoundGenericType::get(ctx.getKeyPathDecl(), Type(),
11757
- {rootTy, valueTy});
11758
- } else if (isKnownKeyPathType(objectTy)) {
11759
- auto *keyPathTy = objectTy->castTo<BoundGenericType>();
11760
- auto args = keyPathTy->getGenericArgs();
11761
- assert(args.size() == 2);
11762
-
11763
- auto root = args.front();
11764
- auto value = getKeyPathValueType(keyPath);
11765
- // Make sure that key path always gets a chance to infer its
11766
- // value type from the member chain.
11767
- if (!value->isEqual(args.back())) {
11768
- contextualType = BoundGenericType::get(
11769
- keyPathTy->getDecl(), keyPathTy->getParent(), {root, value});
11770
- }
11771
- }
11772
- }
11773
-
11774
- assignFixedType(typeVar, contextualType);
11775
- return true;
11776
- }
11777
-
11778
11721
bool ConstraintSystem::resolvePackExpansion(TypeVariableType *typeVar,
11779
11722
Type contextualType) {
11780
11723
assert(typeVar->getImpl().isPackExpansion());
@@ -12300,6 +12243,8 @@ ConstraintSystem::simplifyKeyPathConstraint(
12300
12243
// If key path has to be converted to a function, let's check that
12301
12244
// the contextual type has precisely one parameter.
12302
12245
if (auto *fnTy = keyPathTy->getAs<FunctionType>()) {
12246
+ increaseScore(SK_FunctionConversion, locator);
12247
+
12303
12248
if (fnTy->getParams().size() != 1) {
12304
12249
if (!shouldAttemptFixes())
12305
12250
return SolutionKind::Error;
@@ -12332,57 +12277,8 @@ ConstraintSystem::simplifyKeyPathConstraint(
12332
12277
// If we're fixed to a bound generic type, trying harvesting context from it.
12333
12278
// However, we don't want a solution that fixes the expression type to
12334
12279
// PartialKeyPath; we'd rather that be represented using an upcast conversion.
12335
- if (!tryMatchRootAndValueFromType(keyPathTy))
12336
- return SolutionKind::Error;
12337
-
12338
- bool isValid;
12339
- llvm::Optional<KeyPathCapability> capability;
12340
-
12341
- std::tie(isValid, capability) = inferKeyPathLiteralCapability(keyPath);
12342
-
12343
- // If key path is invalid, let's not don't attempt match capabilities.
12344
- if (!isValid)
12345
- return shouldAttemptFixes() ? SolutionKind::Solved : SolutionKind::Error;
12346
-
12347
- // If key path is valid but not yet sufficiently resolved, let's delay
12348
- // capability checking.
12349
- if (!capability)
12350
- return formUnsolved();
12351
-
12352
- // Resolve the type.
12353
- NominalTypeDecl *kpDecl;
12354
- switch (*capability) {
12355
- case KeyPathCapability::ReadOnly:
12356
- kpDecl = getASTContext().getKeyPathDecl();
12357
- break;
12358
-
12359
- case KeyPathCapability::Writable:
12360
- kpDecl = getASTContext().getWritableKeyPathDecl();
12361
- break;
12362
-
12363
- case KeyPathCapability::ReferenceWritable:
12364
- kpDecl = getASTContext().getReferenceWritableKeyPathDecl();
12365
- break;
12366
- }
12367
-
12368
- // FIXME: Allow the type to be upcast if the type system has a concrete
12369
- // KeyPath type assigned to the expression already.
12370
- if (auto keyPathBGT = keyPathTy->getAs<BoundGenericType>()) {
12371
- if (keyPathBGT->isKeyPath())
12372
- kpDecl = getASTContext().getKeyPathDecl();
12373
- else if (keyPathBGT->isWritableKeyPath() &&
12374
- *capability >= KeyPathCapability::Writable)
12375
- kpDecl = getASTContext().getWritableKeyPathDecl();
12376
- }
12377
-
12378
- if (keyPathTy->is<FunctionType>()) {
12379
- increaseScore(SK_FunctionConversion, locator);
12380
- return SolutionKind::Solved;
12381
- }
12382
-
12383
- auto resolvedKPTy = BoundGenericType::get(kpDecl, nullptr, {rootTy, valueTy});
12384
- return matchTypes(resolvedKPTy, keyPathTy, ConstraintKind::Bind, subflags,
12385
- locator);
12280
+ return tryMatchRootAndValueFromType(keyPathTy) ? SolutionKind::Solved
12281
+ : SolutionKind::Error;
12386
12282
}
12387
12283
12388
12284
ConstraintSystem::SolutionKind
0 commit comments