@@ -2006,24 +2006,44 @@ static ConstraintFix *fixRequirementFailure(ConstraintSystem &cs, Type type1,
2006
2006
// / Attempt to repair typing failures and record fixes if needed.
2007
2007
// / \return true if at least some of the failures has been repaired
2008
2008
// / successfully, which allows type matcher to continue.
2009
- static bool
2010
- repairFailures (ConstraintSystem &cs, Type lhs, Type rhs,
2011
- SmallVectorImpl<RestrictionOrFix> &conversionsOrFixes,
2012
- ConstraintLocatorBuilder locator) {
2009
+ bool ConstraintSystem::repairFailures (
2010
+ Type lhs, Type rhs, SmallVectorImpl<RestrictionOrFix> &conversionsOrFixes,
2011
+ ConstraintLocatorBuilder locator) {
2013
2012
SmallVector<LocatorPathElt, 4 > path;
2014
2013
auto *anchor = locator.getLocatorParts (path);
2015
2014
2016
2015
if (path.empty ()) {
2016
+ if (!anchor)
2017
+ return false ;
2018
+
2017
2019
// If method reference forms a value type of the key path,
2018
2020
// there is going to be a constraint to match result of the
2019
2021
// member lookup to the generic parameter `V` of *KeyPath<R, V>
2020
2022
// type associated with key path expression, which we need to
2021
2023
// fix-up here.
2022
- if (anchor && isa<KeyPathExpr>(anchor)) {
2024
+ if (isa<KeyPathExpr>(anchor)) {
2023
2025
auto *fnType = lhs->getAs <FunctionType>();
2024
2026
if (fnType && fnType->getResult ()->isEqual (rhs))
2025
2027
return true ;
2026
2028
}
2029
+
2030
+ if (isa<AssignExpr>(anchor)) {
2031
+ if (auto *fnType = lhs->getAs <FunctionType>()) {
2032
+ // If left-hand side is a function type but right-hand
2033
+ // side isn't, let's check it would be possible to fix
2034
+ // this by forming an explicit call.
2035
+ if (!rhs->is <FunctionType>() && !rhs->isVoid () &&
2036
+ fnType->getNumParams () == 0 &&
2037
+ matchTypes (fnType->getResult (), rhs, ConstraintKind::Conversion,
2038
+ TypeMatchFlags::TMF_ApplyingFix, locator)
2039
+ .isSuccess ()) {
2040
+ conversionsOrFixes.push_back (
2041
+ InsertExplicitCall::create (*this , getConstraintLocator (locator)));
2042
+ return true ;
2043
+ }
2044
+ }
2045
+ }
2046
+
2027
2047
return false ;
2028
2048
}
2029
2049
@@ -2033,14 +2053,14 @@ repairFailures(ConstraintSystem &cs, Type lhs, Type rhs,
2033
2053
case ConstraintLocator::ApplyArgToParam: {
2034
2054
if (lhs->getOptionalObjectType () && !rhs->getOptionalObjectType ()) {
2035
2055
conversionsOrFixes.push_back (
2036
- ForceOptional::create (cs , lhs, lhs->getOptionalObjectType (),
2037
- cs. getConstraintLocator (locator)));
2056
+ ForceOptional::create (* this , lhs, lhs->getOptionalObjectType (),
2057
+ getConstraintLocator (locator)));
2038
2058
}
2039
2059
break ;
2040
2060
}
2041
2061
2042
2062
case ConstraintLocator::FunctionArgument: {
2043
- auto *argLoc = cs. getConstraintLocator (
2063
+ auto *argLoc = getConstraintLocator (
2044
2064
locator.withPathElement (LocatorPathElt::getSynthesizedArgument (0 )));
2045
2065
2046
2066
// Let's drop the last element which points to a single argument
@@ -2051,7 +2071,7 @@ repairFailures(ConstraintSystem &cs, Type lhs, Type rhs,
2051
2071
path.back ().getKind () == ConstraintLocator::ContextualType))
2052
2072
return false ;
2053
2073
2054
- auto arg = llvm::find_if (cs. getTypeVariables (),
2074
+ auto arg = llvm::find_if (getTypeVariables (),
2055
2075
[&argLoc](const TypeVariableType *typeVar) {
2056
2076
return typeVar->getImpl ().getLocator () == argLoc;
2057
2077
});
@@ -2068,27 +2088,27 @@ repairFailures(ConstraintSystem &cs, Type lhs, Type rhs,
2068
2088
//
2069
2089
// But if `T.Element` didn't get resolved to `Void` we'd like
2070
2090
// to diagnose this as a missing argument which can't be ignored.
2071
- if (arg != cs. getTypeVariables ().end ()) {
2091
+ if (arg != getTypeVariables ().end ()) {
2072
2092
auto fnType = FunctionType::get ({FunctionType::Param (lhs)},
2073
- cs. getASTContext ().TheEmptyTupleType );
2093
+ getASTContext ().TheEmptyTupleType );
2074
2094
conversionsOrFixes.push_back (AddMissingArguments::create (
2075
- cs , fnType, {FunctionType::Param (*arg)},
2076
- cs. getConstraintLocator (anchor, path,
2077
- /* summaryFlags=*/ 0 )));
2095
+ * this , fnType, {FunctionType::Param (*arg)},
2096
+ getConstraintLocator (anchor, path,
2097
+ /* summaryFlags=*/ 0 )));
2078
2098
}
2079
2099
break ;
2080
2100
}
2081
2101
2082
2102
case ConstraintLocator::TypeParameterRequirement:
2083
2103
case ConstraintLocator::ConditionalRequirement: {
2084
- if (auto *fix = fixRequirementFailure (cs , lhs, rhs, anchor, path))
2104
+ if (auto *fix = fixRequirementFailure (* this , lhs, rhs, anchor, path))
2085
2105
conversionsOrFixes.push_back (fix);
2086
2106
break ;
2087
2107
}
2088
2108
2089
2109
case ConstraintLocator::ClosureResult: {
2090
- auto *fix = ContextualMismatch::create (cs , lhs, rhs,
2091
- cs. getConstraintLocator (locator));
2110
+ auto *fix = ContextualMismatch::create (* this , lhs, rhs,
2111
+ getConstraintLocator (locator));
2092
2112
conversionsOrFixes.push_back (fix);
2093
2113
break ;
2094
2114
}
@@ -2098,14 +2118,14 @@ repairFailures(ConstraintSystem &cs, Type lhs, Type rhs,
2098
2118
// between them are mutability and/or root, value type mismatch.
2099
2119
if (isKnownKeyPathType (lhs) && isKnownKeyPathType (rhs)) {
2100
2120
auto *fix = KeyPathContextualMismatch::create (
2101
- cs , lhs, rhs, cs. getConstraintLocator (locator));
2121
+ * this , lhs, rhs, getConstraintLocator (locator));
2102
2122
conversionsOrFixes.push_back (fix);
2103
2123
}
2104
2124
2105
2125
if (lhs->is <FunctionType>() && !rhs->is <AnyFunctionType>() &&
2106
2126
isa<ClosureExpr>(anchor)) {
2107
- auto *fix = ContextualMismatch::create (cs , lhs, rhs,
2108
- cs. getConstraintLocator (locator));
2127
+ auto *fix = ContextualMismatch::create (* this , lhs, rhs,
2128
+ getConstraintLocator (locator));
2109
2129
conversionsOrFixes.push_back (fix);
2110
2130
}
2111
2131
break ;
@@ -2927,7 +2947,7 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
2927
2947
2928
2948
// Attempt to repair any failures identifiable at this point.
2929
2949
if (attemptFixes) {
2930
- if (repairFailures (* this , type1, type2, conversionsOrFixes, locator)) {
2950
+ if (repairFailures (type1, type2, conversionsOrFixes, locator)) {
2931
2951
if (conversionsOrFixes.empty ())
2932
2952
return getTypeMatchSuccess ();
2933
2953
}
@@ -6476,6 +6496,7 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyFixConstraint(
6476
6496
return result;
6477
6497
}
6478
6498
6499
+ case FixKind::InsertCall:
6479
6500
case FixKind::SkipSameTypeRequirement:
6480
6501
case FixKind::SkipSuperclassRequirement:
6481
6502
case FixKind::ContextualMismatch:
@@ -6484,7 +6505,6 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyFixConstraint(
6484
6505
}
6485
6506
6486
6507
case FixKind::UseSubscriptOperator:
6487
- case FixKind::InsertCall:
6488
6508
case FixKind::ExplicitlyEscaping:
6489
6509
case FixKind::CoerceToCheckedCast:
6490
6510
case FixKind::RelabelArguments:
0 commit comments