Skip to content

Commit 2b86bed

Browse files
committed
Sema: Clean up subscript handling in getTypeOfMemberReference()
We did things with subscripts in two places in this function; move them closer together.
1 parent e0ea83a commit 2b86bed

File tree

1 file changed

+19
-24
lines changed

1 file changed

+19
-24
lines changed

lib/Sema/ConstraintSystem.cpp

Lines changed: 19 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1120,18 +1120,31 @@ ConstraintSystem::getTypeOfMemberReference(
11201120
// This is the easy case.
11211121
funcType = value->getInterfaceType()->castTo<AnyFunctionType>();
11221122
} else {
1123-
// For a property, build a function (Self) -> PropType.
1124-
// For a subscript, build a function (Self) -> (Indices...) -> ElementType.
1123+
// For a property, build a type (Self) -> PropType.
1124+
// For a subscript, build a type (Self) -> (Indices...) -> ElementType.
11251125
//
11261126
// If the access is mutating, wrap the storage type in an lvalue type.
11271127
Type refType;
11281128
if (auto *subscript = dyn_cast<SubscriptDecl>(value)) {
11291129
auto elementTy = subscript->getElementInterfaceType();
1130+
11301131
if (doesStorageProduceLValue(TC, subscript, baseTy, useDC, base))
11311132
elementTy = LValueType::get(elementTy);
11321133

1134+
// See ConstraintSystem::resolveOverload() -- optional and dynamic
1135+
// subscripts are a special case, because the optionality is
1136+
// applied to the result type and not the type of the reference.
1137+
if (!isRequirementOrWitness(locator)) {
1138+
if (subscript->getAttrs().hasAttribute<OptionalAttr>())
1139+
elementTy = OptionalType::get(elementTy->getRValueType());
1140+
else if (isDynamicResult) {
1141+
elementTy = ImplicitlyUnwrappedOptionalType::get(
1142+
elementTy->getRValueType());
1143+
}
1144+
}
1145+
11331146
auto indicesTy = subscript->getIndicesInterfaceType();
1134-
refType = FunctionType::get(elementTy, indicesTy,
1147+
refType = FunctionType::get(indicesTy, elementTy,
11351148
AnyFunctionType::ExtInfo());
11361149
} else {
11371150
refType = TC.getUnopenedTypeOfReference(cast<VarDecl>(value),
@@ -1207,27 +1220,9 @@ ConstraintSystem::getTypeOfMemberReference(
12071220

12081221
// Compute the type of the reference.
12091222
Type type;
1210-
if (auto subscript = dyn_cast<SubscriptDecl>(value)) {
1211-
// For a subscript, turn the element type into an (@unchecked)
1212-
// optional or lvalue, depending on whether the result type is
1213-
// optional/dynamic, is settable, or is not.
1214-
auto fnType = openedFnType->getResult()->castTo<FunctionType>();
1215-
auto elementTy = fnType->getResult();
1216-
if (!isRequirementOrWitness(locator)) {
1217-
if (subscript->getAttrs().hasAttribute<OptionalAttr>())
1218-
elementTy = OptionalType::get(elementTy->getRValueType());
1219-
else if (isDynamicResult) {
1220-
elementTy = ImplicitlyUnwrappedOptionalType::get(
1221-
elementTy->getRValueType());
1222-
}
1223-
}
1224-
1225-
type = FunctionType::get(fnType->getInput(), elementTy);
1226-
} else if (!value->isInstanceMember() || isInstance) {
1227-
// For a constructor, enum element, static method, static property,
1228-
// or an instance method referenced through an instance, we've consumed the
1229-
// curried 'self' already. For a type, strip off the 'self' we artificially
1230-
// added.
1223+
if (!value->isInstanceMember() || isInstance) {
1224+
// For a static member referenced through a metatype or an instance
1225+
// member referenced through an instance, strip off the 'self'.
12311226
type = openedFnType->getResult();
12321227
} else if (isDynamicResult && isa<AbstractFunctionDecl>(value)) {
12331228
// For a dynamic result referring to an instance function through

0 commit comments

Comments
 (0)