Skip to content

Commit 1efc9a6

Browse files
committed
Sema: Split off getTypeOfReferenceImpl() from getTypeOfReference()
1 parent d8ce7c3 commit 1efc9a6

File tree

2 files changed

+129
-71
lines changed

2 files changed

+129
-71
lines changed

include/swift/Sema/ConstraintSystem.h

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4437,8 +4437,15 @@ class ConstraintSystem {
44374437
FunctionType *adjustFunctionTypeForConcurrency(
44384438
FunctionType *fnType, Type baseType, ValueDecl *decl, DeclContext *dc,
44394439
unsigned numApplies, bool isMainDispatchQueue,
4440-
ArrayRef<OpenedType> replacements, ConstraintLocatorBuilder locator,
4441-
PreparedOverloadBuilder *preparedOverload);
4440+
bool openGlobalActorType, ConstraintLocatorBuilder locator);
4441+
4442+
/// \returns The opened type and the thrown error type.
4443+
std::pair<Type, Type> getTypeOfReferenceImpl(
4444+
ValueDecl *decl,
4445+
FunctionRefInfo functionRefInfo,
4446+
ConstraintLocatorBuilder locator,
4447+
DeclContext *useDC,
4448+
PreparedOverloadBuilder *preparedOverload);
44424449

44434450
/// Retrieve the type of a reference to the given value declaration.
44444451
///

lib/Sema/TypeOfReference.cpp

Lines changed: 120 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -956,16 +956,22 @@ static bool isRequirementOrWitness(const ConstraintLocatorBuilder &locator) {
956956

957957
FunctionType *ConstraintSystem::adjustFunctionTypeForConcurrency(
958958
FunctionType *fnType, Type baseType, ValueDecl *decl, DeclContext *dc,
959-
unsigned numApplies, bool isMainDispatchQueue, ArrayRef<OpenedType> replacements,
960-
ConstraintLocatorBuilder locator, PreparedOverloadBuilder *preparedOverload) {
959+
unsigned numApplies, bool isMainDispatchQueue, bool openGlobalActorType,
960+
ConstraintLocatorBuilder locator) {
961961

962962
auto *adjustedTy = swift::adjustFunctionTypeForConcurrency(
963963
fnType, decl, dc, numApplies, isMainDispatchQueue, GetClosureType{*this},
964964
ClosureIsolatedByPreconcurrency{*this}, [&](Type type) {
965-
if (replacements.empty())
965+
if (!type->hasTypeParameter())
966966
return type;
967967

968-
return openType(type, replacements, locator, preparedOverload);
968+
// FIXME: This should be handled elsewhere.
969+
if (!openGlobalActorType)
970+
return type;
971+
972+
auto replacements = getOpenedTypes(getConstraintLocator(locator));
973+
ASSERT(!replacements.empty());
974+
return openType(type, replacements, locator, /*preparedOverload=*/nullptr);
969975
});
970976

971977
// Infer @Sendable for global actor isolated function types under the
@@ -1105,13 +1111,14 @@ recordFixIfNeededForPlaceholderInDecl(ConstraintSystem &cs, ValueDecl *D,
11051111
cs.recordFix(IgnoreInvalidPlaceholderInDeclRef::create(cs, loc));
11061112
}
11071113

1108-
DeclReferenceType
1109-
ConstraintSystem::getTypeOfReference(ValueDecl *value,
1110-
FunctionRefInfo functionRefInfo,
1111-
ConstraintLocatorBuilder locator,
1112-
DeclContext *useDC,
1113-
PreparedOverloadBuilder *preparedOverload) {
1114+
std::pair<Type, Type>
1115+
ConstraintSystem::getTypeOfReferenceImpl(ValueDecl *value,
1116+
FunctionRefInfo functionRefInfo,
1117+
ConstraintLocatorBuilder locator,
1118+
DeclContext *useDC,
1119+
PreparedOverloadBuilder *preparedOverload) {
11141120
ASSERT(!!preparedOverload == PreparingOverload);
1121+
11151122
recordFixIfNeededForPlaceholderInDecl(*this, value, locator);
11161123

11171124
if (value->getDeclContext()->isTypeContext() && isa<FuncDecl>(value)) {
@@ -1130,39 +1137,7 @@ ConstraintSystem::getTypeOfReference(ValueDecl *value,
11301137
// If we opened up any type variables, record the replacements.
11311138
recordOpenedTypes(locator, replacements, preparedOverload);
11321139

1133-
auto origOpenedType = openedType;
1134-
if (!isRequirementOrWitness(locator)) {
1135-
unsigned numApplies = getNumApplications(/*hasAppliedSelf*/ false,
1136-
functionRefInfo);
1137-
openedType = adjustFunctionTypeForConcurrency(
1138-
origOpenedType, /*baseType=*/Type(), func, useDC, numApplies, false,
1139-
replacements, locator, preparedOverload);
1140-
}
1141-
1142-
// If this is a method whose result type is dynamic Self, replace
1143-
// DynamicSelf with the actual object type. Repeat the adjustment
1144-
// for the original and adjusted types.
1145-
auto type = openedType;
1146-
if (openedType->hasDynamicSelfType()) {
1147-
auto params = openedType->getParams();
1148-
assert(params.size() == 1);
1149-
Type selfTy = params.front().getPlainType()->getMetatypeInstanceType();
1150-
type = openedType->replaceDynamicSelfType(selfTy)
1151-
->castTo<FunctionType>();
1152-
}
1153-
1154-
auto origType = origOpenedType;
1155-
if (origOpenedType->hasDynamicSelfType()) {
1156-
auto params = origOpenedType->getParams();
1157-
assert(params.size() == 1);
1158-
Type selfTy = params.front().getPlainType()->getMetatypeInstanceType();
1159-
origType = origOpenedType->replaceDynamicSelfType(selfTy)
1160-
->castTo<FunctionType>();
1161-
}
1162-
1163-
// The reference implicitly binds 'self'.
1164-
return {origOpenedType, openedType,
1165-
origType->getResult(), type->getResult(), Type()};
1140+
return {openedType, Type()};
11661141
}
11671142

11681143
// Unqualified reference to a local or global function.
@@ -1191,16 +1166,7 @@ ConstraintSystem::getTypeOfReference(ValueDecl *value,
11911166
// If we opened up any type variables, record the replacements.
11921167
recordOpenedTypes(locator, replacements, preparedOverload);
11931168

1194-
auto origOpenedType = openedType;
1195-
if (!isRequirementOrWitness(locator)) {
1196-
unsigned numApplies = getNumApplications(/*hasAppliedSelf*/ false,
1197-
functionRefInfo);
1198-
openedType = adjustFunctionTypeForConcurrency(
1199-
origOpenedType->castTo<FunctionType>(), /*baseType=*/Type(), funcDecl,
1200-
useDC, numApplies, false, replacements, locator, preparedOverload);
1201-
}
1202-
1203-
return { origOpenedType, openedType, origOpenedType, openedType, Type() };
1169+
return {openedType, Type()};
12041170
}
12051171

12061172
// Unqualified reference to a type.
@@ -1222,11 +1188,11 @@ ConstraintSystem::getTypeOfReference(ValueDecl *value,
12221188

12231189
// Module types are not wrapped in metatypes.
12241190
if (type->is<ModuleType>())
1225-
return { type, type, type, type, Type() };
1191+
return { type, Type() };
12261192

12271193
// If it's a value reference, refer to the metatype.
12281194
type = MetatypeType::get(type);
1229-
return { type, type, type, type, Type() };
1195+
return {type, Type()};
12301196
}
12311197

12321198
// Unqualified reference to a macro.
@@ -1245,7 +1211,7 @@ ConstraintSystem::getTypeOfReference(ValueDecl *value,
12451211

12461212
// FIXME: Should we use replaceParamErrorTypeByPlaceholder() here?
12471213

1248-
return { openedType, openedType, openedType, openedType, Type() };
1214+
return {openedType, Type()};
12491215
}
12501216

12511217
// Only remaining case: unqualified reference to a property.
@@ -1267,17 +1233,103 @@ ConstraintSystem::getTypeOfReference(ValueDecl *value,
12671233
accessor->getEffectiveThrownErrorType().value_or(Type());
12681234
}
12691235

1236+
return {valueType, thrownErrorType};
1237+
}
1238+
1239+
DeclReferenceType
1240+
ConstraintSystem::getTypeOfReference(ValueDecl *value,
1241+
FunctionRefInfo functionRefInfo,
1242+
ConstraintLocatorBuilder locator,
1243+
DeclContext *useDC,
1244+
PreparedOverloadBuilder *preparedOverload) {
1245+
ASSERT(!!preparedOverload == PreparingOverload);
1246+
1247+
Type openedType, thrownErrorType;
1248+
std::tie(openedType, thrownErrorType) = getTypeOfReferenceImpl(
1249+
value, functionRefInfo, locator, useDC, preparedOverload);
1250+
1251+
if (value->getDeclContext()->isTypeContext() && isa<FuncDecl>(value)) {
1252+
auto *openedFnType = openedType->castTo<FunctionType>();
1253+
1254+
// Unqualified lookup can find operator names within nominal types.
1255+
auto func = cast<FuncDecl>(value);
1256+
assert(func->isOperator() && "Lookup should only find operators");
1257+
1258+
1259+
auto origOpenedType = openedFnType;
1260+
if (!isRequirementOrWitness(locator)) {
1261+
unsigned numApplies = getNumApplications(/*hasAppliedSelf*/ false,
1262+
functionRefInfo);
1263+
openedFnType = adjustFunctionTypeForConcurrency(
1264+
origOpenedType, /*baseType=*/Type(), func, useDC, numApplies,
1265+
/*isMainDispatchQueue=*/false, /*openGlobalActorType=*/true, locator);
1266+
}
1267+
1268+
// If this is a method whose result type is dynamic Self, replace
1269+
// DynamicSelf with the actual object type. Repeat the adjustment
1270+
// for the original and adjusted types.
1271+
auto type = openedFnType;
1272+
if (openedFnType->hasDynamicSelfType()) {
1273+
auto params = openedFnType->getParams();
1274+
assert(params.size() == 1);
1275+
Type selfTy = params.front().getPlainType()->getMetatypeInstanceType();
1276+
type = openedFnType->replaceDynamicSelfType(selfTy)
1277+
->castTo<FunctionType>();
1278+
}
1279+
1280+
auto origType = origOpenedType;
1281+
if (origOpenedType->hasDynamicSelfType()) {
1282+
auto params = origOpenedType->getParams();
1283+
assert(params.size() == 1);
1284+
Type selfTy = params.front().getPlainType()->getMetatypeInstanceType();
1285+
origType = origOpenedType->replaceDynamicSelfType(selfTy)
1286+
->castTo<FunctionType>();
1287+
}
1288+
1289+
// The reference implicitly binds 'self'.
1290+
return {origOpenedType, openedType,
1291+
origType->getResult(), type->getResult(), Type()};
1292+
}
1293+
1294+
// Unqualified reference to a local or global function.
1295+
if (auto funcDecl = dyn_cast<AbstractFunctionDecl>(value)) {
1296+
auto origOpenedType = openedType;
1297+
if (!isRequirementOrWitness(locator)) {
1298+
unsigned numApplies = getNumApplications(/*hasAppliedSelf*/ false,
1299+
functionRefInfo);
1300+
openedType = adjustFunctionTypeForConcurrency(
1301+
origOpenedType->castTo<FunctionType>(), /*baseType=*/Type(), funcDecl,
1302+
useDC, numApplies, /*isMainDispatchQueue=*/false,
1303+
/*openGlobalActorType=*/true, locator);
1304+
}
1305+
1306+
return { origOpenedType, openedType, origOpenedType, openedType, Type() };
1307+
}
1308+
1309+
// Unqualified reference to a type.
1310+
if (isa<TypeDecl>(value)) {
1311+
return { openedType, openedType, openedType, openedType, Type() };
1312+
}
1313+
1314+
// Unqualified reference to a macro.
1315+
if (isa<MacroDecl>(value)) {
1316+
return { openedType, openedType, openedType, openedType, Type() };
1317+
}
1318+
1319+
// Only remaining case: unqualified reference to a property.
1320+
auto *varDecl = cast<VarDecl>(value);
1321+
12701322
// Adjust the type for concurrency.
1271-
auto origValueType = valueType;
1323+
auto origOpenedType = openedType;
12721324

12731325
if (!isRequirementOrWitness(locator)) {
1274-
valueType = adjustVarTypeForConcurrency(
1275-
valueType, varDecl, useDC,
1326+
openedType = adjustVarTypeForConcurrency(
1327+
openedType, varDecl, useDC,
12761328
GetClosureType{*this},
12771329
ClosureIsolatedByPreconcurrency{*this});
12781330
}
12791331

1280-
return { origValueType, valueType, origValueType, valueType, thrownErrorType };
1332+
return { origOpenedType, openedType, origOpenedType, openedType, thrownErrorType };
12811333
}
12821334

12831335
/// Bind type variables for archetypes that are determined from
@@ -1990,13 +2042,13 @@ DeclReferenceType ConstraintSystem::getTypeOfMemberReference(
19902042
unsigned numApplies = getNumApplications(hasAppliedSelf, functionRefInfo);
19912043
openedType = adjustFunctionTypeForConcurrency(
19922044
origOpenedType->castTo<FunctionType>(), baseRValueTy, value, useDC,
1993-
numApplies, isMainDispatchQueueMember(locator), replacements, locator,
1994-
preparedOverload);
2045+
numApplies, isMainDispatchQueueMember(locator),
2046+
/*openGlobalActorType=*/true, locator);
19952047
} else if (auto subscript = dyn_cast<SubscriptDecl>(value)) {
19962048
openedType = adjustFunctionTypeForConcurrency(
19972049
origOpenedType->castTo<FunctionType>(), baseRValueTy, subscript, useDC,
1998-
/*numApplies=*/2, /*isMainDispatchQueue=*/false, replacements, locator,
1999-
preparedOverload);
2050+
/*numApplies=*/2, /*isMainDispatchQueue=*/false,
2051+
/*openGlobalActorType=*/true, locator);
20002052
} else if (auto var = dyn_cast<VarDecl>(value)) {
20012053
// Adjust the function's result type, since that's the Var's actual type.
20022054
auto origFnType = origOpenedType->castTo<AnyFunctionType>();
@@ -2131,9 +2183,8 @@ Type ConstraintSystem::getEffectiveOverloadType(ConstraintLocator *locator,
21312183
FunctionType::ExtInfo info;
21322184
type = adjustFunctionTypeForConcurrency(
21332185
FunctionType::get(indices, elementTy, info), overload.getBaseType(),
2134-
subscript, useDC,
2135-
/*numApplies=*/1, /*isMainDispatchQueue=*/false, emptyReplacements,
2136-
locator, /*preparedOverload=*/nullptr);
2186+
subscript, useDC, /*numApplies=*/1, /*isMainDispatchQueue=*/false,
2187+
/*openGlobalActorType=*/false, locator);
21372188
} else if (auto var = dyn_cast<VarDecl>(decl)) {
21382189
type = var->getValueInterfaceType();
21392190
if (doesStorageProduceLValue(
@@ -2178,8 +2229,8 @@ Type ConstraintSystem::getEffectiveOverloadType(ConstraintLocator *locator,
21782229
type = adjustFunctionTypeForConcurrency(
21792230
type->castTo<FunctionType>(), overload.getBaseType(), decl,
21802231
useDC, numApplies, /*isMainDispatchQueue=*/false,
2181-
emptyReplacements, locator, /*preparedOverload=*/nullptr)
2182-
->getResult();
2232+
/*openGlobalActorType=*/false, locator)
2233+
->getResult();
21832234
}
21842235
}
21852236

0 commit comments

Comments
 (0)