@@ -197,21 +197,18 @@ FailureDiagnostic::getFunctionArgApplyInfo(ConstraintLocator *locator) const {
197
197
// have to look through other elements that are generated from an argument
198
198
// conversion such as GenericArgument for an optional-to-optional conversion,
199
199
// and OptionalPayload for a value-to-optional conversion.
200
- auto applyArgElt =
201
- std::find_if (path.rbegin (), path.rend (), [](LocatorPathElt elt) {
202
- return elt.getKind () == ConstraintLocator::ApplyArgToParam;
203
- });
204
-
205
- if (applyArgElt == path.rend ())
200
+ auto iter = path.rbegin ();
201
+ auto applyArgElt = locator->findLast <LocatorPathElt::ApplyArgToParam>(iter);
202
+ if (!applyArgElt)
206
203
return None;
207
204
208
- assert ( std::find_if (applyArgElt + 1 , path. rend (), [](LocatorPathElt elt) {
209
- return elt. getKind () == ConstraintLocator ::ApplyArgToParam;
210
- }) == path. rend () && " Multiple ApplyArgToParam components?" );
205
+ auto nextIter = iter + 1 ;
206
+ assert (!locator-> findLast <LocatorPathElt ::ApplyArgToParam>(nextIter) &&
207
+ " Multiple ApplyArgToParam components?" );
211
208
212
209
// Form a new locator that ends at the apply-arg-to-param element, and
213
210
// simplify it to get the full argument expression.
214
- auto argPath = path.drop_back (applyArgElt - path.rbegin ());
211
+ auto argPath = path.drop_back (iter - path.rbegin ());
215
212
auto *argLocator = cs.getConstraintLocator (
216
213
anchor, argPath, ConstraintLocator::getSummaryFlagsForPath (argPath));
217
214
@@ -271,8 +268,8 @@ FailureDiagnostic::getFunctionArgApplyInfo(ConstraintLocator *locator) const {
271
268
fnInterfaceType = resolveInterfaceType (rawFnType);
272
269
}
273
270
274
- auto argIdx = applyArgElt->getValue ();
275
- auto paramIdx = applyArgElt->getValue2 ();
271
+ auto argIdx = applyArgElt->getArgIdx ();
272
+ auto paramIdx = applyArgElt->getParamIdx ();
276
273
277
274
return FunctionArgApplyInfo (argExpr, argIdx, getType (argExpr), paramIdx,
278
275
fnInterfaceType, fnType, callee);
@@ -329,14 +326,11 @@ const Requirement &RequirementFailure::getRequirement() const {
329
326
ProtocolConformance *RequirementFailure::getConformanceForConditionalReq (
330
327
ConstraintLocator *locator) {
331
328
auto &cs = getConstraintSystem ();
332
- auto path = locator->getPath ();
333
- assert (!path.empty ());
334
-
335
- if (!path.back ().isConditionalRequirement ()) {
336
- assert (path.back ().isTypeParameterRequirement ());
329
+ auto reqElt = locator->castLastElementTo <LocatorPathElt::AnyRequirement>();
330
+ if (!reqElt.isConditionalRequirement ())
337
331
return nullptr ;
338
- }
339
332
333
+ auto path = locator->getPath ();
340
334
auto *typeReqLoc = getConstraintLocator (getRawAnchor (), path.drop_back ());
341
335
342
336
auto result = llvm::find_if (
@@ -411,12 +405,8 @@ GenericSignature *RequirementFailure::getSignature(ConstraintLocator *locator) {
411
405
if (isConditional ())
412
406
return Conformance->getGenericSignature ();
413
407
414
- auto path = locator->getPath ();
415
- for (auto iter = path.rbegin (); iter != path.rend (); ++iter) {
416
- const auto &elt = *iter;
417
- if (elt.getKind () == ConstraintLocator::OpenedGeneric)
418
- return elt.getGenericSignature ();
419
- }
408
+ if (auto genericElt = locator->findLast <LocatorPathElt::OpenedGeneric>())
409
+ return genericElt->getSignature ();
420
410
421
411
llvm_unreachable (" Type requirement failure should always have signature" );
422
412
}
@@ -775,16 +765,9 @@ bool NoEscapeFuncToTypeConversionFailure::diagnoseAsError() {
775
765
return true ;
776
766
}
777
767
778
- GenericTypeParamType *paramTy = nullptr ;
779
-
780
- auto path = getLocator ()->getPath ();
781
- if (!path.empty ()) {
782
- auto &last = path.back ();
783
- if (last.getKind () == ConstraintLocator::GenericParameter)
784
- paramTy = last.getGenericParameter ();
785
- }
786
-
787
- if (paramTy) {
768
+ auto *loc = getLocator ();
769
+ if (auto gpElt = loc->getLastElementAs <LocatorPathElt::GenericParameter>()) {
770
+ auto *paramTy = gpElt->getType ();
788
771
emitDiagnostic (anchor->getLoc (), diag::converting_noescape_to_type,
789
772
paramTy);
790
773
} else {
@@ -1251,14 +1234,13 @@ bool RValueTreatedAsLValueFailure::diagnoseAsError() {
1251
1234
auto argTuple = dyn_cast<TupleExpr>(argExpr);
1252
1235
diagExpr = argTuple->getElement (0 );
1253
1236
} else if (getLocator ()->getPath ().size () > 0 ) {
1254
- auto lastPathElement = getLocator ()->getPath ().back ();
1255
- assert (lastPathElement.getKind () ==
1256
- ConstraintLocator::PathElementKind::ApplyArgToParam);
1237
+ auto argElt =
1238
+ getLocator ()->castLastElementTo <LocatorPathElt::ApplyArgToParam>();
1257
1239
1258
1240
subElementDiagID = diag::cannot_pass_rvalue_inout_subelement;
1259
1241
rvalueDiagID = diag::cannot_pass_rvalue_inout;
1260
1242
if (auto argTuple = dyn_cast<TupleExpr>(argExpr))
1261
- diagExpr = argTuple->getElement (lastPathElement. getValue ());
1243
+ diagExpr = argTuple->getElement (argElt. getArgIdx ());
1262
1244
else if (auto parens = dyn_cast<ParenExpr>(argExpr))
1263
1245
diagExpr = parens->getSubExpr ();
1264
1246
} else {
@@ -1818,7 +1800,7 @@ AssignmentFailure::getMemberRef(ConstraintLocator *locator) const {
1818
1800
auto paramTy = fnType->getParams ()[0 ].getPlainType ();
1819
1801
auto keyPath = paramTy->getAnyNominal ();
1820
1802
auto memberLoc = cs.getConstraintLocator (
1821
- locator, LocatorPathElt::getKeyPathDynamicMember (keyPath));
1803
+ locator, LocatorPathElt::KeyPathDynamicMember (keyPath));
1822
1804
1823
1805
auto memberRef = getOverloadChoiceIfAvailable (memberLoc);
1824
1806
return memberRef ? Optional<OverloadChoice>(memberRef->choice ) : None;
@@ -2403,15 +2385,12 @@ bool TupleContextualFailure::diagnoseAsError() {
2403
2385
}
2404
2386
2405
2387
bool AutoClosureForwardingFailure::diagnoseAsError () {
2406
- auto path = getLocator ()->getPath ();
2407
- assert (!path.empty ());
2408
-
2409
- auto &last = path.back ();
2410
- assert (last.getKind () == ConstraintLocator::ApplyArgToParam);
2388
+ auto *loc = getLocator ();
2389
+ auto last = loc->castLastElementTo <LocatorPathElt::ApplyArgToParam>();
2411
2390
2412
2391
// We need a raw anchor here because `getAnchor()` is simplified
2413
2392
// to the argument expression.
2414
- auto *argExpr = getArgumentExpr (getRawAnchor (), last.getValue ());
2393
+ auto *argExpr = getArgumentExpr (getRawAnchor (), last.getArgIdx ());
2415
2394
emitDiagnostic (argExpr->getLoc (), diag::invalid_autoclosure_forwarding)
2416
2395
.highlight (argExpr->getSourceRange ())
2417
2396
.fixItInsertAfter (argExpr->getEndLoc (), " ()" );
@@ -3570,12 +3549,8 @@ bool KeyPathSubscriptIndexHashableFailure::diagnoseAsError() {
3570
3549
auto loc = anchor->getLoc ();
3571
3550
if (locator->isKeyPathSubscriptComponent ()) {
3572
3551
auto *KPE = cast<KeyPathExpr>(anchor);
3573
- for (auto &elt : locator->getPath ()) {
3574
- if (elt.isKeyPathComponent ()) {
3575
- loc = KPE->getComponents ()[elt.getValue ()].getLoc ();
3576
- break ;
3577
- }
3578
- }
3552
+ if (auto kpElt = locator->findFirst <LocatorPathElt::KeyPathComponent>())
3553
+ loc = KPE->getComponents ()[kpElt->getIndex ()].getLoc ();
3579
3554
}
3580
3555
3581
3556
emitDiagnostic (loc, diag::expr_keypath_subscript_index_not_hashable,
@@ -3588,13 +3563,9 @@ SourceLoc InvalidMemberRefInKeyPath::getLoc() const {
3588
3563
3589
3564
if (auto *KPE = dyn_cast<KeyPathExpr>(anchor)) {
3590
3565
auto *locator = getLocator ();
3591
- auto component =
3592
- llvm::find_if (locator->getPath (), [](const LocatorPathElt &elt) {
3593
- return elt.isKeyPathComponent ();
3594
- });
3595
-
3596
- assert (component != locator->getPath ().end ());
3597
- return KPE->getComponents ()[component->getValue ()].getLoc ();
3566
+ auto component = locator->findFirst <LocatorPathElt::KeyPathComponent>();
3567
+ assert (component);
3568
+ return KPE->getComponents ()[component->getIndex ()].getLoc ();
3598
3569
}
3599
3570
3600
3571
return anchor->getLoc ();
@@ -3681,9 +3652,8 @@ bool CollectionElementContextualFailure::diagnoseAsError() {
3681
3652
}
3682
3653
3683
3654
if (isa<DictionaryExpr>(getRawAnchor ())) {
3684
- const auto &eltLoc = locator->getPath ().back ();
3685
-
3686
- switch (eltLoc.getValue ()) {
3655
+ auto eltLoc = locator->castLastElementTo <LocatorPathElt::TupleElement>();
3656
+ switch (eltLoc.getIndex ()) {
3687
3657
case 0 : // key
3688
3658
diagnostic.emplace (emitDiagnostic (anchor->getLoc (),
3689
3659
diag::cannot_convert_dict_key, eltType,
0 commit comments