Skip to content

Commit 6d8e5f1

Browse files
authored
Merge pull request #28809 from CodaFi/constant-contact
[NFC] Refactor Subscript Expr Rebuilding a Bit
2 parents bc62c14 + 7dd429b commit 6d8e5f1

File tree

4 files changed

+64
-113
lines changed

4 files changed

+64
-113
lines changed

include/swift/AST/Expr.h

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1741,17 +1741,6 @@ class DynamicSubscriptExpr final
17411741
llvm::function_ref<Type(const Expr *)> getType =
17421742
[](const Expr *E) -> Type { return E->getType(); });
17431743

1744-
/// Create a new dynamic subscript.
1745-
static DynamicSubscriptExpr *create(ASTContext &ctx, Expr *base,
1746-
SourceLoc lSquareLoc,
1747-
ArrayRef<Expr *> indexArgs,
1748-
ArrayRef<Identifier> indexArgLabels,
1749-
ArrayRef<SourceLoc> indexArgLabelLocs,
1750-
SourceLoc rSquareLoc,
1751-
Expr *trailingClosure,
1752-
ConcreteDeclRef decl,
1753-
bool implicit);
1754-
17551744
/// getIndex - Retrieve the index of the subscript expression, i.e., the
17561745
/// "offset" into the base value.
17571746
Expr *getIndex() const { return Index; }

lib/AST/Expr.cpp

Lines changed: 0 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1504,33 +1504,6 @@ DynamicSubscriptExpr::create(ASTContext &ctx, Expr *base, Expr *index,
15041504
hasTrailingClosure, decl, implicit);
15051505
}
15061506

1507-
DynamicSubscriptExpr *
1508-
DynamicSubscriptExpr::create(ASTContext &ctx, Expr *base, SourceLoc lSquareLoc,
1509-
ArrayRef<Expr *> indexArgs,
1510-
ArrayRef<Identifier> indexArgLabels,
1511-
ArrayRef<SourceLoc> indexArgLabelLocs,
1512-
SourceLoc rSquareLoc,
1513-
Expr *trailingClosure,
1514-
ConcreteDeclRef decl,
1515-
bool implicit) {
1516-
SmallVector<Identifier, 4> indexArgLabelsScratch;
1517-
SmallVector<SourceLoc, 4> indexArgLabelLocsScratch;
1518-
Expr *index = packSingleArgument(ctx, lSquareLoc, indexArgs, indexArgLabels,
1519-
indexArgLabelLocs, rSquareLoc,
1520-
trailingClosure, implicit,
1521-
indexArgLabelsScratch,
1522-
indexArgLabelLocsScratch);
1523-
1524-
size_t size = totalSizeToAlloc(indexArgLabels, indexArgLabelLocs,
1525-
trailingClosure != nullptr);
1526-
1527-
void *memory = ctx.Allocate(size, alignof(DynamicSubscriptExpr));
1528-
return new (memory) DynamicSubscriptExpr(base, index, indexArgLabels,
1529-
indexArgLabelLocs,
1530-
trailingClosure != nullptr,
1531-
decl, implicit);
1532-
}
1533-
15341507
UnresolvedMemberExpr::UnresolvedMemberExpr(SourceLoc dotLoc,
15351508
DeclNameLoc nameLoc,
15361509
DeclNameRef name, Expr *argument,

lib/Sema/CSApply.cpp

Lines changed: 60 additions & 71 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
}
@@ -4485,7 +4473,8 @@ namespace {
44854473
}
44864474

44874475
void buildKeyPathSubscriptComponent(
4488-
SelectedOverload &overload, SourceLoc componentLoc, Expr *indexExpr,
4476+
const SelectedOverload &overload,
4477+
SourceLoc componentLoc, Expr *indexExpr,
44894478
ArrayRef<Identifier> labels, ConstraintLocator *locator,
44904479
SmallVectorImpl<KeyPathExpr::Component> &components) {
44914480
auto subscript = cast<SubscriptDecl>(overload.choice.getDecl());

lib/Sema/ConstraintSystem.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -471,19 +471,19 @@ enum class SolutionCompareResult {
471471
/// declaration was opened, which may involve type variables.
472472
struct SelectedOverload {
473473
/// The overload choice.
474-
OverloadChoice choice;
474+
const OverloadChoice choice;
475475

476476
/// The opened type of the base of the reference to this overload, if
477477
/// we're referencing a member.
478-
Type openedFullType;
478+
const Type openedFullType;
479479

480480
/// The opened type produced by referring to this overload.
481-
Type openedType;
481+
const Type openedType;
482482

483483
/// The type that this overload binds. Note that this may differ from
484484
/// openedType, for example it will include any IUO unwrapping that has taken
485485
/// place.
486-
Type boundType;
486+
const Type boundType;
487487
};
488488

489489
/// Provides information about the application of a function argument to a

0 commit comments

Comments
 (0)