Skip to content

Commit 549bace

Browse files
committed
[ConstraintSystem] Move @sendable inference for partially applied members to adjustFunctionTypeForConcurrency
(cherry picked from commit a7f9a68)
1 parent 3963122 commit 549bace

File tree

4 files changed

+44
-47
lines changed

4 files changed

+44
-47
lines changed

include/swift/Sema/ConstraintSystem.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4371,7 +4371,7 @@ class ConstraintSystem {
43714371
/// Wrapper over swift::adjustFunctionTypeForConcurrency that passes along
43724372
/// the appropriate closure-type and opening extraction functions.
43734373
FunctionType *adjustFunctionTypeForConcurrency(
4374-
FunctionType *fnType, ValueDecl *decl, DeclContext *dc,
4374+
FunctionType *fnType, Type baseType, ValueDecl *decl, DeclContext *dc,
43754375
unsigned numApplies, bool isMainDispatchQueue,
43764376
OpenedTypeMap &replacements, ConstraintLocatorBuilder locator);
43774377

lib/Sema/ConstraintSystem.cpp

Lines changed: 32 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1696,8 +1696,8 @@ static bool isRequirementOrWitness(const ConstraintLocatorBuilder &locator) {
16961696
}
16971697

16981698
FunctionType *ConstraintSystem::adjustFunctionTypeForConcurrency(
1699-
FunctionType *fnType, ValueDecl *decl, DeclContext *dc, unsigned numApplies,
1700-
bool isMainDispatchQueue, OpenedTypeMap &replacements,
1699+
FunctionType *fnType, Type baseType, ValueDecl *decl, DeclContext *dc,
1700+
unsigned numApplies, bool isMainDispatchQueue, OpenedTypeMap &replacements,
17011701
ConstraintLocatorBuilder locator) {
17021702

17031703
auto *adjustedTy = swift::adjustFunctionTypeForConcurrency(
@@ -1713,10 +1713,23 @@ FunctionType *ConstraintSystem::adjustFunctionTypeForConcurrency(
17131713
if (auto *FD = dyn_cast<AbstractFunctionDecl>(decl)) {
17141714
auto *DC = FD->getDeclContext();
17151715
// All global functions should be @Sendable
1716-
if (DC->isModuleScopeContext() &&
1717-
!adjustedTy->getExtInfo().isSendable()) {
1718-
adjustedTy =
1719-
adjustedTy->withExtInfo(adjustedTy->getExtInfo().withSendable());
1716+
if (DC->isModuleScopeContext()) {
1717+
if (!adjustedTy->getExtInfo().isSendable()) {
1718+
adjustedTy =
1719+
adjustedTy->withExtInfo(adjustedTy->getExtInfo().withSendable());
1720+
}
1721+
} else if (isPartialApplication(getConstraintLocator(locator))) {
1722+
if (baseType &&
1723+
(baseType->is<AnyMetatypeType>() || baseType->isSendableType())) {
1724+
auto referenceTy = adjustedTy->getResult()->castTo<FunctionType>();
1725+
referenceTy =
1726+
referenceTy->withExtInfo(referenceTy->getExtInfo().withSendable())
1727+
->getAs<FunctionType>();
1728+
1729+
adjustedTy =
1730+
FunctionType::get(adjustedTy->getParams(), referenceTy,
1731+
adjustedTy->getExtInfo().withSendable());
1732+
}
17201733
}
17211734
}
17221735
}
@@ -1794,9 +1807,9 @@ ConstraintSystem::getTypeOfReference(ValueDecl *value,
17941807
auto origOpenedType = openedType;
17951808
if (!isRequirementOrWitness(locator)) {
17961809
unsigned numApplies = getNumApplications(value, false, functionRefKind);
1797-
openedType = adjustFunctionTypeForConcurrency(origOpenedType, func, useDC,
1798-
numApplies, false,
1799-
replacements, locator);
1810+
openedType = adjustFunctionTypeForConcurrency(
1811+
origOpenedType, /*baseType=*/Type(), func, useDC, numApplies, false,
1812+
replacements, locator);
18001813
}
18011814

18021815
// The reference implicitly binds 'self'.
@@ -1824,8 +1837,8 @@ ConstraintSystem::getTypeOfReference(ValueDecl *value,
18241837
unsigned numApplies = getNumApplications(
18251838
funcDecl, false, functionRefKind);
18261839
openedType = adjustFunctionTypeForConcurrency(
1827-
origOpenedType->castTo<FunctionType>(), funcDecl, useDC, numApplies,
1828-
false, replacements, locator);
1840+
origOpenedType->castTo<FunctionType>(), /*baseType=*/Type(), funcDecl,
1841+
useDC, numApplies, false, replacements, locator);
18291842
}
18301843

18311844
if (isForCodeCompletion() && openedType->hasError()) {
@@ -2793,20 +2806,6 @@ ConstraintSystem::getTypeOfMemberReference(
27932806
// FIXME: Verify ExtInfo state is correct, not working by accident.
27942807
FunctionType::ExtInfo info;
27952808

2796-
if (Context.LangOpts.hasFeature(Feature::InferSendableFromCaptures)) {
2797-
if (isPartialApplication(locator) &&
2798-
(resolvedBaseTy->is<AnyMetatypeType>() ||
2799-
baseOpenedTy->isSendableType())) {
2800-
// Add @Sendable to functions without conditional conformances
2801-
functionType =
2802-
functionType
2803-
->withExtInfo(functionType->getExtInfo().withSendable())
2804-
->getAs<FunctionType>();
2805-
}
2806-
// Unapplied values should always be Sendable
2807-
info = info.withSendable();
2808-
}
2809-
28102809
// We'll do other adjustment later, but we need to handle parameter
28112810
// isolation to avoid assertions.
28122811
if (fullFunctionType->getIsolation().isParameter())
@@ -2824,11 +2823,12 @@ ConstraintSystem::getTypeOfMemberReference(
28242823
unsigned numApplies = getNumApplications(
28252824
value, hasAppliedSelf, functionRefKind);
28262825
openedType = adjustFunctionTypeForConcurrency(
2827-
origOpenedType->castTo<FunctionType>(), value, useDC, numApplies,
2828-
isMainDispatchQueueMember(locator), replacements, locator);
2826+
origOpenedType->castTo<FunctionType>(), resolvedBaseTy, value, useDC,
2827+
numApplies, isMainDispatchQueueMember(locator), replacements, locator);
28292828
} else if (auto subscript = dyn_cast<SubscriptDecl>(value)) {
28302829
openedType = adjustFunctionTypeForConcurrency(
2831-
origOpenedType->castTo<FunctionType>(), subscript, useDC,
2830+
origOpenedType->castTo<FunctionType>(), resolvedBaseTy, subscript,
2831+
useDC,
28322832
/*numApplies=*/2, /*isMainDispatchQueue=*/false, replacements, locator);
28332833
} else if (auto var = dyn_cast<VarDecl>(value)) {
28342834
// Adjust the function's result type, since that's the Var's actual type.
@@ -2957,7 +2957,8 @@ Type ConstraintSystem::getEffectiveOverloadType(ConstraintLocator *locator,
29572957
// FIXME: Verify ExtInfo state is correct, not working by accident.
29582958
FunctionType::ExtInfo info;
29592959
type = adjustFunctionTypeForConcurrency(
2960-
FunctionType::get(indices, elementTy, info), subscript, useDC,
2960+
FunctionType::get(indices, elementTy, info), overload.getBaseType(),
2961+
subscript, useDC,
29612962
/*numApplies=*/1, /*isMainDispatchQueue=*/false, emptyReplacements,
29622963
locator);
29632964
} else if (auto var = dyn_cast<VarDecl>(decl)) {
@@ -3005,7 +3006,8 @@ Type ConstraintSystem::getEffectiveOverloadType(ConstraintLocator *locator,
30053006
decl, hasAppliedSelf, overload.getFunctionRefKind());
30063007

30073008
type = adjustFunctionTypeForConcurrency(
3008-
type->castTo<FunctionType>(), decl, useDC, numApplies,
3009+
type->castTo<FunctionType>(), overload.getBaseType(), decl,
3010+
useDC, numApplies,
30093011
/*isMainDispatchQueue=*/false, emptyReplacements, locator)
30103012
->getResult();
30113013
}

test/Concurrency/sendable_functions.swift

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -46,19 +46,3 @@ extension S: Sendable where T: Sendable {
4646

4747
@available(SwiftStdlib 5.1, *)
4848
@MainActor @Sendable func globalActorFuncAsync() async { }
49-
50-
func test_initializer_ref() {
51-
func test<T>(_: @Sendable (T, T) -> Array<T>) {
52-
}
53-
54-
// Type of `initRef` should be @Sendable but due to implicitly injected autoclosure it isn't
55-
let initRef = Array.init as (Int, Int) -> Array<Int>
56-
57-
// FIXME: incorrect non-Sendable diagnostic is produced due to `autoclosure` wrapping `Array.init`
58-
test(initRef)
59-
// expected-warning@-1 {{converting non-sendable function value to '@Sendable (Int, Int) -> Array<Int>' may introduce data races}}
60-
61-
// FIXME: Same here
62-
test(Array.init as (Int, Int) -> Array<Int>)
63-
// expected-warning@-1 {{converting non-sendable function value to '@Sendable (Int, Int) -> Array<Int>' may introduce data races}}
64-
}

test/Concurrency/sendable_methods.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,3 +244,14 @@ do {
244244

245245
let _: () -> Void = forward(Test.fn) // Ok
246246
}
247+
248+
249+
func test_initializer_ref() {
250+
func test<T>(_: @Sendable (T, T) -> Array<T>) {
251+
}
252+
253+
let initRef: @Sendable (Int, Int) -> Array<Int> = Array<Int>.init // Ok
254+
255+
test(initRef) // Ok
256+
test(Array<Int>.init) // Ok
257+
}

0 commit comments

Comments
 (0)