@@ -5533,90 +5533,61 @@ ConstraintSystem::simplifyKeyPathConstraint(Type keyPathTy,
5533
5533
bool definitelyFunctionType = false ;
5534
5534
bool definitelyKeyPathType = false ;
5535
5535
5536
- auto tryMatchRootAndValueFromKeyPathType =
5537
- [&](BoundGenericType *bgt, bool allowPartial) -> SolutionKind {
5538
- Type boundRoot, boundValue;
5536
+ auto tryMatchRootAndValueFromType = [&](Type type,
5537
+ bool allowPartial = true ) -> bool {
5538
+ Type boundRoot = Type () , boundValue = Type () ;
5539
5539
5540
+ if (auto bgt = type->getAs <BoundGenericType>()) {
5540
5541
definitelyKeyPathType = true ;
5541
5542
5542
5543
// We can get root and value from a concrete key path type.
5543
- if (bgt->getDecl () == getASTContext ().getKeyPathDecl ()
5544
- || bgt->getDecl () == getASTContext ().getWritableKeyPathDecl ()
5545
- || bgt->getDecl () == getASTContext ().getReferenceWritableKeyPathDecl ()) {
5544
+ if (bgt->getDecl () == getASTContext ().getKeyPathDecl () ||
5545
+ bgt->getDecl () == getASTContext ().getWritableKeyPathDecl () ||
5546
+ bgt->getDecl () == getASTContext ().getReferenceWritableKeyPathDecl ()) {
5546
5547
boundRoot = bgt->getGenericArgs ()[0 ];
5547
5548
boundValue = bgt->getGenericArgs ()[1 ];
5548
5549
} else if (bgt->getDecl () == getASTContext ().getPartialKeyPathDecl ()) {
5549
- if (allowPartial) {
5550
- // We can still get the root from a PartialKeyPath.
5551
- boundRoot = bgt->getGenericArgs ()[0 ];
5552
- boundValue = Type ();
5553
- } else {
5554
- return SolutionKind::Error;
5555
- }
5556
- } else {
5557
- // We can't bind anything from this type.
5558
- return SolutionKind::Solved;
5550
+ if (!allowPartial)
5551
+ return false ;
5552
+
5553
+ // We can still get the root from a PartialKeyPath.
5554
+ boundRoot = bgt->getGenericArgs ()[0 ];
5559
5555
}
5560
- if (matchTypes (boundRoot, rootTy,
5561
- ConstraintKind::Bind, subflags, locator).isFailure ())
5562
- return SolutionKind::Error;
5556
+ }
5563
5557
5564
- if (boundValue
5565
- && matchTypes (boundValue, valueTy,
5566
- ConstraintKind::Bind, subflags, locator).isFailure ())
5567
- return SolutionKind::Error;
5568
-
5569
- return SolutionKind::Solved;
5570
- };
5558
+ if (auto fnTy = type->getAs <FunctionType>()) {
5559
+ definitelyFunctionType = true ;
5571
5560
5572
- auto tryMatchRootAndValueFromFunctionType =
5573
- [&](FunctionType *fnTy) -> SolutionKind {
5574
- if (fnTy->getParams ().size () != 1 )
5575
- return SolutionKind::Error;
5561
+ if (fnTy->getParams ().size () != 1 )
5562
+ return false ;
5576
5563
5577
- Type boundRoot = fnTy->getParams ()[0 ].getPlainType ();
5578
- Type boundValue = fnTy->getResult ();
5564
+ boundRoot = fnTy->getParams ()[0 ].getPlainType ();
5565
+ boundValue = fnTy->getResult ();
5566
+ }
5579
5567
5580
- if (matchTypes (boundRoot, rootTy, ConstraintKind::Bind, subflags, locator)
5568
+ if (boundRoot &&
5569
+ matchTypes (boundRoot, rootTy, ConstraintKind::Bind, subflags, locator)
5581
5570
.isFailure ())
5582
- return SolutionKind::Error ;
5571
+ return false ;
5583
5572
5584
- if (matchTypes (boundValue, valueTy, ConstraintKind::Bind, subflags, locator)
5573
+ if (boundValue &&
5574
+ matchTypes (boundValue, valueTy, ConstraintKind::Bind, subflags, locator)
5585
5575
.isFailure ())
5586
- return SolutionKind::Error ;
5576
+ return false ;
5587
5577
5588
- definitelyFunctionType = true ;
5589
- return SolutionKind::Solved;
5578
+ return true ;
5590
5579
};
5591
5580
5592
5581
// If we're fixed to a bound generic type, trying harvesting context from it.
5593
5582
// However, we don't want a solution that fixes the expression type to
5594
5583
// PartialKeyPath; we'd rather that be represented using an upcast conversion.
5595
- auto keyPathBGT = keyPathTy->getAs <BoundGenericType>();
5596
- if (keyPathBGT) {
5597
- if (tryMatchRootAndValueFromKeyPathType (keyPathBGT, /* allowPartial*/ false )
5598
- == SolutionKind::Error)
5599
- return SolutionKind::Error;
5600
- }
5601
- // If we're bound to a (Root) -> Value function type, use that for context.
5602
- if (auto fnTy = keyPathTy->getAs <FunctionType>()) {
5603
- if (tryMatchRootAndValueFromFunctionType (fnTy) == SolutionKind::Error)
5604
- return SolutionKind::Error;
5605
- }
5584
+ if (!tryMatchRootAndValueFromType (keyPathTy, /* allowPartial=*/ false ))
5585
+ return SolutionKind::Error;
5606
5586
5607
5587
// If the expression has contextual type information, try using that too.
5608
5588
if (auto contextualTy = getContextualType (keyPath)) {
5609
- if (auto contextualBGT = contextualTy->getAs <BoundGenericType>()) {
5610
- if (tryMatchRootAndValueFromKeyPathType (contextualBGT,
5611
- /* allowPartial*/ true )
5612
- == SolutionKind::Error)
5613
- return SolutionKind::Error;
5614
- }
5615
- if (auto contextualBGT = contextualTy->getAs <FunctionType>()) {
5616
- if (tryMatchRootAndValueFromFunctionType (contextualBGT) ==
5617
- SolutionKind::Error)
5618
- return SolutionKind::Error;
5619
- }
5589
+ if (!tryMatchRootAndValueFromType (contextualTy))
5590
+ return SolutionKind::Error;
5620
5591
}
5621
5592
5622
5593
// If we have nothing else, and there's another constraint on our keyPathTy
@@ -5628,11 +5599,9 @@ ConstraintSystem::simplifyKeyPathConstraint(Type keyPathTy,
5628
5599
continue ;
5629
5600
if (constraint.getFirstType ().getPointer () == keyPathTy.getPointer ()) {
5630
5601
auto otherType = constraint.getSecondType ();
5631
- if (auto otherFT = otherType->getAs <FunctionType>()) {
5632
- if (tryMatchRootAndValueFromFunctionType (otherFT) ==
5633
- SolutionKind::Error)
5634
- return SolutionKind::Error;
5635
- }
5602
+ if (otherType->is <FunctionType>() &&
5603
+ !tryMatchRootAndValueFromType (otherType))
5604
+ return SolutionKind::Error;
5636
5605
}
5637
5606
}
5638
5607
}
@@ -5756,15 +5725,15 @@ ConstraintSystem::simplifyKeyPathConstraint(Type keyPathTy,
5756
5725
5757
5726
// FIXME: Allow the type to be upcast if the type system has a concrete
5758
5727
// KeyPath type assigned to the expression already.
5759
- if (keyPathBGT) {
5728
+ if (auto keyPathBGT = keyPathTy-> getAs <BoundGenericType>() ) {
5760
5729
if (keyPathBGT->getDecl () == getASTContext ().getKeyPathDecl ())
5761
5730
kpDecl = getASTContext ().getKeyPathDecl ();
5762
5731
else if (keyPathBGT->getDecl () ==
5763
5732
getASTContext ().getWritableKeyPathDecl () &&
5764
5733
capability >= Writable)
5765
5734
kpDecl = getASTContext ().getWritableKeyPathDecl ();
5766
5735
}
5767
-
5736
+
5768
5737
auto loc = locator.getBaseLocator ();
5769
5738
if (definitelyFunctionType) {
5770
5739
Type fnType =
0 commit comments