@@ -2713,7 +2713,16 @@ namespace {
2713
2713
llvm_unreachable (" Already type-checked" );
2714
2714
}
2715
2715
Type visitKeyPathApplicationExpr (KeyPathApplicationExpr *expr) {
2716
- llvm_unreachable (" Already type-checked" );
2716
+ // This should only appear in already-type-checked solutions, but we may
2717
+ // need to re-check for failure diagnosis.
2718
+ auto locator = CS.getConstraintLocator (expr);
2719
+ auto projectedTy = CS.createTypeVariable (locator,
2720
+ TVO_CanBindToLValue);
2721
+ CS.addKeyPathApplicationConstraint (expr->getKeyPath ()->getType (),
2722
+ expr->getBase ()->getType (),
2723
+ projectedTy,
2724
+ locator);
2725
+ return projectedTy;
2717
2726
}
2718
2727
2719
2728
Type visitEnumIsCaseExpr (EnumIsCaseExpr *expr) {
@@ -2797,19 +2806,6 @@ namespace {
2797
2806
locator);
2798
2807
}
2799
2808
2800
- // If a component is already resolved, then all of them should be
2801
- // resolved, and we can let the expression be. This might happen when
2802
- // re-checking a failed system for diagnostics.
2803
- if (E->getComponents ().front ().isResolved ()) {
2804
- assert ([&]{
2805
- for (auto &c : E->getComponents ())
2806
- if (!c.isResolved ())
2807
- return false ;
2808
- return true ;
2809
- }());
2810
- return E->getType ();
2811
- }
2812
-
2813
2809
bool didOptionalChain = false ;
2814
2810
// We start optimistically from an lvalue base.
2815
2811
Type base = LValueType::get (root);
@@ -2820,16 +2816,23 @@ namespace {
2820
2816
case KeyPathExpr::Component::Kind::Invalid:
2821
2817
break ;
2822
2818
2823
- case KeyPathExpr::Component::Kind::UnresolvedProperty: {
2819
+ case KeyPathExpr::Component::Kind::UnresolvedProperty:
2820
+ // This should only appear in resolved ASTs, but we may need to
2821
+ // re-type-check the constraints during failure diagnosis.
2822
+ case KeyPathExpr::Component::Kind::Property: {
2824
2823
auto memberTy = CS.createTypeVariable (locator,
2825
2824
TVO_CanBindToLValue |
2826
2825
TVO_CanBindToInOut);
2827
- auto refKind = component.getUnresolvedDeclName ().isSimpleName ()
2826
+ auto lookupName = kind == KeyPathExpr::Component::Kind::UnresolvedProperty
2827
+ ? component.getUnresolvedDeclName ()
2828
+ : component.getDeclRef ().getDecl ()->getFullName ();
2829
+
2830
+ auto refKind = lookupName.isSimpleName ()
2828
2831
? FunctionRefKind::Unapplied
2829
2832
: FunctionRefKind::Compound;
2830
2833
auto memberLocator = CS.getConstraintLocator (E,
2831
2834
ConstraintLocator::PathElement::getKeyPathComponent (i));
2832
- CS.addValueMemberConstraint (base, component. getUnresolvedDeclName () ,
2835
+ CS.addValueMemberConstraint (base, lookupName ,
2833
2836
memberTy,
2834
2837
CurDC,
2835
2838
refKind,
@@ -2838,7 +2841,11 @@ namespace {
2838
2841
break ;
2839
2842
}
2840
2843
2841
- case KeyPathExpr::Component::Kind::UnresolvedSubscript: {
2844
+ case KeyPathExpr::Component::Kind::UnresolvedSubscript:
2845
+ // Subscript should only appear in resolved ASTs, but we may need to
2846
+ // re-type-check the constraints during failure diagnosis.
2847
+ case KeyPathExpr::Component::Kind::Subscript: {
2848
+
2842
2849
auto memberLocator = CS.getConstraintLocator (E,
2843
2850
ConstraintLocator::PathElement::getKeyPathComponent (i));
2844
2851
base = addSubscriptConstraints (E, base, component.getIndexExpr (),
@@ -2869,11 +2876,13 @@ namespace {
2869
2876
break ;
2870
2877
}
2871
2878
2872
- case KeyPathExpr::Component::Kind::Property:
2873
- case KeyPathExpr::Component::Kind::Subscript:
2874
- case KeyPathExpr::Component::Kind::OptionalWrap:
2875
- llvm_unreachable (" already resolved" );
2876
- }
2879
+ case KeyPathExpr::Component::Kind::OptionalWrap: {
2880
+ // This should only appear in resolved ASTs, but we may need to
2881
+ // re-type-check the constraints during failure diagnosis.
2882
+ base = OptionalType::get (base);
2883
+ break ;
2884
+ }
2885
+ }
2877
2886
}
2878
2887
2879
2888
// If there was an optional chaining component, the end result must be
0 commit comments