@@ -7274,8 +7274,17 @@ ConstraintSystem::simplifyOneWayConstraint(
7274
7274
secondSimplified, first, ConstraintKind::BindParam, flags, locator);
7275
7275
}
7276
7276
7277
- static Type getFunctionBuilderTypeFor (ConstraintSystem &cs, unsigned paramIdx,
7278
- ConstraintLocator *calleeLocator) {
7277
+ static Type getOpenedFunctionBuilderTypeFor (ConstraintSystem &cs,
7278
+ ConstraintLocatorBuilder locator) {
7279
+ auto lastElt = locator.last ();
7280
+ if (!lastElt)
7281
+ return Type ();
7282
+
7283
+ auto argToParamElt = lastElt->getAs <LocatorPathElt::ApplyArgToParam>();
7284
+ if (!argToParamElt)
7285
+ return Type ();
7286
+
7287
+ auto *calleeLocator = cs.getCalleeLocator (cs.getConstraintLocator (locator));
7279
7288
auto selectedOverload = cs.findSelectedOverloadFor (calleeLocator);
7280
7289
if (!(selectedOverload &&
7281
7290
selectedOverload->choice .getKind () == OverloadChoiceKind::Decl))
@@ -7290,8 +7299,27 @@ static Type getFunctionBuilderTypeFor(ConstraintSystem &cs, unsigned paramIdx,
7290
7299
if (!choice->hasParameterList ())
7291
7300
return Type ();
7292
7301
7293
- auto *PD = getParameterAt (choice, paramIdx);
7294
- return PD->getFunctionBuilderType ();
7302
+ auto *PD = getParameterAt (choice, argToParamElt->getParamIdx ());
7303
+ auto builderType = PD->getFunctionBuilderType ();
7304
+ if (!builderType)
7305
+ return Type ();
7306
+
7307
+ // If the builder type has a type parameter, substitute in the type
7308
+ // variables.
7309
+ if (builderType->hasTypeParameter ()) {
7310
+ // Find the opened type for this callee and substitute in the type
7311
+ // parametes.
7312
+ // FIXME: We should consider changing OpenedTypes to a MapVector.
7313
+ for (const auto &opened : cs.getOpenedTypes ()) {
7314
+ if (opened.first == calleeLocator) {
7315
+ OpenedTypeMap replacements (opened.second .begin (), opened.second .end ());
7316
+ builderType = cs.openType (builderType, replacements);
7317
+ break ;
7318
+ }
7319
+ }
7320
+ assert (!builderType->hasTypeParameter ());
7321
+ }
7322
+ return builderType;
7295
7323
}
7296
7324
7297
7325
bool ConstraintSystem::resolveClosure (TypeVariableType *typeVar,
@@ -7310,15 +7338,7 @@ bool ConstraintSystem::resolveClosure(TypeVariableType *typeVar,
7310
7338
auto *inferredClosureType = getClosureType (closure);
7311
7339
7312
7340
// Determine whether a function builder will be applied.
7313
- Type functionBuilderType;
7314
- ConstraintLocator *calleeLocator = nullptr ;
7315
- if (auto last = locator.last ()) {
7316
- if (auto argToParam = last->getAs <LocatorPathElt::ApplyArgToParam>()) {
7317
- calleeLocator = getCalleeLocator (getConstraintLocator (locator));
7318
- functionBuilderType = getFunctionBuilderTypeFor (
7319
- *this , argToParam->getParamIdx (), calleeLocator);
7320
- }
7321
- }
7341
+ auto functionBuilderType = getOpenedFunctionBuilderTypeFor (*this , locator);
7322
7342
7323
7343
// Determine whether to introduce one-way constraints between the parameter's
7324
7344
// type as seen in the body of the closure and the external parameter
@@ -7392,6 +7412,7 @@ bool ConstraintSystem::resolveClosure(TypeVariableType *typeVar,
7392
7412
7393
7413
// If there is a function builder to apply, do so now.
7394
7414
if (functionBuilderType) {
7415
+ auto *calleeLocator = getCalleeLocator (getConstraintLocator (locator));
7395
7416
if (auto result = matchFunctionBuilder (
7396
7417
closure, functionBuilderType, closureType->getResult (),
7397
7418
ConstraintKind::Conversion, calleeLocator, locator)) {
@@ -9884,9 +9905,11 @@ ConstraintSystem::addConstraintImpl(ConstraintKind kind, Type first,
9884
9905
case ConstraintKind::BindToPointerType:
9885
9906
case ConstraintKind::Subtype:
9886
9907
case ConstraintKind::Conversion:
9908
+ return matchTypes (first, second, kind, subflags, locator);
9909
+
9887
9910
case ConstraintKind::ArgumentConversion:
9888
9911
case ConstraintKind::OperatorArgumentConversion:
9889
- return matchTypes (first, second, kind, subflags , locator);
9912
+ return addArgumentConversionConstraintImpl (kind, first, second , locator);
9890
9913
9891
9914
case ConstraintKind::OpaqueUnderlyingType:
9892
9915
return simplifyOpaqueUnderlyingTypeConstraint (first, second,
@@ -9956,6 +9979,36 @@ ConstraintSystem::addConstraintImpl(ConstraintKind kind, Type first,
9956
9979
llvm_unreachable (" Unhandled ConstraintKind in switch." );
9957
9980
}
9958
9981
9982
+ ConstraintSystem::SolutionKind
9983
+ ConstraintSystem::addArgumentConversionConstraintImpl (
9984
+ ConstraintKind kind, Type first, Type second,
9985
+ ConstraintLocatorBuilder locator) {
9986
+ assert (kind == ConstraintKind::ArgumentConversion ||
9987
+ kind == ConstraintKind::OperatorArgumentConversion);
9988
+
9989
+ // If we have an unresolved closure argument, form an unsolved argument
9990
+ // conversion constraint, making sure to reference the type variables for
9991
+ // a function builder if applicable. This ensures we properly connect the
9992
+ // closure type variable with any type variables in the function builder, as
9993
+ // such type variables will be accessible within the body of the closure when
9994
+ // we open it.
9995
+ first = getFixedTypeRecursive (first, /* rvalue*/ false );
9996
+ if (auto *argTypeVar = first->getAs <TypeVariableType>()) {
9997
+ if (argTypeVar->getImpl ().isClosureType ()) {
9998
+ // Extract any type variables present in the parameter's function builder.
9999
+ SmallVector<TypeVariableType *, 4 > typeVars;
10000
+ if (auto builderTy = getOpenedFunctionBuilderTypeFor (*this , locator))
10001
+ builderTy->getTypeVariables (typeVars);
10002
+
10003
+ auto *loc = getConstraintLocator (locator);
10004
+ addUnsolvedConstraint (
10005
+ Constraint::create (*this , kind, first, second, loc, typeVars));
10006
+ return SolutionKind::Solved;
10007
+ }
10008
+ }
10009
+ return matchTypes (first, second, kind, TMF_GenerateConstraints, locator);
10010
+ }
10011
+
9959
10012
void
9960
10013
ConstraintSystem::addKeyPathApplicationRootConstraint (Type root, ConstraintLocatorBuilder locator) {
9961
10014
// If this is a subscript with a KeyPath expression, add a constraint that
0 commit comments