Skip to content

Commit de3b4ba

Browse files
committed
[Constraint System] Exclude 'Single' and 'Double' function application from Sendable Inference
1 parent 619a517 commit de3b4ba

File tree

2 files changed

+47
-29
lines changed

2 files changed

+47
-29
lines changed

include/swift/Basic/Features.def

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -252,18 +252,16 @@ EXPERIMENTAL_FEATURE(TypedThrows, true)
252252
/// Allow destructuring stored `let` bindings in structs.
253253
EXPERIMENTAL_FEATURE(StructLetDestructuring, true)
254254

255-
<<<<<<< HEAD
256255
/// Enable non-escapable type attributes and function attributes that support
257256
/// lifetime-dependent results.
258257
EXPERIMENTAL_FEATURE(NonEscapableTypes, false)
259258

260259
/// Enable the `@extern` attribute.
261260
EXPERIMENTAL_FEATURE(Extern, true)
262-
=======
261+
263262
// Infer Sendability of unapplied and partial applied methods
264263
// based on type. Global functions are always implicitly Sendable
265264
EXPERIMENTAL_FEATURE(InferSendableMethods, false)
266-
>>>>>>> 175f54caad6 ([Frontend] Feature flag for InferredSendableMethods)
267265

268266
#undef EXPERIMENTAL_FEATURE_EXCLUDED_FROM_MODULE_INTERFACE
269267
#undef EXPERIMENTAL_FEATURE

lib/Sema/ConstraintSystem.cpp

Lines changed: 46 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2426,6 +2426,41 @@ Type ConstraintSystem::getMemberReferenceTypeFromOpenedType(
24262426
return type;
24272427
}
24282428

2429+
2430+
bool isPartialApplication(ConstraintSystem &cs,
2431+
const AbstractFunctionDecl *member,
2432+
ConstraintLocator *locator) {
2433+
// If this is a compiler synthesized implicit conversion, let's skip
2434+
// the check because the base of `UDE` is not the base of the injected
2435+
// initializer.
2436+
if (locator->isLastElement<LocatorPathElt::ConstructorMember>() &&
2437+
locator->findFirst<LocatorPathElt::ImplicitConversion>())
2438+
return false;
2439+
2440+
auto *UDE = getAsExpr<UnresolvedDotExpr>(locator->getAnchor());
2441+
if (UDE == nullptr)
2442+
return false;
2443+
2444+
auto baseTy =
2445+
cs.simplifyType(cs.getType(UDE->getBase()))->getWithoutSpecifierType();
2446+
2447+
// If base is a metatype it would be ignored (unless this is an initializer
2448+
// call), but if it is some other type it means that we have a single
2449+
// application level already.
2450+
unsigned level = 0;
2451+
if (!baseTy->is<MetatypeType>())
2452+
++level;
2453+
2454+
if (auto *call = dyn_cast_or_null<CallExpr>(cs.getParentExpr(UDE))) {
2455+
level += 1;
2456+
}
2457+
2458+
if (level == 2)
2459+
return false;
2460+
2461+
return true;
2462+
}
2463+
24292464
DeclReferenceType
24302465
ConstraintSystem::getTypeOfMemberReference(
24312466
Type baseTy, ValueDecl *value, DeclContext *useDC,
@@ -2636,36 +2671,21 @@ ConstraintSystem::getTypeOfMemberReference(
26362671
functionType, locator);
26372672
auto &ctx = DC->getASTContext();
26382673
auto *parentModule = useDC->getParentModule();
2639-
bool baseTypeSendable = isSendableType(parentModule, baseOpenedTy);
26402674
bool inferredSendable =
26412675
ctx.LangOpts.hasFeature(Feature::InferSendableMethods);
26422676

2643-
if (inferredSendable) {
2644-
auto sendableProtocol = parentModule->getASTContext().getProtocol(
2645-
KnownProtocolKind::Sendable);
2646-
auto baseConformance =
2647-
parentModule->lookupConformance(baseOpenedTy, sendableProtocol);
2648-
2649-
if (baseTypeSendable) {
2677+
bool isPartialApply;
2678+
isPartialApply = isPartialApplication(*this, funcDecl, locator);
2679+
2680+
if (inferredSendable && isPartialApply) {
2681+
// auto sendableProtocol = parentModule->getASTContext().getProtocol(
2682+
// KnownProtocolKind::Sendable);
2683+
// auto baseConformance =
2684+
// parentModule->lookupConformance(baseOpenedTy, sendableProtocol);
2685+
2686+
if (isSendableType(parentModule, baseOpenedTy)) {
26502687
// Add @Sendable to functions without conditional conformances
2651-
if (baseConformance.getConditionalRequirements().empty()) {
2652-
functionType = functionType->withExtInfo(functionType->getExtInfo().withConcurrent())->getAs<FunctionType>();
2653-
} else {
2654-
// Handle Conditional Conformances
2655-
auto substitutionMap = SubstitutionMap::getProtocolSubstitutions(
2656-
sendableProtocol, baseOpenedTy, baseConformance);
2657-
2658-
auto result = TypeChecker::checkGenericArguments(
2659-
parentModule, baseConformance.getConditionalRequirements(),
2660-
QuerySubstitutionMap{substitutionMap});
2661-
2662-
if (result == CheckGenericArgumentsResult::Success) {
2663-
functionType =
2664-
functionType
2665-
->withExtInfo(functionType->getExtInfo().withConcurrent())
2666-
->getAs<FunctionType>();
2667-
}
2668-
}
2688+
functionType = functionType->withExtInfo(functionType->getExtInfo().withConcurrent())->getAs<FunctionType>();
26692689
}
26702690
}
26712691

0 commit comments

Comments
 (0)