@@ -3235,6 +3235,16 @@ ConstraintSystem::matchFunctionTypes(FunctionType *func1, FunctionType *func2,
3235
3235
return getTypeMatchFailure(locator);
3236
3236
}
3237
3237
3238
+ // () -> sending T can be a subtype of () -> T... but not vis-a-versa.
3239
+ if (func1->hasSendingResult() != func2->hasSendingResult() &&
3240
+ (!func1->hasSendingResult() || kind < ConstraintKind::Subtype)) {
3241
+ auto *fix = AllowSendingMismatch::create(
3242
+ *this, getConstraintLocator(locator), func1, func2,
3243
+ AllowSendingMismatch::Kind::Result);
3244
+ if (recordFix(fix))
3245
+ return getTypeMatchFailure(locator);
3246
+ }
3247
+
3238
3248
if (!matchFunctionIsolations(func1, func2, kind, flags, locator))
3239
3249
return getTypeMatchFailure(locator);
3240
3250
@@ -3665,6 +3675,17 @@ ConstraintSystem::matchFunctionTypes(FunctionType *func1, FunctionType *func2,
3665
3675
return getTypeMatchFailure(argumentLocator);
3666
3676
}
3667
3677
3678
+ // Do not allow for functions that expect a sending parameter to match
3679
+ // with a function that expects a non-sending parameter.
3680
+ if (func1Param.getParameterFlags().isSending() &&
3681
+ !func2Param.getParameterFlags().isSending()) {
3682
+ auto *fix = AllowSendingMismatch::create(
3683
+ *this, getConstraintLocator(argumentLocator), func1, func2,
3684
+ AllowSendingMismatch::Kind::Parameter);
3685
+ if (recordFix(fix))
3686
+ return getTypeMatchFailure(argumentLocator);
3687
+ }
3688
+
3668
3689
// FIXME: We should check value ownership too, but it's not completely
3669
3690
// trivial because of inout-to-pointer conversions.
3670
3691
@@ -11785,10 +11806,10 @@ bool ConstraintSystem::resolveClosure(TypeVariableType *typeVar,
11785
11806
if (contextualParam->isIsolated() && !flags.isIsolated() && paramDecl)
11786
11807
isolatedParams.insert(paramDecl);
11787
11808
11788
- param =
11789
- param.withFlags(flags.withInOut( contextualParam->isInOut ())
11790
- .withVariadic (contextualParam->isVariadic ())
11791
- .withIsolated (contextualParam->isIsolated ()));
11809
+ param = param.withFlags(flags.withInOut(contextualParam->isInOut())
11810
+ .withVariadic( contextualParam->isVariadic ())
11811
+ .withIsolated (contextualParam->isIsolated ())
11812
+ .withSending (contextualParam->isSending ()));
11792
11813
}
11793
11814
}
11794
11815
@@ -11915,6 +11936,12 @@ bool ConstraintSystem::resolveClosure(TypeVariableType *typeVar,
11915
11936
closureExtInfo = closureExtInfo.withSendable();
11916
11937
}
11917
11938
11939
+ // Propagate sending result from the contextual type to the closure.
11940
+ if (auto contextualFnType = contextualType->getAs<FunctionType>()) {
11941
+ if (contextualFnType->hasExtInfo() && contextualFnType->hasSendingResult())
11942
+ closureExtInfo = closureExtInfo.withSendingResult();
11943
+ }
11944
+
11918
11945
// Isolated parameters override any other kind of isolation we might infer.
11919
11946
if (hasIsolatedParam) {
11920
11947
closureExtInfo = closureExtInfo.withIsolation(
@@ -15113,6 +15140,7 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyFixConstraint(
15113
15140
}
15114
15141
}
15115
15142
15143
+ case FixKind::AllowSendingMismatch:
15116
15144
case FixKind::InsertCall:
15117
15145
case FixKind::RemoveReturn:
15118
15146
case FixKind::RemoveAddressOf:
0 commit comments