@@ -2020,6 +2020,51 @@ bool ConstraintSystem::repairFailures(
2020
2020
SmallVector<LocatorPathElt, 4 > path;
2021
2021
auto *anchor = locator.getLocatorParts (path);
2022
2022
2023
+ // If there is a missing explicit call it could be:
2024
+ //
2025
+ // a). Contextual e.g. `let _: R = foo`
2026
+ // b). Argument is a function value passed to parameter
2027
+ // which expects its result type e.g. `foo(bar)`
2028
+ // c). Assigment destination type matches return type of
2029
+ // of the function value e.g. `foo = bar` or `foo = .bar`
2030
+ auto repairByInsertingExplicitCall = [&](Type srcType, Type dstType) -> bool {
2031
+ auto fnType = srcType->getAs <FunctionType>();
2032
+ if (!fnType || fnType->getNumParams () > 0 )
2033
+ return false ;
2034
+
2035
+ auto resultType = fnType->getResult ();
2036
+ // If this is situation like `x = { ... }` where closure results in
2037
+ // `Void`, let's not suggest to call the closure, because it's most
2038
+ // likely not intended.
2039
+ if (anchor && isa<AssignExpr>(anchor)) {
2040
+ auto *assignment = cast<AssignExpr>(anchor);
2041
+ if (isa<ClosureExpr>(assignment->getSrc ()) && resultType->isVoid ())
2042
+ return false ;
2043
+ }
2044
+
2045
+ // If left-hand side is a function type but right-hand
2046
+ // side isn't, let's check it would be possible to fix
2047
+ // this by forming an explicit call.
2048
+ auto convertTo = dstType->lookThroughAllOptionalTypes ();
2049
+ // Right-hand side can't be - a function, a type variable or dependent
2050
+ // member, or `Any` (if function conversion to `Any` didn't succeed there
2051
+ // is something else going on e.g. problem with escapiness).
2052
+ if (convertTo->is <FunctionType>() || convertTo->isTypeVariableOrMember () ||
2053
+ convertTo->isAny ())
2054
+ return false ;
2055
+
2056
+ auto result = matchTypes (resultType, dstType, ConstraintKind::Conversion,
2057
+ TypeMatchFlags::TMF_ApplyingFix, locator);
2058
+
2059
+ if (result.isSuccess ()) {
2060
+ conversionsOrFixes.push_back (
2061
+ InsertExplicitCall::create (*this , getConstraintLocator (locator)));
2062
+ return true ;
2063
+ }
2064
+
2065
+ return false ;
2066
+ };
2067
+
2023
2068
if (path.empty ()) {
2024
2069
if (!anchor)
2025
2070
return false ;
@@ -2036,21 +2081,8 @@ bool ConstraintSystem::repairFailures(
2036
2081
}
2037
2082
2038
2083
if (auto *AE = dyn_cast<AssignExpr>(anchor)) {
2039
- if (auto *fnType = lhs->getAs <FunctionType>()) {
2040
- // If left-hand side is a function type but right-hand
2041
- // side isn't, let's check it would be possible to fix
2042
- // this by forming an explicit call.
2043
- auto convertTo = rhs->lookThroughAllOptionalTypes ();
2044
- if (!convertTo->is <FunctionType>() && !convertTo->isVoid () &&
2045
- fnType->getNumParams () == 0 &&
2046
- matchTypes (fnType->getResult (), rhs, ConstraintKind::Conversion,
2047
- TypeMatchFlags::TMF_ApplyingFix, locator)
2048
- .isSuccess ()) {
2049
- conversionsOrFixes.push_back (
2050
- InsertExplicitCall::create (*this , getConstraintLocator (locator)));
2051
- return true ;
2052
- }
2053
- }
2084
+ if (repairByInsertingExplicitCall (lhs, rhs))
2085
+ return true ;
2054
2086
2055
2087
if (isa<InOutExpr>(AE->getSrc ())) {
2056
2088
conversionsOrFixes.push_back (
@@ -2066,6 +2098,9 @@ bool ConstraintSystem::repairFailures(
2066
2098
switch (elt.getKind ()) {
2067
2099
case ConstraintLocator::LValueConversion:
2068
2100
case ConstraintLocator::ApplyArgToParam: {
2101
+ if (repairByInsertingExplicitCall (lhs, rhs))
2102
+ return true ;
2103
+
2069
2104
if (lhs->getOptionalObjectType () && !rhs->getOptionalObjectType ()) {
2070
2105
conversionsOrFixes.push_back (
2071
2106
ForceOptional::create (*this , lhs, lhs->getOptionalObjectType (),
@@ -2137,6 +2172,9 @@ bool ConstraintSystem::repairFailures(
2137
2172
return true ;
2138
2173
}
2139
2174
2175
+ if (repairByInsertingExplicitCall (lhs, rhs))
2176
+ return true ;
2177
+
2140
2178
// If both types are key path, the only differences
2141
2179
// between them are mutability and/or root, value type mismatch.
2142
2180
if (isKnownKeyPathType (lhs) && isKnownKeyPathType (rhs)) {
@@ -2154,6 +2192,12 @@ bool ConstraintSystem::repairFailures(
2154
2192
break ;
2155
2193
}
2156
2194
2195
+ case ConstraintLocator::AutoclosureResult: {
2196
+ if (repairByInsertingExplicitCall (lhs, rhs))
2197
+ return true ;
2198
+ break ;
2199
+ }
2200
+
2157
2201
default :
2158
2202
break ;
2159
2203
}
0 commit comments