Skip to content

Commit a0919f7

Browse files
committed
[CS] Use subclasses to expose locator element info
Instead of adding specific accessors directly to ConstraintLocator::PathElement, add subclasses that expose these accessors.
1 parent 258d05a commit a0919f7

12 files changed

+484
-368
lines changed

lib/Sema/CSApply.cpp

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1542,14 +1542,14 @@ namespace {
15421542

15431543
auto *componentLoc = cs.getConstraintLocator(
15441544
memberLoc,
1545-
LocatorPathElt::getKeyPathDynamicMember(keyPathTy->getAnyNominal()));
1545+
LocatorPathElt::KeyPathDynamicMember(keyPathTy->getAnyNominal()));
15461546
auto overload = solution.getOverloadChoice(componentLoc);
15471547

15481548
auto getKeyPathComponentIndex =
15491549
[](ConstraintLocator *locator) -> unsigned {
15501550
for (const auto &elt : locator->getPath()) {
1551-
if (elt.getKind() == ConstraintLocator::KeyPathComponent)
1552-
return elt.getKeyPathComponentIdx();
1551+
if (auto kpElt = elt.getAs<LocatorPathElt::KeyPathComponent>())
1552+
return kpElt->getIndex();
15531553
}
15541554
llvm_unreachable("no keypath component node");
15551555
};
@@ -4245,7 +4245,7 @@ namespace {
42454245
Optional<SelectedOverload> foundDecl;
42464246

42474247
auto locator = cs.getConstraintLocator(
4248-
E, ConstraintLocator::PathElement::getKeyPathComponent(i));
4248+
E, LocatorPathElt::KeyPathComponent(i));
42494249
if (kind == KeyPathExpr::Component::Kind::UnresolvedSubscript) {
42504250
locator =
42514251
cs.getConstraintLocator(locator,
@@ -5027,7 +5027,7 @@ Expr *ExprRewriter::coerceTupleToTuple(Expr *expr,
50275027
auto *toElt
50285028
= coerceToType(fromElt, toEltType,
50295029
locator.withPathElement(
5030-
LocatorPathElt::getTupleElement(i)));
5030+
LocatorPathElt::TupleElement(i)));
50315031
if (!toElt)
50325032
return nullptr;
50335033

@@ -5070,7 +5070,7 @@ Expr *ExprRewriter::coerceTupleToTuple(Expr *expr,
50705070
auto *toElt
50715071
= coerceToType(fromElt, toEltType,
50725072
locator.withPathElement(
5073-
LocatorPathElt::getTupleElement(source)));
5073+
LocatorPathElt::TupleElement(source)));
50745074
if (!toElt)
50755075
return nullptr;
50765076

@@ -5390,7 +5390,7 @@ Expr *ExprRewriter::coerceCallArguments(
53905390
auto getArgLocator = [&](unsigned argIdx, unsigned paramIdx)
53915391
-> ConstraintLocatorBuilder {
53925392
return locator.withPathElement(
5393-
LocatorPathElt::getApplyArgToParam(argIdx, paramIdx));
5393+
LocatorPathElt::ApplyArgToParam(argIdx, paramIdx));
53945394
};
53955395

53965396
bool matchCanFail =
@@ -5934,8 +5934,7 @@ buildOpaqueElementConversion(ExprRewriter &rewriter, SourceRange srcRange,
59345934

59355935
Expr *conversion = buildElementConversion(
59365936
rewriter, srcRange, srcType, destType, bridged,
5937-
locator.withPathElement(
5938-
ConstraintLocator::PathElement::getGenericArgument(typeArgIndex)),
5937+
locator.withPathElement(LocatorPathElt::GenericArgument(typeArgIndex)),
59395938
opaque);
59405939

59415940
return { opaque, conversion };
@@ -5954,8 +5953,7 @@ void ExprRewriter::peepholeArrayUpcast(ArrayExpr *expr, Type toType,
59545953

59555954
// Convert the elements.
59565955
ConstraintLocatorBuilder innerLocator =
5957-
locator.withPathElement(
5958-
ConstraintLocator::PathElement::getGenericArgument(0));
5956+
locator.withPathElement(LocatorPathElt::GenericArgument(0));
59595957
for (auto &element : expr->getElements()) {
59605958
if (auto newElement = buildElementConversion(*this, expr->getLoc(),
59615959
cs.getType(element),
@@ -5982,8 +5980,7 @@ void ExprRewriter::peepholeDictionaryUpcast(DictionaryExpr *expr,
59825980
expr->setType(toType);
59835981

59845982
ConstraintLocatorBuilder valueLocator =
5985-
locator.withPathElement(
5986-
ConstraintLocator::PathElement::getGenericArgument(1));
5983+
locator.withPathElement(LocatorPathElt::GenericArgument(1));
59875984

59885985
// Convert the elements.
59895986
TupleTypeElt tupleTypeElts[2] = { keyType, valueType };

lib/Sema/CSDiag.cpp

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,8 @@ void constraints::simplifyLocator(Expr *&anchor,
175175
case ConstraintLocator::NamedTupleElement:
176176
case ConstraintLocator::TupleElement: {
177177
// Extract tuple element.
178-
unsigned index = path[0].getTupleElementIdx();
178+
auto elt = path[0].castTo<LocatorPathElt::AnyTupleElement>();
179+
unsigned index = elt.getIndex();
179180
if (auto tupleExpr = dyn_cast<TupleExpr>(anchor)) {
180181
if (index < tupleExpr->getNumElements()) {
181182
anchor = tupleExpr->getElement(index);
@@ -194,10 +195,11 @@ void constraints::simplifyLocator(Expr *&anchor,
194195
break;
195196
}
196197

197-
case ConstraintLocator::ApplyArgToParam:
198+
case ConstraintLocator::ApplyArgToParam: {
199+
auto elt = path[0].castTo<LocatorPathElt::ApplyArgToParam>();
198200
// Extract tuple element.
199201
if (auto tupleExpr = dyn_cast<TupleExpr>(anchor)) {
200-
unsigned index = path[0].getArgIdx();
202+
unsigned index = elt.getArgIdx();
201203
if (index < tupleExpr->getNumElements()) {
202204
anchor = tupleExpr->getElement(index);
203205
path = path.slice(1);
@@ -207,14 +209,14 @@ void constraints::simplifyLocator(Expr *&anchor,
207209

208210
// Extract subexpression in parentheses.
209211
if (auto parenExpr = dyn_cast<ParenExpr>(anchor)) {
210-
assert(path[0].getArgIdx() == 0);
212+
assert(elt.getArgIdx() == 0);
211213

212214
anchor = parenExpr->getSubExpr();
213215
path = path.slice(1);
214216
continue;
215217
}
216218
break;
217-
219+
}
218220
case ConstraintLocator::ConstructorMember:
219221
if (auto typeExpr = dyn_cast<TypeExpr>(anchor)) {
220222
// This is really an implicit 'init' MemberRef, so point at the base,
@@ -872,8 +874,8 @@ diagnoseUnresolvedDotExprTypeRequirementFailure(ConstraintSystem &cs,
872874
if (path.empty())
873875
return false;
874876

875-
auto &last = path.back();
876-
if (last.getKind() != ConstraintLocator::TypeParameterRequirement)
877+
auto reqElt = path.back().getAs<LocatorPathElt::TypeParameterRequirement>();
878+
if (!reqElt)
877879
return false;
878880

879881
auto *anchor = locator->getAnchor();
@@ -901,7 +903,7 @@ diagnoseUnresolvedDotExprTypeRequirementFailure(ConstraintSystem &cs,
901903

902904
auto req = member->getAsGenericContext()
903905
->getGenericSignature()
904-
->getRequirements()[last.getRequirementIdx()];
906+
->getRequirements()[reqElt->getIndex()];
905907

906908
Diag<Type, Type, Type, Type, StringRef> note;
907909
switch (req.getKind()) {
@@ -1845,7 +1847,7 @@ bool FailureDiagnosis::diagnoseContextualConversionError(
18451847

18461848
ContextualFailure failure(
18471849
expr, CS, CTP, exprType, contextualType,
1848-
CS.getConstraintLocator(expr, LocatorPathElt::getContextualType()));
1850+
CS.getConstraintLocator(expr, LocatorPathElt::ContextualType()));
18491851
return failure.diagnoseAsError();
18501852
}
18511853

@@ -4793,7 +4795,7 @@ bool FailureDiagnosis::diagnoseClosureExpr(
47934795

47944796
MissingArgumentsFailure failure(
47954797
expr, CS, fnType, inferredArgCount - actualArgCount,
4796-
CS.getConstraintLocator(CE, LocatorPathElt::getContextualType()));
4798+
CS.getConstraintLocator(CE, LocatorPathElt::ContextualType()));
47974799
return failure.diagnoseAsError();
47984800
}
47994801

lib/Sema/CSDiagnostics.cpp

Lines changed: 29 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -197,21 +197,21 @@ FailureDiagnostic::getFunctionArgApplyInfo(ConstraintLocator *locator) const {
197197
// have to look through other elements that are generated from an argument
198198
// conversion such as GenericArgument for an optional-to-optional conversion,
199199
// and OptionalPayload for a value-to-optional conversion.
200-
auto applyArgElt =
200+
auto applyArgEltIter =
201201
std::find_if(path.rbegin(), path.rend(), [](LocatorPathElt elt) {
202-
return elt.getKind() == ConstraintLocator::ApplyArgToParam;
202+
return elt.is<LocatorPathElt::ApplyArgToParam>();
203203
});
204204

205-
if (applyArgElt == path.rend())
205+
if (applyArgEltIter == path.rend())
206206
return None;
207207

208-
assert(std::find_if(applyArgElt + 1, path.rend(), [](LocatorPathElt elt) {
208+
assert(std::find_if(applyArgEltIter + 1, path.rend(), [](LocatorPathElt elt) {
209209
return elt.getKind() == ConstraintLocator::ApplyArgToParam;
210210
}) == path.rend() && "Multiple ApplyArgToParam components?");
211211

212212
// Form a new locator that ends at the apply-arg-to-param element, and
213213
// simplify it to get the full argument expression.
214-
auto argPath = path.drop_back(applyArgElt - path.rbegin());
214+
auto argPath = path.drop_back(applyArgEltIter - path.rbegin());
215215
auto *argLocator = cs.getConstraintLocator(
216216
anchor, argPath, ConstraintLocator::getSummaryFlagsForPath(argPath));
217217

@@ -271,8 +271,9 @@ FailureDiagnostic::getFunctionArgApplyInfo(ConstraintLocator *locator) const {
271271
fnInterfaceType = resolveInterfaceType(rawFnType);
272272
}
273273

274-
auto argIdx = applyArgElt->getArgIdx();
275-
auto paramIdx = applyArgElt->getParamIdx();
274+
auto applyArgElt = applyArgEltIter->castTo<LocatorPathElt::ApplyArgToParam>();
275+
auto argIdx = applyArgElt.getArgIdx();
276+
auto paramIdx = applyArgElt.getParamIdx();
276277

277278
return FunctionArgApplyInfo(argExpr, argIdx, getType(argExpr), paramIdx,
278279
fnInterfaceType, fnType, callee);
@@ -331,11 +332,10 @@ ProtocolConformance *RequirementFailure::getConformanceForConditionalReq(
331332
auto &cs = getConstraintSystem();
332333
auto path = locator->getPath();
333334
assert(!path.empty());
335+
assert(path.back().is<LocatorPathElt::AnyRequirement>());
334336

335-
if (!path.back().isConditionalRequirement()) {
336-
assert(path.back().isTypeParameterRequirement());
337+
if (!path.back().isConditionalRequirement())
337338
return nullptr;
338-
}
339339

340340
auto *typeReqLoc = getConstraintLocator(getRawAnchor(), path.drop_back());
341341

@@ -414,8 +414,8 @@ GenericSignature *RequirementFailure::getSignature(ConstraintLocator *locator) {
414414
auto path = locator->getPath();
415415
for (auto iter = path.rbegin(); iter != path.rend(); ++iter) {
416416
const auto &elt = *iter;
417-
if (elt.getKind() == ConstraintLocator::OpenedGeneric)
418-
return elt.getGenericSignature();
417+
if (auto genericElt = elt.getAs<LocatorPathElt::OpenedGeneric>())
418+
return genericElt->getSignature();
419419
}
420420

421421
llvm_unreachable("Type requirement failure should always have signature");
@@ -783,11 +783,9 @@ bool NoEscapeFuncToTypeConversionFailure::diagnoseAsError() {
783783
GenericTypeParamType *paramTy = nullptr;
784784

785785
auto path = getLocator()->getPath();
786-
if (!path.empty()) {
787-
auto &last = path.back();
788-
if (last.getKind() == ConstraintLocator::GenericParameter)
789-
paramTy = last.getGenericParameter();
790-
}
786+
if (!path.empty())
787+
if (auto gpElt = path.back().getAs<LocatorPathElt::GenericParameter>())
788+
paramTy = gpElt->getType();
791789

792790
if (paramTy) {
793791
emitDiagnostic(anchor->getLoc(), diag::converting_noescape_to_type,
@@ -1257,13 +1255,12 @@ bool RValueTreatedAsLValueFailure::diagnoseAsError() {
12571255
diagExpr = argTuple->getElement(0);
12581256
} else if (getLocator()->getPath().size() > 0) {
12591257
auto lastPathElement = getLocator()->getPath().back();
1260-
assert(lastPathElement.getKind() ==
1261-
ConstraintLocator::PathElementKind::ApplyArgToParam);
1258+
auto argElt = lastPathElement.castTo<LocatorPathElt::ApplyArgToParam>();
12621259

12631260
subElementDiagID = diag::cannot_pass_rvalue_inout_subelement;
12641261
rvalueDiagID = diag::cannot_pass_rvalue_inout;
12651262
if (auto argTuple = dyn_cast<TupleExpr>(argExpr))
1266-
diagExpr = argTuple->getElement(lastPathElement.getArgIdx());
1263+
diagExpr = argTuple->getElement(argElt.getArgIdx());
12671264
else if (auto parens = dyn_cast<ParenExpr>(argExpr))
12681265
diagExpr = parens->getSubExpr();
12691266
} else {
@@ -1824,7 +1821,7 @@ AssignmentFailure::getMemberRef(ConstraintLocator *locator) const {
18241821
auto paramTy = fnType->getParams()[0].getPlainType();
18251822
auto keyPath = paramTy->getAnyNominal();
18261823
auto memberLoc = cs.getConstraintLocator(
1827-
locator, LocatorPathElt::getKeyPathDynamicMember(keyPath));
1824+
locator, LocatorPathElt::KeyPathDynamicMember(keyPath));
18281825

18291826
auto memberRef = getOverloadChoiceIfAvailable(memberLoc);
18301827
return memberRef ? Optional<OverloadChoice>(memberRef->choice) : None;
@@ -2412,8 +2409,7 @@ bool AutoClosureForwardingFailure::diagnoseAsError() {
24122409
auto path = getLocator()->getPath();
24132410
assert(!path.empty());
24142411

2415-
auto &last = path.back();
2416-
assert(last.getKind() == ConstraintLocator::ApplyArgToParam);
2412+
auto last = path.back().castTo<LocatorPathElt::ApplyArgToParam>();
24172413

24182414
// We need a raw anchor here because `getAnchor()` is simplified
24192415
// to the argument expression.
@@ -3577,8 +3573,8 @@ bool KeyPathSubscriptIndexHashableFailure::diagnoseAsError() {
35773573
if (locator->isKeyPathSubscriptComponent()) {
35783574
auto *KPE = cast<KeyPathExpr>(anchor);
35793575
for (auto &elt : locator->getPath()) {
3580-
if (elt.isKeyPathComponent()) {
3581-
loc = KPE->getComponents()[elt.getKeyPathComponentIdx()].getLoc();
3576+
if (auto kpElt = elt.getAs<LocatorPathElt::KeyPathComponent>()) {
3577+
loc = KPE->getComponents()[kpElt->getIndex()].getLoc();
35823578
break;
35833579
}
35843580
}
@@ -3594,13 +3590,14 @@ SourceLoc InvalidMemberRefInKeyPath::getLoc() const {
35943590

35953591
if (auto *KPE = dyn_cast<KeyPathExpr>(anchor)) {
35963592
auto *locator = getLocator();
3597-
auto component =
3593+
auto componentIter =
35983594
llvm::find_if(locator->getPath(), [](const LocatorPathElt &elt) {
35993595
return elt.isKeyPathComponent();
36003596
});
36013597

3602-
assert(component != locator->getPath().end());
3603-
return KPE->getComponents()[component->getKeyPathComponentIdx()].getLoc();
3598+
assert(componentIter != locator->getPath().end());
3599+
auto component = componentIter->castTo<LocatorPathElt::KeyPathComponent>();
3600+
return KPE->getComponents()[component.getIndex()].getLoc();
36043601
}
36053602

36063603
return anchor->getLoc();
@@ -3687,9 +3684,11 @@ bool CollectionElementContextualFailure::diagnoseAsError() {
36873684
}
36883685

36893686
if (isa<DictionaryExpr>(getRawAnchor())) {
3690-
const auto &eltLoc = locator->getPath().back();
3687+
auto path = locator->getPath();
3688+
assert(!path.empty());
3689+
auto eltLoc = path.back().castTo<LocatorPathElt::TupleElement>();
36913690

3692-
switch (eltLoc.getTupleElementIdx()) {
3691+
switch (eltLoc.getIndex()) {
36933692
case 0: // key
36943693
diagnostic.emplace(emitDiagnostic(anchor->getLoc(),
36953694
diag::cannot_convert_dict_key, eltType,

lib/Sema/CSDiagnostics.h

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -240,9 +240,7 @@ class RequirementFailure : public FailureDiagnostic {
240240
auto path = locator->getPath();
241241
assert(!path.empty());
242242

243-
auto &last = path.back();
244-
assert(last.isTypeParameterRequirement() ||
245-
last.isConditionalRequirement());
243+
auto last = path.back().castTo<LocatorPathElt::AnyRequirement>();
246244
assert(last.getRequirementKind() == kind);
247245

248246
// It's possible sometimes not to have no base expression.
@@ -255,10 +253,8 @@ class RequirementFailure : public FailureDiagnostic {
255253

256254
unsigned getRequirementIndex() const {
257255
auto path = getLocator()->getPath();
258-
assert(!path.empty());
259-
260-
auto &requirementLoc = path.back();
261-
return requirementLoc.getRequirementIdx();
256+
auto reqElt = path.back().castTo<LocatorPathElt::AnyRequirement>();
257+
return reqElt.getIndex();
262258
}
263259

264260
/// The generic base type where failing requirement comes from.

0 commit comments

Comments
 (0)