@@ -11729,7 +11729,6 @@ bool ConstraintSystem::resolveKeyPath(TypeVariableType *typeVar,
11729
11729
11730
11730
auto root = args.front();
11731
11731
auto value = getKeyPathValueType(keyPath);
11732
-
11733
11732
// Make sure that key path always gets a chance to infer its
11734
11733
// value type from the member chain.
11735
11734
if (!value->isEqual(args.back())) {
@@ -12212,6 +12211,19 @@ ConstraintSystem::simplifyKeyPathConstraint(
12212
12211
bool definitelyKeyPathType = false;
12213
12212
bool resolveAsMultiArgFuncFix = false;
12214
12213
12214
+ auto formUnsolved = [&]() -> SolutionKind {
12215
+ if (flags.contains(TMF_GenerateConstraints)) {
12216
+ addUnsolvedConstraint(Constraint::create(
12217
+ *this, ConstraintKind::KeyPath, keyPathTy, rootTy, valueTy,
12218
+ locator.getBaseLocator(), componentTypeVars));
12219
+ return SolutionKind::Solved;
12220
+ }
12221
+ return SolutionKind::Unsolved;
12222
+ };
12223
+
12224
+ if (keyPathTy->isTypeVariableOrMember())
12225
+ return formUnsolved();
12226
+
12215
12227
auto tryMatchRootAndValueFromType = [&](Type type,
12216
12228
bool allowPartial = true) -> bool {
12217
12229
Type boundRoot = Type(), boundValue = Type();
@@ -12493,60 +12505,19 @@ ConstraintSystem::simplifyKeyPathConstraint(
12493
12505
kpDecl = getASTContext().getWritableKeyPathDecl();
12494
12506
}
12495
12507
12496
- auto formUnsolved = [&]() {
12497
- addUnsolvedConstraint(Constraint::create(
12498
- *this, ConstraintKind::KeyPath, keyPathTy, rootTy, valueTy,
12499
- locator.getBaseLocator(), componentTypeVars));
12500
- };
12501
-
12502
12508
auto loc = locator.getBaseLocator();
12503
12509
if (definitelyFunctionType) {
12504
12510
increaseScore(SK_FunctionConversion, locator);
12505
12511
return SolutionKind::Solved;
12506
12512
} else if (!anyComponentsUnresolved ||
12507
12513
(definitelyKeyPathType && capability == ReadOnly)) {
12508
- // If key path is connected to a disjunction (i.e. through coercion
12509
- // or used as an argument to a function/subscipt call) it cannot be
12510
- // bound until the choice is selected because it's undetermined
12511
- // until then whether key path is implicitly converted to a function
12512
- // type or not.
12513
- //
12514
- // \code
12515
- // struct Data {
12516
- // var value: Int = 42
12517
- // }
12518
- //
12519
- // func test<S: Sequence>(_: S, _: (S.Element) -> Int) {}
12520
- // func test<C: Collection>(_: C, _: (C.Element) -> Int) {}
12521
- //
12522
- // func test(arr: [Data]) {
12523
- // test(arr, \Data.value)
12524
- // }
12525
- // \endcode
12526
- //
12527
- // In this example if we did allow to bind the key path before
12528
- // an overload of `test` is selected, we'd end up with no solutions
12529
- // because the type of the key path expression is actually: '(Data) -> Int'
12530
- // and not 'WritableKeyPath<Data, Int>`.
12531
- auto *typeVar = keyPathTy->getAs<TypeVariableType>();
12532
- if (typeVar && findConstraintThroughOptionals(
12533
- typeVar, OptionalWrappingDirection::Unwrap,
12534
- [&](Constraint *match, TypeVariableType *) {
12535
- return match->getKind() ==
12536
- ConstraintKind::ApplicableFunction ||
12537
- match->getKind() == ConstraintKind::Disjunction;
12538
- })) {
12539
- formUnsolved();
12540
- } else {
12541
- auto resolvedKPTy =
12542
- BoundGenericType::get(kpDecl, nullptr, {rootTy, valueTy});
12543
- return matchTypes(resolvedKPTy, keyPathTy, ConstraintKind::Bind,
12544
- subflags, loc);
12545
- }
12546
- } else {
12547
- formUnsolved();
12514
+ auto resolvedKPTy =
12515
+ BoundGenericType::get(kpDecl, nullptr, {rootTy, valueTy});
12516
+ return matchTypes(resolvedKPTy, keyPathTy, ConstraintKind::Bind, subflags,
12517
+ loc);
12548
12518
}
12549
- return SolutionKind::Solved;
12519
+
12520
+ return formUnsolved();
12550
12521
}
12551
12522
12552
12523
ConstraintSystem::SolutionKind
0 commit comments