@@ -1875,9 +1875,7 @@ isInvalidPartialApplication(ConstraintSystem &cs, const ValueDecl *member,
1875
1875
1876
1876
std::pair<Type, bool > ConstraintSystem::adjustTypeOfOverloadReference (
1877
1877
const OverloadChoice &choice, ConstraintLocator *locator,
1878
- Type boundType, Type refType, DeclContext *useDC,
1879
- llvm::function_ref<void (unsigned int , Type, ConstraintLocator *)>
1880
- verifyThatArgumentIsHashable) {
1878
+ Type boundType, Type refType) {
1881
1879
// If the declaration is unavailable, note that in the score.
1882
1880
if (choice.getDecl ()->getAttrs ().isUnavailable (getASTContext ())) {
1883
1881
increaseScore (SK_Unavailable);
@@ -1899,6 +1897,7 @@ std::pair<Type, bool> ConstraintSystem::adjustTypeOfOverloadReference(
1899
1897
1900
1898
// Deal with values declared as implicitly unwrapped, or
1901
1899
// functions with return types that are implicitly unwrapped.
1900
+ // TODO: Move this logic to bindOverloadType.
1902
1901
if (choice.isImplicitlyUnwrappedValueOrReturnValue ()) {
1903
1902
// Build the disjunction to attempt binding both T? and T (or
1904
1903
// function returning T? and function returning T).
@@ -1910,6 +1909,7 @@ std::pair<Type, bool> ConstraintSystem::adjustTypeOfOverloadReference(
1910
1909
bindConstraintCreated = true ;
1911
1910
}
1912
1911
1912
+ // TODO: Move this to getTypeOfMemberReference.
1913
1913
refType = OptionalType::get (refType->getRValueType ());
1914
1914
}
1915
1915
@@ -1922,6 +1922,7 @@ std::pair<Type, bool> ConstraintSystem::adjustTypeOfOverloadReference(
1922
1922
case OverloadChoiceKind::KeyPathApplication:
1923
1923
return {refType, bindConstraintCreated};
1924
1924
case OverloadChoiceKind::DeclViaDynamic: {
1925
+ // TODO: Move the IUO handling logic here to bindOverloadType.
1925
1926
if (isa<SubscriptDecl>(choice.getDecl ())) {
1926
1927
// We always expect function type for subscripts.
1927
1928
auto fnTy = refType->castTo <AnyFunctionType>();
@@ -1982,20 +1983,52 @@ std::pair<Type, bool> ConstraintSystem::adjustTypeOfOverloadReference(
1982
1983
1983
1984
// We store an Optional of the originally resolved type in the
1984
1985
// overload set.
1986
+ // TODO: Move this to getTypeOfMemberReference.
1985
1987
refType = OptionalType::get (refType->getRValueType ());
1986
1988
}
1987
1989
1988
1990
return {refType, /* bindConstraintCreated*/ true };
1989
1991
}
1992
+ case OverloadChoiceKind::DynamicMemberLookup:
1993
+ case OverloadChoiceKind::KeyPathDynamicMemberLookup:
1994
+ return {refType, bindConstraintCreated};
1995
+ }
1996
+
1997
+ llvm_unreachable (" Unhandled OverloadChoiceKind in switch." );
1998
+ }
1999
+
2000
+ void ConstraintSystem::bindOverloadType (
2001
+ const SelectedOverload &overload, Type boundType,
2002
+ ConstraintLocator *locator, DeclContext *useDC,
2003
+ llvm::function_ref<void (unsigned int , Type, ConstraintLocator *)>
2004
+ verifyThatArgumentIsHashable) {
2005
+ auto choice = overload.choice ;
2006
+ auto openedType = overload.openedType ;
2007
+
2008
+ auto bindTypeOrIUO = [&](Type ty) {
2009
+ if (choice.isImplicitlyUnwrappedValueOrReturnValue ()) {
2010
+ // Build the disjunction to attempt binding both T? and T (or
2011
+ // function returning T? and function returning T).
2012
+ buildDisjunctionForImplicitlyUnwrappedOptional (boundType, ty, locator);
2013
+ } else {
2014
+ // Add the type binding constraint.
2015
+ addConstraint (ConstraintKind::Bind, boundType, ty, locator);
2016
+ }
2017
+ };
2018
+ switch (choice.getKind ()) {
2019
+ case OverloadChoiceKind::Decl:
2020
+ case OverloadChoiceKind::DeclViaBridge:
2021
+ case OverloadChoiceKind::DeclViaUnwrappedOptional:
2022
+ case OverloadChoiceKind::TupleIndex:
2023
+ case OverloadChoiceKind::BaseType:
2024
+ case OverloadChoiceKind::KeyPathApplication:
2025
+ case OverloadChoiceKind::DeclViaDynamic:
2026
+ bindTypeOrIUO (openedType);
2027
+ return ;
1990
2028
case OverloadChoiceKind::DynamicMemberLookup: {
1991
2029
// DynamicMemberLookup results are always a (dynamicMember:T1)->T2
1992
2030
// subscript.
1993
- auto refFnType = refType->castTo <FunctionType>();
1994
-
1995
- // If this is a dynamic member lookup, then the decl we have is for the
1996
- // subscript(dynamicMember:) member, but the type we need to return is the
1997
- // result of the subscript. Dig through it.
1998
- refType = refFnType->getResult ();
2031
+ auto refFnType = openedType->castTo <FunctionType>();
1999
2032
2000
2033
// Before we drop the argument type on the floor, we need to constrain it
2001
2034
// to having a literal conformance to ExpressibleByStringLiteral. This
@@ -2008,7 +2041,7 @@ std::pair<Type, bool> ConstraintSystem::adjustTypeOfOverloadReference(
2008
2041
TypeChecker::getProtocol (getASTContext (), choice.getDecl ()->getLoc (),
2009
2042
KnownProtocolKind::ExpressibleByStringLiteral);
2010
2043
if (!stringLiteral)
2011
- return {refType, bindConstraintCreated} ;
2044
+ return ;
2012
2045
2013
2046
addConstraint (ConstraintKind::LiteralConformsTo, argType,
2014
2047
stringLiteral->getDeclaredType (), locator);
@@ -2018,19 +2051,21 @@ std::pair<Type, bool> ConstraintSystem::adjustTypeOfOverloadReference(
2018
2051
if (isa<KeyPathExpr>(locator->getAnchor ()))
2019
2052
verifyThatArgumentIsHashable (0 , argType, locator);
2020
2053
2021
- return {refType, bindConstraintCreated};
2054
+ // The resolved decl is for subscript(dynamicMember:), however the original
2055
+ // member constraint was for a property. Therefore we need to bind to the
2056
+ // result type.
2057
+ bindTypeOrIUO (refFnType->getResult ());
2058
+ return ;
2022
2059
}
2023
2060
case OverloadChoiceKind::KeyPathDynamicMemberLookup: {
2024
- auto *fnType = refType ->castTo <FunctionType>();
2061
+ auto *fnType = openedType ->castTo <FunctionType>();
2025
2062
assert (fnType->getParams ().size () == 1 &&
2026
2063
" subscript always has one argument" );
2027
2064
// Parameter type is KeyPath<T, U> where `T` is a root type
2028
2065
// and U is a leaf type (aka member type).
2029
2066
auto keyPathTy =
2030
2067
fnType->getParams ()[0 ].getPlainType ()->castTo <BoundGenericType>();
2031
2068
2032
- refType = fnType->getResult ();
2033
-
2034
2069
auto *keyPathDecl = keyPathTy->getAnyNominal ();
2035
2070
assert (isKnownKeyPathDecl (getASTContext (), keyPathDecl) &&
2036
2071
" parameter is supposed to be a keypath" );
@@ -2051,18 +2086,11 @@ std::pair<Type, bool> ConstraintSystem::adjustTypeOfOverloadReference(
2051
2086
DeclName memberName =
2052
2087
isSubscriptRef ? DeclBaseName::createSubscript () : choice.getName ();
2053
2088
2054
- auto *memberRef = Constraint::createMember (
2055
- *this , ConstraintKind::ValueMember, LValueType::get (rootTy), memberTy,
2056
- memberName, useDC,
2057
- isSubscriptRef ? FunctionRefKind::DoubleApply
2058
- : FunctionRefKind::Unapplied,
2059
- keyPathLoc);
2060
-
2061
- // Delay simplication of this constraint until after the overload choice
2062
- // has been bound for this key path dynamic member. This helps to identify
2063
- // recursive calls with the same base.
2064
- addUnsolvedConstraint (memberRef);
2065
- activateConstraint (memberRef);
2089
+ addValueMemberConstraint (LValueType::get (rootTy), memberName, memberTy,
2090
+ useDC,
2091
+ isSubscriptRef ? FunctionRefKind::DoubleApply
2092
+ : FunctionRefKind::Unapplied,
2093
+ /* outerAlternatives=*/ {}, keyPathLoc);
2066
2094
2067
2095
// In case of subscript things are more compicated comparing to "dot"
2068
2096
// syntax, because we have to get "applicable function" constraint
@@ -2140,10 +2168,15 @@ std::pair<Type, bool> ConstraintSystem::adjustTypeOfOverloadReference(
2140
2168
2141
2169
if (isa<KeyPathExpr>(locator->getAnchor ()))
2142
2170
verifyThatArgumentIsHashable (0 , keyPathTy, locator);
2171
+
2172
+ // The resolved decl is for subscript(dynamicMember:), however the
2173
+ // original member constraint was either for a property, or we've
2174
+ // re-purposed the overload type variable to represent the result type of
2175
+ // the subscript. In both cases, we need to bind to the result type.
2176
+ bindTypeOrIUO (fnType->getResult ());
2177
+ return ;
2143
2178
}
2144
- return {refType, bindConstraintCreated};
2145
2179
}
2146
-
2147
2180
llvm_unreachable (" Unhandled OverloadChoiceKind in switch." );
2148
2181
}
2149
2182
@@ -2231,8 +2264,7 @@ void ConstraintSystem::resolveOverload(ConstraintLocator *locator,
2231
2264
// getTypeOfMemberReference(); their result types are unchecked
2232
2265
// optional.
2233
2266
std::tie (refType, bindConstraintCreated) =
2234
- adjustTypeOfOverloadReference (choice, locator, boundType, refType,
2235
- useDC, verifyThatArgumentIsHashable);
2267
+ adjustTypeOfOverloadReference (choice, locator, boundType, refType);
2236
2268
break ;
2237
2269
}
2238
2270
@@ -2361,15 +2393,8 @@ void ConstraintSystem::resolveOverload(ConstraintLocator *locator,
2361
2393
2362
2394
// In some cases we already created the appropriate bind constraints.
2363
2395
if (!bindConstraintCreated) {
2364
- if (choice.isImplicitlyUnwrappedValueOrReturnValue ()) {
2365
- // Build the disjunction to attempt binding both T? and T (or
2366
- // function returning T? and function returning T).
2367
- buildDisjunctionForImplicitlyUnwrappedOptional (boundType, refType,
2368
- locator);
2369
- } else {
2370
- // Add the type binding constraint.
2371
- addConstraint (ConstraintKind::Bind, boundType, refType, locator);
2372
- }
2396
+ bindOverloadType (overload, boundType, locator, useDC,
2397
+ verifyThatArgumentIsHashable);
2373
2398
}
2374
2399
2375
2400
if (getASTContext ().TypeCheckerOpts .DebugConstraintSolver ) {
0 commit comments