@@ -1322,6 +1322,7 @@ ConstraintSystem::matchTupleTypes(TupleType *tuple1, TupleType *tuple2,
13221322 case ConstraintKind::FunctionInput:
13231323 case ConstraintKind::FunctionResult:
13241324 case ConstraintKind::OneWayEqual:
1325+ case ConstraintKind::OneWayBindParam:
13251326 case ConstraintKind::DefaultClosureType:
13261327 llvm_unreachable (" Not a conversion" );
13271328 }
@@ -1387,6 +1388,7 @@ static bool matchFunctionRepresentations(FunctionTypeRepresentation rep1,
13871388 case ConstraintKind::FunctionInput:
13881389 case ConstraintKind::FunctionResult:
13891390 case ConstraintKind::OneWayEqual:
1391+ case ConstraintKind::OneWayBindParam:
13901392 case ConstraintKind::DefaultClosureType:
13911393 return false ;
13921394 }
@@ -1698,6 +1700,7 @@ ConstraintSystem::matchFunctionTypes(FunctionType *func1, FunctionType *func2,
16981700 case ConstraintKind::FunctionInput:
16991701 case ConstraintKind::FunctionResult:
17001702 case ConstraintKind::OneWayEqual:
1703+ case ConstraintKind::OneWayBindParam:
17011704 case ConstraintKind::DefaultClosureType:
17021705 llvm_unreachable (" Not a relational constraint" );
17031706 }
@@ -4340,6 +4343,7 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
43404343 case ConstraintKind::FunctionInput:
43414344 case ConstraintKind::FunctionResult:
43424345 case ConstraintKind::OneWayEqual:
4346+ case ConstraintKind::OneWayBindParam:
43434347 case ConstraintKind::DefaultClosureType:
43444348 llvm_unreachable (" Not a relational constraint" );
43454349 }
@@ -7064,9 +7068,16 @@ ConstraintSystem::simplifyOneWayConstraint(
70647068 return SolutionKind::Solved;
70657069 }
70667070
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);
70707081}
70717082
70727083static Type getFunctionBuilderTypeFor (ConstraintSystem &cs, unsigned paramIdx,
@@ -7104,6 +7115,24 @@ bool ConstraintSystem::resolveClosure(TypeVariableType *typeVar,
71047115 auto *closure = cast<ClosureExpr>(closureLocator->getAnchor ());
71057116 auto *inferredClosureType = getClosureType (closure);
71067117
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+
71077136 auto *paramList = closure->getParameters ();
71087137 SmallVector<AnyFunctionType::Param, 4 > parameters;
71097138 for (unsigned i = 0 , n = paramList->size (); i != n; ++i) {
@@ -7117,13 +7146,25 @@ bool ConstraintSystem::resolveClosure(TypeVariableType *typeVar,
71177146 }
71187147
71197148 Type internalType;
7120-
71217149 if (paramList->get (i)->getTypeRepr ()) {
71227150 // Internal type is the type used in the body of the closure,
71237151 // so "external" type translates to it as follows:
71247152 // - `Int...` -> `[Int]`,
71257153 // - `inout Int` -> `@lvalue Int`.
71267154 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+ }
71277168 } else {
71287169 auto *paramLoc =
71297170 getConstraintLocator (closure, LocatorPathElt::TupleElement (i));
@@ -7137,7 +7178,13 @@ bool ConstraintSystem::resolveClosure(TypeVariableType *typeVar,
71377178 param.isVariadic () ? ArraySliceType::get (typeVar) : Type (typeVar);
71387179
71397180 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+ }
71417188 }
71427189
71437190 setType (paramList->get (i), internalType);
@@ -7149,17 +7196,12 @@ bool ConstraintSystem::resolveClosure(TypeVariableType *typeVar,
71497196 inferredClosureType->getExtInfo ());
71507197 assignFixedType (typeVar, closureType, closureLocator);
71517198
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 ();
71637205 }
71647206 }
71657207
@@ -9687,6 +9729,7 @@ ConstraintSystem::addConstraintImpl(ConstraintKind kind, Type first,
96879729 subflags, locator);
96889730
96899731 case ConstraintKind::OneWayEqual:
9732+ case ConstraintKind::OneWayBindParam:
96909733 return simplifyOneWayConstraint (kind, first, second, subflags, locator);
96919734
96929735 case ConstraintKind::ValueMember:
@@ -10194,6 +10237,7 @@ ConstraintSystem::simplifyConstraint(const Constraint &constraint) {
1019410237 return SolutionKind::Unsolved;
1019510238
1019610239 case ConstraintKind::OneWayEqual:
10240+ case ConstraintKind::OneWayBindParam:
1019710241 return simplifyOneWayConstraint (constraint.getKind (),
1019810242 constraint.getFirstType (),
1019910243 constraint.getSecondType (),
0 commit comments