@@ -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,
@@ -7118,12 +7129,27 @@ bool ConstraintSystem::resolveClosure(TypeVariableType *typeVar,
7118
7129
7119
7130
Type internalType;
7120
7131
7132
+ bool oneWayConstraints =
7133
+ getASTContext ().TypeCheckerOpts .EnableOneWayClosureParameters ;
7121
7134
if (paramList->get (i)->getTypeRepr ()) {
7122
7135
// Internal type is the type used in the body of the closure,
7123
7136
// so "external" type translates to it as follows:
7124
7137
// - `Int...` -> `[Int]`,
7125
7138
// - `inout Int` -> `@lvalue Int`.
7126
7139
internalType = param.getParameterType ();
7140
+
7141
+ // When there are type variables in the type and we have enabled
7142
+ // one-way constraints, create a fresh type variable to handle the
7143
+ // binding.
7144
+ if (oneWayConstraints && internalType->hasTypeVariable ()) {
7145
+ auto *paramLoc =
7146
+ getConstraintLocator (closure, LocatorPathElt::TupleElement (i));
7147
+ auto *typeVar = createTypeVariable (paramLoc, TVO_CanBindToLValue |
7148
+ TVO_CanBindToNoEscape);
7149
+ addConstraint (
7150
+ ConstraintKind::OneWayBindParam, typeVar, internalType, paramLoc);
7151
+ internalType = typeVar;
7152
+ }
7127
7153
} else {
7128
7154
auto *paramLoc =
7129
7155
getConstraintLocator (closure, LocatorPathElt::TupleElement (i));
@@ -7137,7 +7163,13 @@ bool ConstraintSystem::resolveClosure(TypeVariableType *typeVar,
7137
7163
param.isVariadic () ? ArraySliceType::get (typeVar) : Type (typeVar);
7138
7164
7139
7165
auto externalType = param.getOldType ();
7140
- addConstraint (ConstraintKind::BindParam, externalType, typeVar, paramLoc);
7166
+ if (oneWayConstraints) {
7167
+ addConstraint (
7168
+ ConstraintKind::OneWayBindParam, typeVar, externalType, paramLoc);
7169
+ } else {
7170
+ addConstraint (
7171
+ ConstraintKind::BindParam, externalType, typeVar, paramLoc);
7172
+ }
7141
7173
}
7142
7174
7143
7175
setType (paramList->get (i), internalType);
@@ -9687,6 +9719,7 @@ ConstraintSystem::addConstraintImpl(ConstraintKind kind, Type first,
9687
9719
subflags, locator);
9688
9720
9689
9721
case ConstraintKind::OneWayEqual:
9722
+ case ConstraintKind::OneWayBindParam:
9690
9723
return simplifyOneWayConstraint (kind, first, second, subflags, locator);
9691
9724
9692
9725
case ConstraintKind::ValueMember:
@@ -10194,6 +10227,7 @@ ConstraintSystem::simplifyConstraint(const Constraint &constraint) {
10194
10227
return SolutionKind::Unsolved;
10195
10228
10196
10229
case ConstraintKind::OneWayEqual:
10230
+ case ConstraintKind::OneWayBindParam:
10197
10231
return simplifyOneWayConstraint (constraint.getKind (),
10198
10232
constraint.getFirstType (),
10199
10233
constraint.getSecondType (),
0 commit comments