@@ -1322,6 +1322,7 @@ ConstraintSystem::matchTupleTypes(TupleType *tuple1, TupleType *tuple2,
1322
1322
case ConstraintKind::FunctionInput:
1323
1323
case ConstraintKind::FunctionResult:
1324
1324
case ConstraintKind::OneWayEqual:
1325
+ case ConstraintKind::OneWayBindParam:
1325
1326
case ConstraintKind::DefaultClosureType:
1326
1327
llvm_unreachable (" Not a conversion" );
1327
1328
}
@@ -1387,6 +1388,7 @@ static bool matchFunctionRepresentations(FunctionTypeRepresentation rep1,
1387
1388
case ConstraintKind::FunctionInput:
1388
1389
case ConstraintKind::FunctionResult:
1389
1390
case ConstraintKind::OneWayEqual:
1391
+ case ConstraintKind::OneWayBindParam:
1390
1392
case ConstraintKind::DefaultClosureType:
1391
1393
return false ;
1392
1394
}
@@ -1698,6 +1700,7 @@ ConstraintSystem::matchFunctionTypes(FunctionType *func1, FunctionType *func2,
1698
1700
case ConstraintKind::FunctionInput:
1699
1701
case ConstraintKind::FunctionResult:
1700
1702
case ConstraintKind::OneWayEqual:
1703
+ case ConstraintKind::OneWayBindParam:
1701
1704
case ConstraintKind::DefaultClosureType:
1702
1705
llvm_unreachable (" Not a relational constraint" );
1703
1706
}
@@ -4340,6 +4343,7 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
4340
4343
case ConstraintKind::FunctionInput:
4341
4344
case ConstraintKind::FunctionResult:
4342
4345
case ConstraintKind::OneWayEqual:
4346
+ case ConstraintKind::OneWayBindParam:
4343
4347
case ConstraintKind::DefaultClosureType:
4344
4348
llvm_unreachable (" Not a relational constraint" );
4345
4349
}
@@ -7064,9 +7068,16 @@ ConstraintSystem::simplifyOneWayConstraint(
7064
7068
return SolutionKind::Solved;
7065
7069
}
7066
7070
7067
- // Translate this constraint into a one-way binding constraint.
7068
- return matchTypes (first, secondSimplified, ConstraintKind::Equal, flags,
7069
- locator);
7071
+ // Translate this constraint into an equality or bind-parameter constraint,
7072
+ // as appropriate.
7073
+ if (kind == ConstraintKind::OneWayEqual) {
7074
+ return matchTypes (first, secondSimplified, ConstraintKind::Equal, flags,
7075
+ locator);
7076
+ }
7077
+
7078
+ assert (kind == ConstraintKind::OneWayBindParam);
7079
+ return matchTypes (
7080
+ secondSimplified, first, ConstraintKind::BindParam, flags, locator);
7070
7081
}
7071
7082
7072
7083
static Type getFunctionBuilderTypeFor (ConstraintSystem &cs, unsigned paramIdx,
@@ -7104,6 +7115,24 @@ bool ConstraintSystem::resolveClosure(TypeVariableType *typeVar,
7104
7115
auto *closure = cast<ClosureExpr>(closureLocator->getAnchor ());
7105
7116
auto *inferredClosureType = getClosureType (closure);
7106
7117
7118
+ // Determine whether a function builder will be applied.
7119
+ Type functionBuilderType;
7120
+ ConstraintLocator *calleeLocator = nullptr ;
7121
+ if (auto last = locator.last ()) {
7122
+ if (auto argToParam = last->getAs <LocatorPathElt::ApplyArgToParam>()) {
7123
+ calleeLocator = getCalleeLocator (getConstraintLocator (locator));
7124
+ functionBuilderType = getFunctionBuilderTypeFor (
7125
+ *this , argToParam->getParamIdx (), calleeLocator);
7126
+ }
7127
+ }
7128
+
7129
+ // Determine whether to introduce one-way constraints between the parameter's
7130
+ // type as seen in the body of the closure and the external parameter
7131
+ // type.
7132
+ bool oneWayConstraints =
7133
+ getASTContext ().TypeCheckerOpts .EnableOneWayClosureParameters ||
7134
+ functionBuilderType;
7135
+
7107
7136
auto *paramList = closure->getParameters ();
7108
7137
SmallVector<AnyFunctionType::Param, 4 > parameters;
7109
7138
for (unsigned i = 0 , n = paramList->size (); i != n; ++i) {
@@ -7117,13 +7146,25 @@ bool ConstraintSystem::resolveClosure(TypeVariableType *typeVar,
7117
7146
}
7118
7147
7119
7148
Type internalType;
7120
-
7121
7149
if (paramList->get (i)->getTypeRepr ()) {
7122
7150
// Internal type is the type used in the body of the closure,
7123
7151
// so "external" type translates to it as follows:
7124
7152
// - `Int...` -> `[Int]`,
7125
7153
// - `inout Int` -> `@lvalue Int`.
7126
7154
internalType = param.getParameterType ();
7155
+
7156
+ // When there are type variables in the type and we have enabled
7157
+ // one-way constraints, create a fresh type variable to handle the
7158
+ // binding.
7159
+ if (oneWayConstraints && internalType->hasTypeVariable ()) {
7160
+ auto *paramLoc =
7161
+ getConstraintLocator (closure, LocatorPathElt::TupleElement (i));
7162
+ auto *typeVar = createTypeVariable (paramLoc, TVO_CanBindToLValue |
7163
+ TVO_CanBindToNoEscape);
7164
+ addConstraint (
7165
+ ConstraintKind::OneWayBindParam, typeVar, internalType, paramLoc);
7166
+ internalType = typeVar;
7167
+ }
7127
7168
} else {
7128
7169
auto *paramLoc =
7129
7170
getConstraintLocator (closure, LocatorPathElt::TupleElement (i));
@@ -7137,7 +7178,13 @@ bool ConstraintSystem::resolveClosure(TypeVariableType *typeVar,
7137
7178
param.isVariadic () ? ArraySliceType::get (typeVar) : Type (typeVar);
7138
7179
7139
7180
auto externalType = param.getOldType ();
7140
- addConstraint (ConstraintKind::BindParam, externalType, typeVar, paramLoc);
7181
+ if (oneWayConstraints) {
7182
+ addConstraint (
7183
+ ConstraintKind::OneWayBindParam, typeVar, externalType, paramLoc);
7184
+ } else {
7185
+ addConstraint (
7186
+ ConstraintKind::BindParam, externalType, typeVar, paramLoc);
7187
+ }
7141
7188
}
7142
7189
7143
7190
setType (paramList->get (i), internalType);
@@ -7149,17 +7196,12 @@ bool ConstraintSystem::resolveClosure(TypeVariableType *typeVar,
7149
7196
inferredClosureType->getExtInfo ());
7150
7197
assignFixedType (typeVar, closureType, closureLocator);
7151
7198
7152
- if (auto last = locator.last ()) {
7153
- if (auto argToParam = last->getAs <LocatorPathElt::ApplyArgToParam>()) {
7154
- auto *calleeLocator = getCalleeLocator (getConstraintLocator (locator));
7155
- if (auto functionBuilderType = getFunctionBuilderTypeFor (
7156
- *this , argToParam->getParamIdx (), calleeLocator)) {
7157
- if (auto result = matchFunctionBuilder (
7158
- closure, functionBuilderType, closureType->getResult (),
7159
- ConstraintKind::Conversion, calleeLocator, locator)) {
7160
- return result->isSuccess ();
7161
- }
7162
- }
7199
+ // If there is a function builder to apply, do so now.
7200
+ if (functionBuilderType) {
7201
+ if (auto result = matchFunctionBuilder (
7202
+ closure, functionBuilderType, closureType->getResult (),
7203
+ ConstraintKind::Conversion, calleeLocator, locator)) {
7204
+ return result->isSuccess ();
7163
7205
}
7164
7206
}
7165
7207
@@ -9687,6 +9729,7 @@ ConstraintSystem::addConstraintImpl(ConstraintKind kind, Type first,
9687
9729
subflags, locator);
9688
9730
9689
9731
case ConstraintKind::OneWayEqual:
9732
+ case ConstraintKind::OneWayBindParam:
9690
9733
return simplifyOneWayConstraint (kind, first, second, subflags, locator);
9691
9734
9692
9735
case ConstraintKind::ValueMember:
@@ -10194,6 +10237,7 @@ ConstraintSystem::simplifyConstraint(const Constraint &constraint) {
10194
10237
return SolutionKind::Unsolved;
10195
10238
10196
10239
case ConstraintKind::OneWayEqual:
10240
+ case ConstraintKind::OneWayBindParam:
10197
10241
return simplifyOneWayConstraint (constraint.getKind (),
10198
10242
constraint.getFirstType (),
10199
10243
constraint.getSecondType (),
0 commit comments