@@ -1978,6 +1978,51 @@ bool ConstraintSystem::repairFailures(
1978
1978
SmallVector<LocatorPathElt, 4 > path;
1979
1979
auto *anchor = locator.getLocatorParts (path);
1980
1980
1981
+ // If there is a missing explicit call it could be:
1982
+ //
1983
+ // a). Contextual e.g. `let _: R = foo`
1984
+ // b). Argument is a function value passed to parameter
1985
+ // which expects its result type e.g. `foo(bar)`
1986
+ // c). Assigment destination type matches return type of
1987
+ // of the function value e.g. `foo = bar` or `foo = .bar`
1988
+ auto repairByInsertingExplicitCall = [&](Type srcType, Type dstType) -> bool {
1989
+ auto fnType = srcType->getAs <FunctionType>();
1990
+ if (!fnType || fnType->getNumParams () > 0 )
1991
+ return false ;
1992
+
1993
+ auto resultType = fnType->getResult ();
1994
+ // If this is situation like `x = { ... }` where closure results in
1995
+ // `Void`, let's not suggest to call the closure, because it's most
1996
+ // likely not intended.
1997
+ if (anchor && isa<AssignExpr>(anchor)) {
1998
+ auto *assignment = cast<AssignExpr>(anchor);
1999
+ if (isa<ClosureExpr>(assignment->getSrc ()) && resultType->isVoid ())
2000
+ return false ;
2001
+ }
2002
+
2003
+ // If left-hand side is a function type but right-hand
2004
+ // side isn't, let's check it would be possible to fix
2005
+ // this by forming an explicit call.
2006
+ auto convertTo = dstType->lookThroughAllOptionalTypes ();
2007
+ // Right-hand side can't be - a function, a type variable or dependent
2008
+ // member, or `Any` (if function conversion to `Any` didn't succeed there
2009
+ // is something else going on e.g. problem with escapiness).
2010
+ if (convertTo->is <FunctionType>() || convertTo->isTypeVariableOrMember () ||
2011
+ convertTo->isAny ())
2012
+ return false ;
2013
+
2014
+ auto result = matchTypes (resultType, dstType, ConstraintKind::Conversion,
2015
+ TypeMatchFlags::TMF_ApplyingFix, locator);
2016
+
2017
+ if (result.isSuccess ()) {
2018
+ conversionsOrFixes.push_back (
2019
+ InsertExplicitCall::create (*this , getConstraintLocator (locator)));
2020
+ return true ;
2021
+ }
2022
+
2023
+ return false ;
2024
+ };
2025
+
1981
2026
if (path.empty ()) {
1982
2027
if (!anchor)
1983
2028
return false ;
@@ -1994,21 +2039,8 @@ bool ConstraintSystem::repairFailures(
1994
2039
}
1995
2040
1996
2041
if (auto *AE = dyn_cast<AssignExpr>(anchor)) {
1997
- if (auto *fnType = lhs->getAs <FunctionType>()) {
1998
- // If left-hand side is a function type but right-hand
1999
- // side isn't, let's check it would be possible to fix
2000
- // this by forming an explicit call.
2001
- auto convertTo = rhs->lookThroughAllOptionalTypes ();
2002
- if (!convertTo->is <FunctionType>() && !convertTo->isVoid () &&
2003
- fnType->getNumParams () == 0 &&
2004
- matchTypes (fnType->getResult (), rhs, ConstraintKind::Conversion,
2005
- TypeMatchFlags::TMF_ApplyingFix, locator)
2006
- .isSuccess ()) {
2007
- conversionsOrFixes.push_back (
2008
- InsertExplicitCall::create (*this , getConstraintLocator (locator)));
2009
- return true ;
2010
- }
2011
- }
2042
+ if (repairByInsertingExplicitCall (lhs, rhs))
2043
+ return true ;
2012
2044
2013
2045
if (isa<InOutExpr>(AE->getSrc ())) {
2014
2046
conversionsOrFixes.push_back (
@@ -2024,6 +2056,9 @@ bool ConstraintSystem::repairFailures(
2024
2056
switch (elt.getKind ()) {
2025
2057
case ConstraintLocator::LValueConversion:
2026
2058
case ConstraintLocator::ApplyArgToParam: {
2059
+ if (repairByInsertingExplicitCall (lhs, rhs))
2060
+ return true ;
2061
+
2027
2062
if (lhs->getOptionalObjectType () && !rhs->getOptionalObjectType ()) {
2028
2063
conversionsOrFixes.push_back (
2029
2064
ForceOptional::create (*this , lhs, lhs->getOptionalObjectType (),
@@ -2095,6 +2130,9 @@ bool ConstraintSystem::repairFailures(
2095
2130
return true ;
2096
2131
}
2097
2132
2133
+ if (repairByInsertingExplicitCall (lhs, rhs))
2134
+ return true ;
2135
+
2098
2136
// If both types are key path, the only differences
2099
2137
// between them are mutability and/or root, value type mismatch.
2100
2138
if (isKnownKeyPathType (lhs) && isKnownKeyPathType (rhs)) {
@@ -2112,6 +2150,12 @@ bool ConstraintSystem::repairFailures(
2112
2150
break ;
2113
2151
}
2114
2152
2153
+ case ConstraintLocator::AutoclosureResult: {
2154
+ if (repairByInsertingExplicitCall (lhs, rhs))
2155
+ return true ;
2156
+ break ;
2157
+ }
2158
+
2115
2159
default :
2116
2160
break ;
2117
2161
}
0 commit comments