Skip to content

Commit 7c00af5

Browse files
committed
Delay @preconcurrency-related type adjustments until the last moment.
This allows us to retain the full opened type before adjustment when needed, but should otherwise not change anything.
1 parent bbf7650 commit 7c00af5

File tree

4 files changed

+57
-39
lines changed

4 files changed

+57
-39
lines changed

include/swift/Sema/ConstraintSystem.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4423,10 +4423,11 @@ class ConstraintSystem {
44234423
const OpenedTypeMap &replacements);
44244424

44254425
/// Wrapper over swift::adjustFunctionTypeForConcurrency that passes along
4426-
/// the appropriate closure-type extraction function.
4426+
/// the appropriate closure-type and opening extraction functions.
44274427
AnyFunctionType *adjustFunctionTypeForConcurrency(
44284428
AnyFunctionType *fnType, ValueDecl *decl, DeclContext *dc,
4429-
unsigned numApplies, bool isMainDispatchQueue);
4429+
unsigned numApplies, bool isMainDispatchQueue,
4430+
OpenedTypeMap &replacements);
44304431

44314432
/// Retrieve the type of a reference to the given value declaration.
44324433
///

lib/Sema/ConstraintSystem.cpp

Lines changed: 48 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1428,9 +1428,16 @@ static bool isRequirementOrWitness(const ConstraintLocatorBuilder &locator) {
14281428

14291429
AnyFunctionType *ConstraintSystem::adjustFunctionTypeForConcurrency(
14301430
AnyFunctionType *fnType, ValueDecl *decl, DeclContext *dc,
1431-
unsigned numApplies, bool isMainDispatchQueue) {
1431+
unsigned numApplies, bool isMainDispatchQueue,
1432+
OpenedTypeMap &replacements) {
14321433
return swift::adjustFunctionTypeForConcurrency(
1433-
fnType, decl, dc, numApplies, isMainDispatchQueue, GetClosureType{*this});
1434+
fnType, decl, dc, numApplies, isMainDispatchQueue, GetClosureType{*this},
1435+
[&](Type type) {
1436+
if (replacements.empty())
1437+
return type;
1438+
1439+
return openType(type, replacements);
1440+
});
14341441
}
14351442

14361443
/// For every parameter in \p type that has an error type, replace that
@@ -1479,11 +1486,6 @@ ConstraintSystem::getTypeOfReference(ValueDecl *value,
14791486

14801487
AnyFunctionType *funcType = func->getInterfaceType()
14811488
->castTo<AnyFunctionType>();
1482-
if (!isRequirementOrWitness(locator)) {
1483-
unsigned numApplies = getNumApplications(value, false, functionRefKind);
1484-
funcType = adjustFunctionTypeForConcurrency(
1485-
funcType, func, useDC, numApplies, false);
1486-
}
14871489
auto openedType = openFunctionType(
14881490
funcType, locator, replacements, func->getDeclContext());
14891491

@@ -1500,6 +1502,13 @@ ConstraintSystem::getTypeOfReference(ValueDecl *value,
15001502
->castTo<FunctionType>();
15011503
}
15021504

1505+
auto origOpenedType = openedType;
1506+
if (!isRequirementOrWitness(locator)) {
1507+
unsigned numApplies = getNumApplications(value, false, functionRefKind);
1508+
openedType = cast<FunctionType>(adjustFunctionTypeForConcurrency(
1509+
origOpenedType, func, useDC, numApplies, false, replacements));
1510+
}
1511+
15031512
// The reference implicitly binds 'self'.
15041513
return {openedType, openedType->getResult()};
15051514
}
@@ -1512,20 +1521,20 @@ ConstraintSystem::getTypeOfReference(ValueDecl *value,
15121521
auto numLabelsToRemove = getNumRemovedArgumentLabels(
15131522
funcDecl, /*isCurriedInstanceReference=*/false, functionRefKind);
15141523

1524+
auto openedType = openFunctionType(funcType, locator, replacements,
1525+
funcDecl->getDeclContext())
1526+
->removeArgumentLabels(numLabelsToRemove);
1527+
openedType = unwrapPropertyWrapperParameterTypes(*this, funcDecl, functionRefKind, openedType->castTo<FunctionType>(), locator);
1528+
1529+
auto origOpenedType = openedType;
15151530
if (!isRequirementOrWitness(locator)) {
15161531
unsigned numApplies = getNumApplications(
15171532
funcDecl, false, functionRefKind);
1518-
funcType = adjustFunctionTypeForConcurrency(
1519-
funcType, funcDecl, useDC, numApplies, false);
1533+
openedType = cast<FunctionType>(adjustFunctionTypeForConcurrency(
1534+
origOpenedType->castTo<FunctionType>(), funcDecl, useDC,
1535+
numApplies, false, replacements));
15201536
}
15211537

1522-
auto openedType = openFunctionType(funcType, locator, replacements,
1523-
funcDecl->getDeclContext())
1524-
->removeArgumentLabels(numLabelsToRemove);
1525-
openedType = unwrapPropertyWrapperParameterTypes(*this, funcDecl, functionRefKind,
1526-
openedType->getAs<FunctionType>(),
1527-
locator);
1528-
15291538
if (isForCodeCompletion() && openedType->hasError()) {
15301539
// In code completion, replace error types by placeholder types so we can
15311540
// match the types we know instead of bailing out completely.
@@ -2096,22 +2105,13 @@ ConstraintSystem::getTypeOfMemberReference(
20962105

20972106
AnyFunctionType *funcType;
20982107

2099-
if (isa<AbstractFunctionDecl>(value) ||
2100-
isa<EnumElementDecl>(value)) {
2108+
if (isa<AbstractFunctionDecl>(value) || isa<EnumElementDecl>(value)) {
21012109
if (auto ErrorTy = value->getInterfaceType()->getAs<ErrorType>()) {
21022110
return {ErrorType::get(ErrorTy->getASTContext()),
21032111
ErrorType::get(ErrorTy->getASTContext())};
21042112
}
21052113
// This is the easy case.
21062114
funcType = value->getInterfaceType()->castTo<AnyFunctionType>();
2107-
2108-
if (!isRequirementOrWitness(locator)) {
2109-
unsigned numApplies = getNumApplications(
2110-
value, hasAppliedSelf, functionRefKind);
2111-
funcType = adjustFunctionTypeForConcurrency(
2112-
funcType, value, useDC, numApplies,
2113-
isMainDispatchQueueMember(locator));
2114-
}
21152115
} else {
21162116
// For a property, build a type (Self) -> PropType.
21172117
// For a subscript, build a type (Self) -> (Indices...) -> ElementType.
@@ -2128,11 +2128,7 @@ ConstraintSystem::getTypeOfMemberReference(
21282128
->castTo<AnyFunctionType>()->getParams();
21292129
// FIXME: Verify ExtInfo state is correct, not working by accident.
21302130
FunctionType::ExtInfo info;
2131-
auto *refFnType = FunctionType::get(indices, elementTy, info);
2132-
2133-
refType = adjustFunctionTypeForConcurrency(
2134-
refFnType, subscript, useDC, /*numApplies=*/1,
2135-
/*isMainDispatchQueue=*/false);
2131+
refType = FunctionType::get(indices, elementTy, info);
21362132
} else {
21372133
refType = getUnopenedTypeOfReference(cast<VarDecl>(value), baseTy, useDC,
21382134
locator,
@@ -2244,6 +2240,22 @@ ConstraintSystem::getTypeOfMemberReference(
22442240
FunctionType::get(fullFunctionType->getParams(), functionType, info);
22452241
}
22462242

2243+
// Adjust the type for concurrency.
2244+
Type origOpenedType = openedType;
2245+
2246+
if ((isa<AbstractFunctionDecl>(value) || isa<EnumElementDecl>(value)) &&
2247+
!isRequirementOrWitness(locator)) {
2248+
unsigned numApplies = getNumApplications(
2249+
value, hasAppliedSelf, functionRefKind);
2250+
openedType = adjustFunctionTypeForConcurrency(
2251+
origOpenedType->castTo<AnyFunctionType>(), value, useDC, numApplies,
2252+
isMainDispatchQueueMember(locator), replacements);
2253+
} else if (auto subscript = dyn_cast<SubscriptDecl>(value)) {
2254+
openedType = adjustFunctionTypeForConcurrency(
2255+
origOpenedType->castTo<AnyFunctionType>(), subscript, useDC,
2256+
/*numApplies=*/2, /*isMainDispatchQueue=*/false, replacements);
2257+
}
2258+
22472259
// Compute the type of the reference.
22482260
Type type = openedType;
22492261

@@ -2456,6 +2468,7 @@ Type ConstraintSystem::getEffectiveOverloadType(ConstraintLocator *locator,
24562468
uncurryLevel);
24572469
};
24582470

2471+
OpenedTypeMap emptyReplacements;
24592472
if (auto subscript = dyn_cast<SubscriptDecl>(decl)) {
24602473
auto elementTy = subscript->getElementInterfaceType();
24612474

@@ -2478,7 +2491,8 @@ Type ConstraintSystem::getEffectiveOverloadType(ConstraintLocator *locator,
24782491
FunctionType::ExtInfo info;
24792492
type = adjustFunctionTypeForConcurrency(
24802493
FunctionType::get(indices, elementTy, info),
2481-
subscript, useDC, /*numApplies=*/1, /*isMainDispatchQueue=*/false);
2494+
subscript, useDC, /*numApplies=*/1, /*isMainDispatchQueue=*/false,
2495+
emptyReplacements);
24822496
} else if (auto var = dyn_cast<VarDecl>(decl)) {
24832497
type = var->getValueInterfaceType();
24842498
if (doesStorageProduceLValue(var, overload.getBaseType(), useDC)) {
@@ -2524,7 +2538,8 @@ Type ConstraintSystem::getEffectiveOverloadType(ConstraintLocator *locator,
25242538

25252539
type = adjustFunctionTypeForConcurrency(
25262540
type->castTo<FunctionType>(),
2527-
decl, useDC, numApplies, /*isMainDispatchQueue=*/false)
2541+
decl, useDC, numApplies, /*isMainDispatchQueue=*/false,
2542+
emptyReplacements)
25282543
->getResult();
25292544
}
25302545
}

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4547,7 +4547,7 @@ static AnyFunctionType *applyUnsafeConcurrencyToFunctionType(
45474547
return fnType;
45484548

45494549
AnyFunctionType *outerFnType = nullptr;
4550-
if (func && func->hasImplicitSelfDecl()) {
4550+
if ((subscript && numApplies > 1) || (func && func->hasImplicitSelfDecl())) {
45514551
outerFnType = fnType;
45524552
fnType = outerFnType->getResult()->castTo<AnyFunctionType>();
45534553

@@ -4637,7 +4637,8 @@ static AnyFunctionType *applyUnsafeConcurrencyToFunctionType(
46374637
AnyFunctionType *swift::adjustFunctionTypeForConcurrency(
46384638
AnyFunctionType *fnType, ValueDecl *decl, DeclContext *dc,
46394639
unsigned numApplies, bool isMainDispatchQueue,
4640-
llvm::function_ref<Type(const AbstractClosureExpr *)> getType) {
4640+
llvm::function_ref<Type(const AbstractClosureExpr *)> getType,
4641+
llvm::function_ref<Type(Type)> openType) {
46414642
// Apply unsafe concurrency features to the given function type.
46424643
bool strictChecking = contextRequiresStrictConcurrencyChecking(dc, getType);
46434644
fnType = applyUnsafeConcurrencyToFunctionType(
@@ -4660,7 +4661,7 @@ AnyFunctionType *swift::adjustFunctionTypeForConcurrency(
46604661
LLVM_FALLTHROUGH;
46614662

46624663
case ActorIsolation::GlobalActor:
4663-
globalActorType = isolation.getGlobalActor();
4664+
globalActorType = openType(isolation.getGlobalActor());
46644665
break;
46654666
}
46664667
}

lib/Sema/TypeCheckConcurrency.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -427,7 +427,8 @@ Type adjustVarTypeForConcurrency(
427427
AnyFunctionType *adjustFunctionTypeForConcurrency(
428428
AnyFunctionType *fnType, ValueDecl *decl, DeclContext *dc,
429429
unsigned numApplies, bool isMainDispatchQueue,
430-
llvm::function_ref<Type(const AbstractClosureExpr *)> getType);
430+
llvm::function_ref<Type(const AbstractClosureExpr *)> getType,
431+
llvm::function_ref<Type(Type)> openType);
431432

432433
/// Determine whether the given name is that of a DispatchQueue operation that
433434
/// takes a closure to be executed on the queue.

0 commit comments

Comments
 (0)