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