Skip to content

Commit 7dd429b

Browse files
committed
[NFC] Refactor buildSubscript a bit
Have callers resolve the SelectedOverload instead of the callee. Then make the error paths more apparent, and flush Optional<SelectedOverload> wherever it can be found.
1 parent 1534b36 commit 7dd429b

File tree

1 file changed

+58
-70
lines changed

1 file changed

+58
-70
lines changed

lib/Sema/CSApply.cpp

Lines changed: 58 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -1228,41 +1228,13 @@ namespace {
12281228
bool hasTrailingClosure,
12291229
ConstraintLocatorBuilder locator, bool isImplicit,
12301230
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) {
12601232
// Build the new subscript.
12611233
auto newSubscript = buildSubscriptHelper(base, index, argLabels,
1262-
*selected, hasTrailingClosure,
1234+
selected, hasTrailingClosure,
12631235
locator, isImplicit, semantics);
12641236

1265-
if (selected->choice.getKind() == OverloadChoiceKind::DeclViaDynamic) {
1237+
if (selected.choice.getKind() == OverloadChoiceKind::DeclViaDynamic) {
12661238
// Rewrite for implicit unwrapping if the solution requires it.
12671239
auto *dynamicLocator = cs.getConstraintLocator(
12681240
locator, {ConstraintLocator::SubscriptMember,
@@ -1277,19 +1249,19 @@ namespace {
12771249
}
12781250
}
12791251

1280-
if (selected->choice.isDecl()) {
1252+
if (selected.choice.isDecl()) {
12811253
auto locatorKind = ConstraintLocator::SubscriptMember;
1282-
if (selected->choice.getKind() ==
1254+
if (selected.choice.getKind() ==
12831255
OverloadChoiceKind::DynamicMemberLookup)
12841256
locatorKind = ConstraintLocator::Member;
12851257

1286-
if (selected->choice.getKind() ==
1258+
if (selected.choice.getKind() ==
12871259
OverloadChoiceKind::KeyPathDynamicMemberLookup &&
12881260
!isa<SubscriptExpr>(locator.getAnchor()))
12891261
locatorKind = ConstraintLocator::Member;
12901262

12911263
newSubscript =
1292-
forceUnwrapIfExpected(newSubscript, selected->choice,
1264+
forceUnwrapIfExpected(newSubscript, selected.choice,
12931265
locator.withPathElement(locatorKind));
12941266
}
12951267

@@ -1298,7 +1270,7 @@ namespace {
12981270

12991271
Expr *buildSubscriptHelper(Expr *base, Expr *index,
13001272
ArrayRef<Identifier> argLabels,
1301-
SelectedOverload &selected,
1273+
const SelectedOverload &selected,
13021274
bool hasTrailingClosure,
13031275
ConstraintLocatorBuilder locator,
13041276
bool isImplicit, AccessSemantics semantics) {
@@ -2862,8 +2834,29 @@ namespace {
28622834
cs.getConstraintLocator(expr, ConstraintLocator::SubscriptMember);
28632835
auto overload = solution.getOverloadChoiceIfAvailable(memberLocator);
28642836

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) {
28672860
return buildDynamicMemberLookupRef(
28682861
expr, expr->getBase(), expr->getIndex()->getStartLoc(), SourceLoc(),
28692862
*overload, memberLocator);
@@ -2872,7 +2865,7 @@ namespace {
28722865
return buildSubscript(
28732866
expr->getBase(), expr->getIndex(), expr->getArgumentLabels(),
28742867
expr->hasTrailingClosure(), cs.getConstraintLocator(expr),
2875-
expr->isImplicit(), expr->getAccessSemantics(), overload);
2868+
expr->isImplicit(), expr->getAccessSemantics(), *overload);
28762869
}
28772870

28782871
/// "Finish" an array expression by filling in the semantic expression.
@@ -2967,11 +2960,14 @@ namespace {
29672960
}
29682961

29692962
Expr *visitDynamicSubscriptExpr(DynamicSubscriptExpr *expr) {
2963+
auto *memberLocator =
2964+
cs.getConstraintLocator(expr, ConstraintLocator::SubscriptMember);
29702965
return buildSubscript(expr->getBase(), expr->getIndex(),
29712966
expr->getArgumentLabels(),
29722967
expr->hasTrailingClosure(),
29732968
cs.getConstraintLocator(expr),
2974-
expr->isImplicit(), AccessSemantics::Ordinary);
2969+
expr->isImplicit(), AccessSemantics::Ordinary,
2970+
solution.getOverloadChoice(memberLocator));
29752971
}
29762972

29772973
Expr *visitTupleElementExpr(TupleElementExpr *expr) {
@@ -4193,8 +4189,6 @@ namespace {
41934189
}
41944190

41954191
auto kind = origComponent.getKind();
4196-
Optional<SelectedOverload> foundDecl;
4197-
41984192
auto locator = cs.getConstraintLocator(
41994193
E, LocatorPathElt::KeyPathComponent(i));
42004194

@@ -4207,48 +4201,42 @@ namespace {
42074201
// If this is an unresolved link, make sure we resolved it.
42084202
if (kind == KeyPathExpr::Component::Kind::UnresolvedProperty ||
42094203
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;
42244222
}
42254223
}
42264224

42274225
switch (kind) {
42284226
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(),
42364229
locator, resolvedComponents);
42374230
break;
42384231
}
42394232
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-
42464233
ArrayRef<Identifier> subscriptLabels;
42474234
if (!isDynamicMember)
42484235
subscriptLabels = origComponent.getSubscriptLabels();
42494236

42504237
buildKeyPathSubscriptComponent(
4251-
*foundDecl, origComponent.getLoc(), origComponent.getIndexExpr(),
4238+
solution.getOverloadChoice(locator),
4239+
origComponent.getLoc(), origComponent.getIndexExpr(),
42524240
subscriptLabels, locator, resolvedComponents);
42534241
break;
42544242
}

0 commit comments

Comments
 (0)