Skip to content

Commit d8ead6c

Browse files
committed
Sema: Refactor getTypeOf{Member,}Reference() to take the OverloadChoice
1 parent 2fde4a5 commit d8ead6c

File tree

3 files changed

+69
-64
lines changed

3 files changed

+69
-64
lines changed

include/swift/Sema/ConstraintSystem.h

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4441,8 +4441,7 @@ class ConstraintSystem {
44414441

44424442
/// \returns The opened type and the thrown error type.
44434443
std::pair<Type, Type> getTypeOfReferenceImpl(
4444-
ValueDecl *decl,
4445-
FunctionRefInfo functionRefInfo,
4444+
OverloadChoice choice,
44464445
ConstraintLocatorBuilder locator,
44474446
DeclContext *useDC,
44484447
PreparedOverloadBuilder *preparedOverload);
@@ -4453,20 +4452,16 @@ class ConstraintSystem {
44534452
/// the type by replacing each instance of an archetype with a fresh type
44544453
/// variable.
44554454
///
4456-
/// \param decl The declarations whose type is being computed.
4457-
///
44584455
/// \returns a description of the type of this declaration reference.
44594456
DeclReferenceType getTypeOfReference(
4460-
ValueDecl *decl,
4461-
FunctionRefInfo functionRefInfo,
4457+
OverloadChoice choice,
44624458
ConstraintLocatorBuilder locator,
44634459
DeclContext *useDC,
44644460
PreparedOverloadBuilder *preparedOverload);
44654461

44664462
/// \returns the opened type, the thrown error type, and the base object type.
44674463
std::tuple<Type, Type, Type> getTypeOfMemberReferenceImpl(
4468-
Type baseTy, ValueDecl *decl, DeclContext *useDC, bool isDynamicLookup,
4469-
FunctionRefInfo functionRefInfo, ConstraintLocator *locator,
4464+
OverloadChoice choice, DeclContext *useDC, ConstraintLocator *locator,
44704465
SmallVectorImpl<OpenedType> *replacements = nullptr,
44714466
PreparedOverloadBuilder *preparedOverload = nullptr);
44724467

@@ -4477,13 +4472,9 @@ class ConstraintSystem {
44774472
/// this routine "opens up" the type by replacing each instance of a generic
44784473
/// parameter with a fresh type variable.
44794474
///
4480-
/// \param isDynamicLookup Indicates that this declaration was found via
4481-
/// dynamic lookup.
4482-
///
44834475
/// \returns a description of the type of this declaration reference.
44844476
DeclReferenceType getTypeOfMemberReference(
4485-
Type baseTy, ValueDecl *decl, DeclContext *useDC, bool isDynamicLookup,
4486-
FunctionRefInfo functionRefInfo, ConstraintLocator *locator,
4477+
OverloadChoice choice, DeclContext *useDC, ConstraintLocator *locator,
44874478
SmallVectorImpl<OpenedType> *replacements = nullptr,
44884479
PreparedOverloadBuilder *preparedOverload = nullptr);
44894480

@@ -4497,7 +4488,7 @@ class ConstraintSystem {
44974488
}
44984489

44994490
private:
4500-
DeclReferenceType getTypeOfMemberTypeReference(
4491+
Type getTypeOfMemberTypeReference(
45014492
Type baseObjTy, TypeDecl *typeDecl, ConstraintLocator *locator,
45024493
PreparedOverloadBuilder *preparedOverload);
45034494

lib/Sema/TypeCheckProtocol.cpp

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1172,11 +1172,9 @@ swift::matchWitness(WitnessChecker::RequirementEnvironmentCache &reqEnvCache,
11721172

11731173
reqLocator =
11741174
cs->getConstraintLocator(req, ConstraintLocator::ProtocolRequirement);
1175+
OverloadChoice reqChoice(selfTy, req, FunctionRefInfo::doubleBaseNameApply());
11751176
auto reqTypeInfo =
1176-
cs->getTypeOfMemberReference(selfTy, req, dc,
1177-
/*isDynamicResult=*/false,
1178-
FunctionRefInfo::doubleBaseNameApply(),
1179-
reqLocator, &reqReplacements);
1177+
cs->getTypeOfMemberReference(reqChoice, dc, reqLocator, &reqReplacements);
11801178
reqType = reqTypeInfo.adjustedReferenceType;
11811179
reqType = reqType->getRValueType();
11821180

@@ -1202,23 +1200,23 @@ swift::matchWitness(WitnessChecker::RequirementEnvironmentCache &reqEnvCache,
12021200
}
12031201

12041202
// Open up the witness type.
1205-
SmallVector<OpenedType, 4> witnessReplacements;
1206-
12071203
witnessType = witness->getInterfaceType();
12081204
witnessLocator =
12091205
cs->getConstraintLocator(req, LocatorPathElt::Witness(witness));
12101206
DeclReferenceType openWitnessTypeInfo;
12111207

12121208
if (witness->getDeclContext()->isTypeContext()) {
1209+
OverloadChoice witnessChoice(selfTy, witness, FunctionRefInfo::doubleBaseNameApply());
12131210
openWitnessTypeInfo =
1214-
cs->getTypeOfMemberReference(selfTy, witness, dc,
1215-
/*isDynamicResult=*/false,
1216-
FunctionRefInfo::doubleBaseNameApply(),
1217-
witnessLocator, &witnessReplacements);
1211+
cs->getTypeOfMemberReference(witnessChoice, dc,
1212+
witnessLocator,
1213+
/*replacements=*/nullptr,
1214+
/*preparedOverload=*/nullptr);
12181215
} else {
1216+
OverloadChoice witnessChoice(Type(), witness, FunctionRefInfo::doubleBaseNameApply());
12191217
openWitnessTypeInfo =
12201218
cs->getTypeOfReference(
1221-
witness, FunctionRefInfo::doubleBaseNameApply(), witnessLocator,
1219+
witnessChoice, witnessLocator,
12221220
/*useDC=*/nullptr, /*preparedOverload=*/nullptr);
12231221
}
12241222

lib/Sema/TypeOfReference.cpp

Lines changed: 55 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1109,11 +1109,12 @@ recordFixIfNeededForPlaceholderInDecl(ConstraintSystem &cs, ValueDecl *D,
11091109
}
11101110

11111111
std::pair<Type, Type>
1112-
ConstraintSystem::getTypeOfReferenceImpl(ValueDecl *value,
1113-
FunctionRefInfo functionRefInfo,
1112+
ConstraintSystem::getTypeOfReferenceImpl(OverloadChoice choice,
11141113
ConstraintLocatorBuilder locator,
11151114
DeclContext *useDC,
11161115
PreparedOverloadBuilder *preparedOverload) {
1116+
auto *value = choice.getDecl();
1117+
11171118
ASSERT(!!preparedOverload == PreparingOverload);
11181119

11191120
recordFixIfNeededForPlaceholderInDecl(*this, value, locator);
@@ -1139,6 +1140,8 @@ ConstraintSystem::getTypeOfReferenceImpl(ValueDecl *value,
11391140

11401141
// Unqualified reference to a local or global function.
11411142
if (auto funcDecl = dyn_cast<AbstractFunctionDecl>(value)) {
1143+
auto functionRefInfo = choice.getFunctionRefInfo();
1144+
11421145
SmallVector<OpenedType, 4> replacements;
11431146

11441147
auto funcType = funcDecl->getInterfaceType()->castTo<AnyFunctionType>();
@@ -1234,16 +1237,17 @@ ConstraintSystem::getTypeOfReferenceImpl(ValueDecl *value,
12341237
}
12351238

12361239
DeclReferenceType
1237-
ConstraintSystem::getTypeOfReference(ValueDecl *value,
1238-
FunctionRefInfo functionRefInfo,
1240+
ConstraintSystem::getTypeOfReference(OverloadChoice choice,
12391241
ConstraintLocatorBuilder locator,
12401242
DeclContext *useDC,
12411243
PreparedOverloadBuilder *preparedOverload) {
12421244
ASSERT(!!preparedOverload == PreparingOverload);
12431245

12441246
Type openedType, thrownErrorType;
12451247
std::tie(openedType, thrownErrorType) = getTypeOfReferenceImpl(
1246-
value, functionRefInfo, locator, useDC, preparedOverload);
1248+
choice, locator, useDC, preparedOverload);
1249+
1250+
auto *value = choice.getDecl();
12471251

12481252
if (value->getDeclContext()->isTypeContext() && isa<FuncDecl>(value)) {
12491253
auto *openedFnType = openedType->castTo<FunctionType>();
@@ -1252,6 +1256,7 @@ ConstraintSystem::getTypeOfReference(ValueDecl *value,
12521256
auto func = cast<FuncDecl>(value);
12531257
assert(func->isOperator() && "Lookup should only find operators");
12541258

1259+
auto functionRefInfo = choice.getFunctionRefInfo();
12551260

12561261
auto origOpenedType = openedFnType;
12571262
if (!isRequirementOrWitness(locator)) {
@@ -1293,7 +1298,7 @@ ConstraintSystem::getTypeOfReference(ValueDecl *value,
12931298
auto origOpenedType = openedType;
12941299
if (!isRequirementOrWitness(locator)) {
12951300
unsigned numApplies = getNumApplications(/*hasAppliedSelf*/ false,
1296-
functionRefInfo);
1301+
choice.getFunctionRefInfo());
12971302
openedType = adjustFunctionTypeForConcurrency(
12981303
origOpenedType->castTo<FunctionType>(), /*baseType=*/Type(), funcDecl,
12991304
useDC, numApplies, /*isMainDispatchQueue=*/false,
@@ -1523,10 +1528,10 @@ void ConstraintSystem::openGenericRequirement(
15231528
preparedOverload);
15241529
}
15251530

1526-
DeclReferenceType ConstraintSystem::getTypeOfMemberTypeReference(
1531+
Type ConstraintSystem::getTypeOfMemberTypeReference(
15271532
Type baseObjTy, TypeDecl *typeDecl, ConstraintLocator *locator,
15281533
PreparedOverloadBuilder *preparedOverload) {
1529-
assert(!isa<ModuleDecl>(typeDecl) && "Nested module?");
1534+
ASSERT(!isa<ModuleDecl>(typeDecl) && "Nested module?");
15301535

15311536
auto memberTy = TypeChecker::substMemberTypeWithBase(typeDecl, baseObjTy);
15321537

@@ -1552,8 +1557,7 @@ DeclReferenceType ConstraintSystem::getTypeOfMemberTypeReference(
15521557
}
15531558

15541559
FunctionType::Param baseObjParam(baseObjTy);
1555-
auto openedType = FunctionType::get({baseObjParam}, memberTy);
1556-
return { openedType, openedType, memberTy, memberTy, Type() };
1560+
return FunctionType::get({baseObjParam}, memberTy);
15571561
}
15581562

15591563
std::pair<Type, Type> ConstraintSystem::getOpenedStorageType(
@@ -1853,18 +1857,30 @@ static FunctionType *applyOptionality(ValueDecl *value, FunctionType *fnTy) {
18531857

18541858
std::tuple<Type, Type, Type>
18551859
ConstraintSystem::getTypeOfMemberReferenceImpl(
1856-
Type baseTy, ValueDecl *value, DeclContext *useDC, bool isDynamicLookup,
1857-
FunctionRefInfo functionRefInfo, ConstraintLocator *locator,
1858-
SmallVectorImpl<OpenedType> *replacementsPtr,
1860+
OverloadChoice choice, DeclContext *useDC,
1861+
ConstraintLocator *locator, SmallVectorImpl<OpenedType> *replacementsPtr,
18591862
PreparedOverloadBuilder *preparedOverload) {
1860-
ASSERT(!isa<TypeDecl>(value));
18611863
ASSERT(!!preparedOverload == PreparingOverload);
1864+
1865+
auto *value = choice.getDecl();
1866+
auto functionRefInfo = choice.getFunctionRefInfo();
1867+
18621868
recordFixIfNeededForPlaceholderInDecl(*this, value, locator);
18631869

18641870
// Figure out the instance type used for the base.
1871+
auto baseTy = choice.getBaseType();
18651872
Type baseRValueTy = baseTy->getRValueType();
18661873
auto baseObjTy = baseRValueTy->getMetatypeInstanceType();
18671874

1875+
Type openedType;
1876+
Type thrownErrorType;
1877+
1878+
if (auto *typeDecl = dyn_cast<TypeDecl>(value)) {
1879+
openedType = getTypeOfMemberTypeReference(baseObjTy, typeDecl,
1880+
locator, preparedOverload);
1881+
return {openedType, thrownErrorType, baseObjTy};
1882+
}
1883+
18681884
// Figure out the declaration context to use when opening this type.
18691885
DeclContext *innerDC = value->getInnermostDeclContext();
18701886
DeclContext *outerDC = value->getDeclContext();
@@ -1898,8 +1914,6 @@ ConstraintSystem::getTypeOfMemberReferenceImpl(
18981914
// strip it off later.
18991915
auto hasAppliedSelf = doesMemberRefApplyCurriedSelf(baseRValueTy, value);
19001916

1901-
Type openedType;
1902-
Type thrownErrorType;
19031917
if (isa<AbstractFunctionDecl>(value) ||
19041918
isa<EnumElementDecl>(value) ||
19051919
isa<MacroDecl>(value)) {
@@ -1987,7 +2001,7 @@ ConstraintSystem::getTypeOfMemberReferenceImpl(
19872001
addConstraint(ConstraintKind::Bind, baseOpenedTy, selfObjTy,
19882002
getConstraintLocator(locator), /*isFavored=*/false,
19892003
preparedOverload);
1990-
} else if (!isDynamicLookup) {
2004+
} else if (choice.getKind() != OverloadChoiceKind::DeclViaDynamic) {
19912005
addSelfConstraint(*this, baseOpenedTy, selfObjTy, locator, preparedOverload);
19922006
}
19932007

@@ -2025,42 +2039,40 @@ ConstraintSystem::getTypeOfMemberReferenceImpl(
20252039
}
20262040

20272041
DeclReferenceType ConstraintSystem::getTypeOfMemberReference(
2028-
Type baseTy, ValueDecl *value, DeclContext *useDC, bool isDynamicLookup,
2029-
FunctionRefInfo functionRefInfo, ConstraintLocator *locator,
2042+
OverloadChoice choice, DeclContext *useDC, ConstraintLocator *locator,
20302043
SmallVectorImpl<OpenedType> *replacementsPtr,
20312044
PreparedOverloadBuilder *preparedOverload) {
20322045
ASSERT(!!preparedOverload == PreparingOverload);
20332046

2047+
auto *value = choice.getDecl();
2048+
20342049
// Figure out the instance type used for the base.
2035-
Type baseRValueTy = baseTy;
2050+
Type baseRValueTy = choice.getBaseType();
20362051
Type baseObjTy = baseRValueTy->getMetatypeInstanceType();
20372052

2038-
// If the base is a module type, just use the type of the decl.
2039-
if (baseObjTy->getMetatypeInstanceType()->is<ModuleType>()) {
2040-
return getTypeOfReference(value, functionRefInfo, locator, useDC,
2041-
preparedOverload);
2042-
}
2043-
2044-
if (auto *typeDecl = dyn_cast<TypeDecl>(value)) {
2045-
return getTypeOfMemberTypeReference(baseObjTy, typeDecl,
2046-
locator, preparedOverload);
2047-
}
2053+
// A reference to a module member is really unqualified, and should
2054+
// be handled by the caller via getTypeOfReference().
2055+
ASSERT(!baseObjTy->is<ModuleType>());
20482056

20492057
Type openedType, thrownErrorType;
20502058
std::tie(openedType, thrownErrorType, baseObjTy)
2051-
= getTypeOfMemberReferenceImpl(baseTy, value, useDC,
2052-
isDynamicLookup, functionRefInfo,
2053-
locator, replacementsPtr,
2059+
= getTypeOfMemberReferenceImpl(choice, useDC, locator, replacementsPtr,
20542060
preparedOverload);
20552061

2062+
if (isa<TypeDecl>(value)) {
2063+
auto type = openedType->castTo<FunctionType>()->getResult();
2064+
return { openedType, openedType, type, type, Type() };
2065+
}
2066+
20562067
auto hasAppliedSelf = doesMemberRefApplyCurriedSelf(baseRValueTy, value);
20572068

20582069
// Adjust the opened type for concurrency.
20592070
Type origOpenedType = openedType;
20602071
if (isRequirementOrWitness(locator)) {
20612072
// Don't adjust when doing witness matching, because that can cause cycles.
20622073
} else if (isa<AbstractFunctionDecl>(value) || isa<EnumElementDecl>(value)) {
2063-
unsigned numApplies = getNumApplications(hasAppliedSelf, functionRefInfo);
2074+
unsigned numApplies = getNumApplications(
2075+
hasAppliedSelf, choice.getFunctionRefInfo());
20642076
openedType = adjustFunctionTypeForConcurrency(
20652077
origOpenedType->castTo<FunctionType>(), baseObjTy, value, useDC,
20662078
numApplies, isMainDispatchQueueMember(locator),
@@ -2082,6 +2094,8 @@ DeclReferenceType ConstraintSystem::getTypeOfMemberReference(
20822094
origFnType->getParams(), resultTy, origFnType->getExtInfo());
20832095
}
20842096

2097+
bool isDynamicLookup = (choice.getKind() == OverloadChoiceKind::DeclViaDynamic);
2098+
20852099
// Check if we need to apply a layer of optionality to the type.
20862100
if (!isRequirementOrWitness(locator)) {
20872101
if (isDynamicLookup || value->getAttrs().hasAttribute<OptionalAttr>()) {
@@ -2833,14 +2847,16 @@ ConstraintSystem::prepareOverloadImpl(ConstraintLocator *locator,
28332847
// Retrieve the type of a reference to the specific declaration choice.
28342848
assert(!baseTy->hasTypeParameter());
28352849

2850+
// If the base is a module type, it's an unqualified reference.
2851+
if (baseTy->getMetatypeInstanceType()->is<ModuleType>()) {
2852+
return getTypeOfReference(choice, locator, useDC, preparedOverload);
2853+
}
2854+
28362855
return getTypeOfMemberReference(
2837-
baseTy, choice.getDecl(), useDC,
2838-
(choice.getKind() == OverloadChoiceKind::DeclViaDynamic),
2839-
choice.getFunctionRefInfo(), locator, nullptr, preparedOverload);
2856+
choice, useDC, locator, /*replacements=*/nullptr, preparedOverload);
28402857
} else {
28412858
return getTypeOfReference(
2842-
choice.getDecl(), choice.getFunctionRefInfo(), locator, useDC,
2843-
preparedOverload);
2859+
choice, locator, useDC, preparedOverload);
28442860
}
28452861
}
28462862

0 commit comments

Comments
 (0)