[Concurrency] References to global-actor functions have global-actor-qualified type.

When referencing a function that is on a global actor, e.g.,

    @MainActor func doSomething() -> Int

the result of that reference is a global-actor-qualified function type, e.g.,

    @MainActor () -> Int

Part of rdar://76030136.
This commit is contained in:
Doug Gregor
2021-04-13 15:49:18 -07:00
parent f53f80ff04
commit cdb7de19bf
6 changed files with 105 additions and 18 deletions

View File

@@ -1233,6 +1233,16 @@ unwrapPropertyWrapperParameterTypes(ConstraintSystem &cs, AbstractFunctionDecl *
functionType->getExtInfo());
}
/// Determine whether the given locator is for a witness or requirement.
static bool isRequirementOrWitness(const ConstraintLocatorBuilder &locator) {
if (auto last = locator.last()) {
return last->getKind() == ConstraintLocator::ProtocolRequirement ||
last->getKind() == ConstraintLocator::Witness;
}
return false;
}
std::pair<Type, Type>
ConstraintSystem::getTypeOfReference(ValueDecl *value,
FunctionRefKind functionRefKind,
@@ -1245,9 +1255,12 @@ ConstraintSystem::getTypeOfReference(ValueDecl *value,
OpenedTypeMap replacements;
auto openedType =
openFunctionType(func->getInterfaceType()->castTo<AnyFunctionType>(),
locator, replacements, func->getDeclContext());
AnyFunctionType *funcType = func->getInterfaceType()
->castTo<AnyFunctionType>();
if (!isRequirementOrWitness(locator))
funcType = applyGlobalActorType(funcType, func, useDC);
auto openedType = openFunctionType(
funcType, locator, replacements, func->getDeclContext());
// If we opened up any type variables, record the replacements.
recordOpenedTypes(locator, replacements);
@@ -1274,10 +1287,12 @@ ConstraintSystem::getTypeOfReference(ValueDecl *value,
auto numLabelsToRemove = getNumRemovedArgumentLabels(
funcDecl, /*isCurriedInstanceReference=*/false, functionRefKind);
if (!isRequirementOrWitness(locator))
funcType = applyGlobalActorType(funcType, funcDecl, useDC);
auto openedType = openFunctionType(funcType, locator, replacements,
funcDecl->getDeclContext())
->removeArgumentLabels(numLabelsToRemove);
openedType = unwrapPropertyWrapperParameterTypes(*this, funcDecl, functionRefKind,
openedType->getAs<FunctionType>(),
locator);
@@ -1514,16 +1529,6 @@ static void addSelfConstraint(ConstraintSystem &cs, Type objectTy, Type selfTy,
cs.getConstraintLocator(locator));
}
/// Determine whether the given locator is for a witness or requirement.
static bool isRequirementOrWitness(const ConstraintLocatorBuilder &locator) {
if (auto last = locator.last()) {
return last->getKind() == ConstraintLocator::ProtocolRequirement ||
last->getKind() == ConstraintLocator::Witness;
}
return false;
}
Type constraints::getDynamicSelfReplacementType(
Type baseObjTy, const ValueDecl *member, ConstraintLocator *memberLocator) {
// Constructions must always have their dynamic 'Self' result type replaced
@@ -1623,6 +1628,9 @@ ConstraintSystem::getTypeOfMemberReference(
isa<EnumElementDecl>(value)) {
// This is the easy case.
funcType = value->getInterfaceType()->castTo<AnyFunctionType>();
if (!isRequirementOrWitness(locator))
funcType = applyGlobalActorType(funcType, value, useDC);
} else {
// For a property, build a type (Self) -> PropType.
// For a subscript, build a type (Self) -> (Indices...) -> ElementType.