@@ -2440,11 +2440,62 @@ void ConstraintSystem::bindOverloadType(const SelectedOverload &overload,
24402440 auto memberTy = createTypeVariable (keyPathLoc, TVO_CanBindToLValue |
24412441 TVO_CanBindToNoEscape);
24422442
2443+ bool isSubscriptRef = locator->isSubscriptMemberRef ();
2444+ auto addMemberConstraint = [&]() {
2445+ // Attempt to lookup a member with a give name in the root type and
2446+ // assign result to the leaf type of the keypath.
2447+ DeclNameRef memberName =
2448+ isSubscriptRef ? DeclNameRef::createSubscript ()
2449+ // FIXME: Should propagate name-as-written through.
2450+ : DeclNameRef (choice.getName ());
2451+
2452+ // Check the current depth of applied dynamic member lookups, if we've
2453+ // exceeded the limit then record a fix and set a hole for the member.
2454+ unsigned lookupDepth = [&]() {
2455+ auto path = keyPathLoc->getPath ();
2456+ auto iter = path.begin ();
2457+ (void )keyPathLoc->findFirst <LocatorPathElt::KeyPathDynamicMember>(iter);
2458+ return path.end () - iter;
2459+ }();
2460+ if (lookupDepth > ctx.TypeCheckerOpts .DynamicMemberLookupDepthLimit ) {
2461+ (void )recordFix (TooManyDynamicMemberLookups::create (
2462+ *this , DeclNameRef (choice.getName ()), locator));
2463+ recordTypeVariablesAsHoles (memberTy);
2464+ } else {
2465+ addValueMemberConstraint (
2466+ LValueType::get (rootTy), memberName, memberTy, useDC,
2467+ isSubscriptRef ? FunctionRefInfo::doubleBaseNameApply ()
2468+ : FunctionRefInfo::unappliedBaseName (),
2469+ /* outerAlternatives=*/ {}, keyPathLoc);
2470+ }
2471+ };
2472+
2473+ // If we're doing a subscript lookup and have a dynamic member base we need
2474+ // to add the applicable function first since solving the member constraint
2475+ // requires the constraint to be available for recursive cases since it may
2476+ // retire it. We can't yet do this in the general case since the simplifying
2477+ // of the applicable fn in CSGen is currently load-bearing for existential
2478+ // opening.
2479+ // FIXME: Once existential opening is no longer sensitive to solving
2480+ // order, we ought to be able to just always record the applicable fn as
2481+ // an unsolved constraint before the member.
2482+ auto delayMemberConstraint =
2483+ isSubscriptRef && simplifyType (rootTy)
2484+ ->getRValueType ()
2485+ ->getMetatypeInstanceType ()
2486+ ->eraseDynamicSelfType ()
2487+ ->hasDynamicMemberLookupAttribute ();
2488+ if (!delayMemberConstraint)
2489+ addMemberConstraint ();
2490+ SWIFT_DEFER {
2491+ if (delayMemberConstraint)
2492+ addMemberConstraint ();
2493+ };
2494+
24432495 // In case of subscript things are more complicated comparing to "dot"
24442496 // syntax, because we have to get "applicable function" constraint
24452497 // associated with index expression and re-bind it to match "member type"
24462498 // looked up by dynamically.
2447- bool isSubscriptRef = locator->isSubscriptMemberRef ();
24482499 if (isSubscriptRef) {
24492500 // Make sure that regular subscript declarations (if any) are
24502501 // preferred over key path dynamic member lookup.
@@ -2521,35 +2572,6 @@ void ConstraintSystem::bindOverloadType(const SelectedOverload &overload,
25212572 // fact that this a property access in the source.
25222573 addDynamicMemberSubscriptConstraints (/* argTy*/ paramTy, boundType);
25232574 }
2524-
2525- // Attempt to lookup a member with a give name in the root type and
2526- // assign result to the leaf type of the keypath. Note we need to do this
2527- // after handling the applicable function constraint in the subscript case
2528- // to ensure it's available for recursive cases.
2529- DeclNameRef memberName = isSubscriptRef
2530- ? DeclNameRef::createSubscript ()
2531- // FIXME: Should propagate name-as-written through.
2532- : DeclNameRef (choice.getName ());
2533-
2534- // Check the current depth of applied dynamic member lookups, if we've
2535- // exceeded the limit then record a fix and set a hole for the member.
2536- unsigned lookupDepth = [&]() {
2537- auto path = keyPathLoc->getPath ();
2538- auto iter = path.begin ();
2539- (void )keyPathLoc->findFirst <LocatorPathElt::KeyPathDynamicMember>(iter);
2540- return path.end () - iter;
2541- }();
2542- if (lookupDepth > ctx.TypeCheckerOpts .DynamicMemberLookupDepthLimit ) {
2543- (void )recordFix (TooManyDynamicMemberLookups::create (
2544- *this , DeclNameRef (choice.getName ()), locator));
2545- recordTypeVariablesAsHoles (memberTy);
2546- } else {
2547- addValueMemberConstraint (
2548- LValueType::get (rootTy), memberName, memberTy, useDC,
2549- isSubscriptRef ? FunctionRefInfo::doubleBaseNameApply ()
2550- : FunctionRefInfo::unappliedBaseName (),
2551- /* outerAlternatives=*/ {}, keyPathLoc);
2552- }
25532575 return ;
25542576 }
25552577 }
0 commit comments