@@ -1120,18 +1120,31 @@ ConstraintSystem::getTypeOfMemberReference(
1120
1120
// This is the easy case.
1121
1121
funcType = value->getInterfaceType ()->castTo <AnyFunctionType>();
1122
1122
} 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.
1125
1125
//
1126
1126
// If the access is mutating, wrap the storage type in an lvalue type.
1127
1127
Type refType;
1128
1128
if (auto *subscript = dyn_cast<SubscriptDecl>(value)) {
1129
1129
auto elementTy = subscript->getElementInterfaceType ();
1130
+
1130
1131
if (doesStorageProduceLValue (TC, subscript, baseTy, useDC, base))
1131
1132
elementTy = LValueType::get (elementTy);
1132
1133
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
+
1133
1146
auto indicesTy = subscript->getIndicesInterfaceType ();
1134
- refType = FunctionType::get (elementTy, indicesTy ,
1147
+ refType = FunctionType::get (indicesTy, elementTy ,
1135
1148
AnyFunctionType::ExtInfo ());
1136
1149
} else {
1137
1150
refType = TC.getUnopenedTypeOfReference (cast<VarDecl>(value),
@@ -1207,27 +1220,9 @@ ConstraintSystem::getTypeOfMemberReference(
1207
1220
1208
1221
// Compute the type of the reference.
1209
1222
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'.
1231
1226
type = openedFnType->getResult ();
1232
1227
} else if (isDynamicResult && isa<AbstractFunctionDecl>(value)) {
1233
1228
// For a dynamic result referring to an instance function through
0 commit comments