@@ -1228,41 +1228,13 @@ namespace {
1228
1228
bool hasTrailingClosure,
1229
1229
ConstraintLocatorBuilder locator, bool isImplicit,
1230
1230
AccessSemantics semantics,
1231
- Optional<SelectedOverload> selected = None) {
1232
-
1233
- // Determine the declaration selected for this subscript operation.
1234
- if (!selected)
1235
- selected = solution.getOverloadChoiceIfAvailable (
1236
- cs.getConstraintLocator (
1237
- locator.withPathElement (
1238
- ConstraintLocator::SubscriptMember)));
1239
-
1240
- // Handles situation where there was a solution available but it didn't
1241
- // have a proper overload selected from subscript call, might be because
1242
- // solver was allowed to return free or unresolved types, which can
1243
- // happen while running diagnostics on one of the expressions.
1244
- if (!selected.hasValue ()) {
1245
- auto &de = cs.getASTContext ().Diags ;
1246
- auto baseType = cs.getType (base);
1247
-
1248
- if (auto errorType = baseType->getAs <ErrorType>()) {
1249
- de.diagnose (base->getLoc (), diag::cannot_subscript_base,
1250
- errorType->getOriginalType ())
1251
- .highlight (base->getSourceRange ());
1252
- } else {
1253
- de.diagnose (base->getLoc (), diag::cannot_subscript_ambiguous_base)
1254
- .highlight (base->getSourceRange ());
1255
- }
1256
-
1257
- return nullptr ;
1258
- }
1259
-
1231
+ const SelectedOverload &selected) {
1260
1232
// Build the new subscript.
1261
1233
auto newSubscript = buildSubscriptHelper (base, index, argLabels,
1262
- * selected, hasTrailingClosure,
1234
+ selected, hasTrailingClosure,
1263
1235
locator, isImplicit, semantics);
1264
1236
1265
- if (selected-> choice .getKind () == OverloadChoiceKind::DeclViaDynamic) {
1237
+ if (selected. choice .getKind () == OverloadChoiceKind::DeclViaDynamic) {
1266
1238
// Rewrite for implicit unwrapping if the solution requires it.
1267
1239
auto *dynamicLocator = cs.getConstraintLocator (
1268
1240
locator, {ConstraintLocator::SubscriptMember,
@@ -1277,19 +1249,19 @@ namespace {
1277
1249
}
1278
1250
}
1279
1251
1280
- if (selected-> choice .isDecl ()) {
1252
+ if (selected. choice .isDecl ()) {
1281
1253
auto locatorKind = ConstraintLocator::SubscriptMember;
1282
- if (selected-> choice .getKind () ==
1254
+ if (selected. choice .getKind () ==
1283
1255
OverloadChoiceKind::DynamicMemberLookup)
1284
1256
locatorKind = ConstraintLocator::Member;
1285
1257
1286
- if (selected-> choice .getKind () ==
1258
+ if (selected. choice .getKind () ==
1287
1259
OverloadChoiceKind::KeyPathDynamicMemberLookup &&
1288
1260
!isa<SubscriptExpr>(locator.getAnchor ()))
1289
1261
locatorKind = ConstraintLocator::Member;
1290
1262
1291
1263
newSubscript =
1292
- forceUnwrapIfExpected (newSubscript, selected-> choice ,
1264
+ forceUnwrapIfExpected (newSubscript, selected. choice ,
1293
1265
locator.withPathElement (locatorKind));
1294
1266
}
1295
1267
@@ -1298,7 +1270,7 @@ namespace {
1298
1270
1299
1271
Expr *buildSubscriptHelper (Expr *base, Expr *index,
1300
1272
ArrayRef<Identifier> argLabels,
1301
- SelectedOverload &selected,
1273
+ const SelectedOverload &selected,
1302
1274
bool hasTrailingClosure,
1303
1275
ConstraintLocatorBuilder locator,
1304
1276
bool isImplicit, AccessSemantics semantics) {
@@ -2862,8 +2834,29 @@ namespace {
2862
2834
cs.getConstraintLocator (expr, ConstraintLocator::SubscriptMember);
2863
2835
auto overload = solution.getOverloadChoiceIfAvailable (memberLocator);
2864
2836
2865
- if (overload && overload->choice .getKind () ==
2866
- OverloadChoiceKind::KeyPathDynamicMemberLookup) {
2837
+ // Handles situation where there was a solution available but it didn't
2838
+ // have a proper overload selected from subscript call, might be because
2839
+ // solver was allowed to return free or unresolved types, which can
2840
+ // happen while running diagnostics on one of the expressions.
2841
+ if (!overload) {
2842
+ const auto *base = expr->getBase ();
2843
+ auto &de = cs.getASTContext ().Diags ;
2844
+ auto baseType = cs.getType (base);
2845
+
2846
+ if (auto errorType = baseType->getAs <ErrorType>()) {
2847
+ de.diagnose (base->getLoc (), diag::cannot_subscript_base,
2848
+ errorType->getOriginalType ())
2849
+ .highlight (base->getSourceRange ());
2850
+ } else {
2851
+ de.diagnose (base->getLoc (), diag::cannot_subscript_ambiguous_base)
2852
+ .highlight (base->getSourceRange ());
2853
+ }
2854
+
2855
+ return nullptr ;
2856
+ }
2857
+
2858
+ if (overload->choice .getKind () ==
2859
+ OverloadChoiceKind::KeyPathDynamicMemberLookup) {
2867
2860
return buildDynamicMemberLookupRef (
2868
2861
expr, expr->getBase (), expr->getIndex ()->getStartLoc (), SourceLoc (),
2869
2862
*overload, memberLocator);
@@ -2872,7 +2865,7 @@ namespace {
2872
2865
return buildSubscript (
2873
2866
expr->getBase (), expr->getIndex (), expr->getArgumentLabels (),
2874
2867
expr->hasTrailingClosure (), cs.getConstraintLocator (expr),
2875
- expr->isImplicit (), expr->getAccessSemantics (), overload);
2868
+ expr->isImplicit (), expr->getAccessSemantics (), * overload);
2876
2869
}
2877
2870
2878
2871
// / "Finish" an array expression by filling in the semantic expression.
@@ -2967,11 +2960,14 @@ namespace {
2967
2960
}
2968
2961
2969
2962
Expr *visitDynamicSubscriptExpr (DynamicSubscriptExpr *expr) {
2963
+ auto *memberLocator =
2964
+ cs.getConstraintLocator (expr, ConstraintLocator::SubscriptMember);
2970
2965
return buildSubscript (expr->getBase (), expr->getIndex (),
2971
2966
expr->getArgumentLabels (),
2972
2967
expr->hasTrailingClosure (),
2973
2968
cs.getConstraintLocator (expr),
2974
- expr->isImplicit (), AccessSemantics::Ordinary);
2969
+ expr->isImplicit (), AccessSemantics::Ordinary,
2970
+ solution.getOverloadChoice (memberLocator));
2975
2971
}
2976
2972
2977
2973
Expr *visitTupleElementExpr (TupleElementExpr *expr) {
@@ -4193,8 +4189,6 @@ namespace {
4193
4189
}
4194
4190
4195
4191
auto kind = origComponent.getKind ();
4196
- Optional<SelectedOverload> foundDecl;
4197
-
4198
4192
auto locator = cs.getConstraintLocator (
4199
4193
E, LocatorPathElt::KeyPathComponent (i));
4200
4194
@@ -4207,48 +4201,42 @@ namespace {
4207
4201
// If this is an unresolved link, make sure we resolved it.
4208
4202
if (kind == KeyPathExpr::Component::Kind::UnresolvedProperty ||
4209
4203
kind == KeyPathExpr::Component::Kind::UnresolvedSubscript) {
4210
- foundDecl = solution.getOverloadChoiceIfAvailable (locator);
4211
- // Leave the component unresolved if the overload was not resolved.
4212
- if (foundDecl) {
4213
- isDynamicMember =
4214
- foundDecl->choice .getKind () ==
4215
- OverloadChoiceKind::DynamicMemberLookup ||
4216
- foundDecl->choice .getKind () ==
4217
- OverloadChoiceKind::KeyPathDynamicMemberLookup;
4218
-
4219
- // If this was a @dynamicMemberLookup property, then we actually
4220
- // form a subscript reference, so switch the kind.
4221
- if (isDynamicMember) {
4222
- kind = KeyPathExpr::Component::Kind::UnresolvedSubscript;
4223
- }
4204
+ auto foundDecl = solution.getOverloadChoiceIfAvailable (locator);
4205
+ if (!foundDecl) {
4206
+ // If we couldn't resolve the component, leave it alone.
4207
+ resolvedComponents.push_back (origComponent);
4208
+ baseTy = origComponent.getComponentType ();
4209
+ continue ;
4210
+ }
4211
+
4212
+ isDynamicMember =
4213
+ foundDecl->choice .getKind () ==
4214
+ OverloadChoiceKind::DynamicMemberLookup ||
4215
+ foundDecl->choice .getKind () ==
4216
+ OverloadChoiceKind::KeyPathDynamicMemberLookup;
4217
+
4218
+ // If this was a @dynamicMemberLookup property, then we actually
4219
+ // form a subscript reference, so switch the kind.
4220
+ if (isDynamicMember) {
4221
+ kind = KeyPathExpr::Component::Kind::UnresolvedSubscript;
4224
4222
}
4225
4223
}
4226
4224
4227
4225
switch (kind) {
4228
4226
case KeyPathExpr::Component::Kind::UnresolvedProperty: {
4229
- // If we couldn't resolve the component, leave it alone.
4230
- if (!foundDecl) {
4231
- resolvedComponents.push_back (origComponent);
4232
- break ;
4233
- }
4234
-
4235
- buildKeyPathPropertyComponent (*foundDecl, origComponent.getLoc (),
4227
+ buildKeyPathPropertyComponent (solution.getOverloadChoice (locator),
4228
+ origComponent.getLoc (),
4236
4229
locator, resolvedComponents);
4237
4230
break ;
4238
4231
}
4239
4232
case KeyPathExpr::Component::Kind::UnresolvedSubscript: {
4240
- // Leave the component unresolved if the overload was not resolved.
4241
- if (!foundDecl) {
4242
- resolvedComponents.push_back (origComponent);
4243
- break ;
4244
- }
4245
-
4246
4233
ArrayRef<Identifier> subscriptLabels;
4247
4234
if (!isDynamicMember)
4248
4235
subscriptLabels = origComponent.getSubscriptLabels ();
4249
4236
4250
4237
buildKeyPathSubscriptComponent (
4251
- *foundDecl, origComponent.getLoc (), origComponent.getIndexExpr (),
4238
+ solution.getOverloadChoice (locator),
4239
+ origComponent.getLoc (), origComponent.getIndexExpr (),
4252
4240
subscriptLabels, locator, resolvedComponents);
4253
4241
break ;
4254
4242
}
@@ -4485,7 +4473,8 @@ namespace {
4485
4473
}
4486
4474
4487
4475
void buildKeyPathSubscriptComponent (
4488
- SelectedOverload &overload, SourceLoc componentLoc, Expr *indexExpr,
4476
+ const SelectedOverload &overload,
4477
+ SourceLoc componentLoc, Expr *indexExpr,
4489
4478
ArrayRef<Identifier> labels, ConstraintLocator *locator,
4490
4479
SmallVectorImpl<KeyPathExpr::Component> &components) {
4491
4480
auto subscript = cast<SubscriptDecl>(overload.choice .getDecl ());
0 commit comments