@@ -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 }
@@ -1699,6 +1701,7 @@ ConstraintSystem::matchFunctionTypes(FunctionType *func1, FunctionType *func2,
16991701 case ConstraintKind::FunctionInput:
17001702 case ConstraintKind::FunctionResult:
17011703 case ConstraintKind::OneWayEqual:
1704+ case ConstraintKind::OneWayBindParam:
17021705 case ConstraintKind::DefaultClosureType:
17031706 llvm_unreachable (" Not a relational constraint" );
17041707 }
@@ -4406,6 +4409,7 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
44064409 case ConstraintKind::FunctionInput:
44074410 case ConstraintKind::FunctionResult:
44084411 case ConstraintKind::OneWayEqual:
4412+ case ConstraintKind::OneWayBindParam:
44094413 case ConstraintKind::DefaultClosureType:
44104414 llvm_unreachable (" Not a relational constraint" );
44114415 }
@@ -7121,9 +7125,16 @@ ConstraintSystem::simplifyOneWayConstraint(
71217125 return SolutionKind::Solved;
71227126 }
71237127
7124- // Translate this constraint into a one-way binding constraint.
7125- return matchTypes (first, secondSimplified, ConstraintKind::Equal, flags,
7126- locator);
7128+ // Translate this constraint into an equality or bind-parameter constraint,
7129+ // as appropriate.
7130+ if (kind == ConstraintKind::OneWayEqual) {
7131+ return matchTypes (first, secondSimplified, ConstraintKind::Equal, flags,
7132+ locator);
7133+ }
7134+
7135+ assert (kind == ConstraintKind::OneWayBindParam);
7136+ return matchTypes (
7137+ secondSimplified, first, ConstraintKind::BindParam, flags, locator);
71277138}
71287139
71297140static Type getFunctionBuilderTypeFor (ConstraintSystem &cs, unsigned paramIdx,
@@ -7175,12 +7186,27 @@ bool ConstraintSystem::resolveClosure(TypeVariableType *typeVar,
71757186
71767187 Type internalType;
71777188
7189+ bool oneWayConstraints =
7190+ getASTContext ().TypeCheckerOpts .EnableOneWayClosureParameters ;
71787191 if (paramList->get (i)->getTypeRepr ()) {
71797192 // Internal type is the type used in the body of the closure,
71807193 // so "external" type translates to it as follows:
71817194 // - `Int...` -> `[Int]`,
71827195 // - `inout Int` -> `@lvalue Int`.
71837196 internalType = param.getParameterType ();
7197+
7198+ // When there are type variables in the type and we have enabled
7199+ // one-way constraints, create a fresh type variable to handle the
7200+ // binding.
7201+ if (oneWayConstraints && internalType->hasTypeVariable ()) {
7202+ auto *paramLoc =
7203+ getConstraintLocator (closure, LocatorPathElt::TupleElement (i));
7204+ auto *typeVar = createTypeVariable (paramLoc, TVO_CanBindToLValue |
7205+ TVO_CanBindToNoEscape);
7206+ addConstraint (
7207+ ConstraintKind::OneWayBindParam, typeVar, internalType, paramLoc);
7208+ internalType = typeVar;
7209+ }
71847210 } else {
71857211 auto *paramLoc =
71867212 getConstraintLocator (closure, LocatorPathElt::TupleElement (i));
@@ -7194,7 +7220,13 @@ bool ConstraintSystem::resolveClosure(TypeVariableType *typeVar,
71947220 param.isVariadic () ? ArraySliceType::get (typeVar) : Type (typeVar);
71957221
71967222 auto externalType = param.getOldType ();
7197- addConstraint (ConstraintKind::BindParam, externalType, typeVar, paramLoc);
7223+ if (oneWayConstraints) {
7224+ addConstraint (
7225+ ConstraintKind::OneWayBindParam, typeVar, externalType, paramLoc);
7226+ } else {
7227+ addConstraint (
7228+ ConstraintKind::BindParam, externalType, typeVar, paramLoc);
7229+ }
71987230 }
71997231
72007232 setType (paramList->get (i), internalType);
@@ -9759,6 +9791,7 @@ ConstraintSystem::addConstraintImpl(ConstraintKind kind, Type first,
97599791 subflags, locator);
97609792
97619793 case ConstraintKind::OneWayEqual:
9794+ case ConstraintKind::OneWayBindParam:
97629795 return simplifyOneWayConstraint (kind, first, second, subflags, locator);
97639796
97649797 case ConstraintKind::ValueMember:
@@ -10271,6 +10304,7 @@ ConstraintSystem::simplifyConstraint(const Constraint &constraint) {
1027110304 return SolutionKind::Unsolved;
1027210305
1027310306 case ConstraintKind::OneWayEqual:
10307+ case ConstraintKind::OneWayBindParam:
1027410308 return simplifyOneWayConstraint (constraint.getKind (),
1027510309 constraint.getFirstType (),
1027610310 constraint.getSecondType (),
0 commit comments