Skip to content

Commit 98a54a1

Browse files
authored
Merge pull request #26297 from hamishknight/pass-by-value-by-name
[CS] Add specific accessors for path element info
2 parents e77b040 + 6e45ef1 commit 98a54a1

12 files changed

+614
-426
lines changed

lib/Sema/CSApply.cpp

Lines changed: 11 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1545,18 +1545,9 @@ namespace {
15451545

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

1551-
auto getKeyPathComponentIndex =
1552-
[](ConstraintLocator *locator) -> unsigned {
1553-
for (const auto &elt : locator->getPath()) {
1554-
if (elt.getKind() == ConstraintLocator::KeyPathComponent)
1555-
return elt.getValue();
1556-
}
1557-
llvm_unreachable("no keypath component node");
1558-
};
1559-
15601551
// Looks like there is a chain of implicit `subscript(dynamicMember:)`
15611552
// calls necessary to resolve a member reference.
15621553
if (overload.choice.getKind() ==
@@ -1581,8 +1572,9 @@ namespace {
15811572
// of a keypath expression e.g. `\Lens<[Int]>.count` where
15821573
// `count` is referenced using dynamic lookup.
15831574
if (auto *KPE = dyn_cast<KeyPathExpr>(anchor)) {
1584-
auto componentIdx = getKeyPathComponentIndex(memberLoc);
1585-
auto &origComponent = KPE->getComponents()[componentIdx];
1575+
auto kpElt = memberLoc->findFirst<LocatorPathElt::KeyPathComponent>();
1576+
assert(kpElt && "no keypath component node");
1577+
auto &origComponent = KPE->getComponents()[kpElt->getIndex()];
15861578

15871579
using ComponentKind = KeyPathExpr::Component::Kind;
15881580
if (origComponent.getKind() == ComponentKind::UnresolvedProperty) {
@@ -4248,7 +4240,7 @@ namespace {
42484240
Optional<SelectedOverload> foundDecl;
42494241

42504242
auto locator = cs.getConstraintLocator(
4251-
E, ConstraintLocator::PathElement::getKeyPathComponent(i));
4243+
E, LocatorPathElt::KeyPathComponent(i));
42524244
if (kind == KeyPathExpr::Component::Kind::UnresolvedSubscript) {
42534245
locator =
42544246
cs.getConstraintLocator(locator,
@@ -5030,7 +5022,7 @@ Expr *ExprRewriter::coerceTupleToTuple(Expr *expr,
50305022
auto *toElt
50315023
= coerceToType(fromElt, toEltType,
50325024
locator.withPathElement(
5033-
LocatorPathElt::getTupleElement(i)));
5025+
LocatorPathElt::TupleElement(i)));
50345026
if (!toElt)
50355027
return nullptr;
50365028

@@ -5073,7 +5065,7 @@ Expr *ExprRewriter::coerceTupleToTuple(Expr *expr,
50735065
auto *toElt
50745066
= coerceToType(fromElt, toEltType,
50755067
locator.withPathElement(
5076-
LocatorPathElt::getTupleElement(source)));
5068+
LocatorPathElt::TupleElement(source)));
50775069
if (!toElt)
50785070
return nullptr;
50795071

@@ -5393,7 +5385,7 @@ Expr *ExprRewriter::coerceCallArguments(
53935385
auto getArgLocator = [&](unsigned argIdx, unsigned paramIdx)
53945386
-> ConstraintLocatorBuilder {
53955387
return locator.withPathElement(
5396-
LocatorPathElt::getApplyArgToParam(argIdx, paramIdx));
5388+
LocatorPathElt::ApplyArgToParam(argIdx, paramIdx));
53975389
};
53985390

53995391
bool matchCanFail =
@@ -5937,8 +5929,7 @@ buildOpaqueElementConversion(ExprRewriter &rewriter, SourceRange srcRange,
59375929

59385930
Expr *conversion = buildElementConversion(
59395931
rewriter, srcRange, srcType, destType, bridged,
5940-
locator.withPathElement(
5941-
ConstraintLocator::PathElement::getGenericArgument(typeArgIndex)),
5932+
locator.withPathElement(LocatorPathElt::GenericArgument(typeArgIndex)),
59425933
opaque);
59435934

59445935
return { opaque, conversion };
@@ -5957,8 +5948,7 @@ void ExprRewriter::peepholeArrayUpcast(ArrayExpr *expr, Type toType,
59575948

59585949
// Convert the elements.
59595950
ConstraintLocatorBuilder innerLocator =
5960-
locator.withPathElement(
5961-
ConstraintLocator::PathElement::getGenericArgument(0));
5951+
locator.withPathElement(LocatorPathElt::GenericArgument(0));
59625952
for (auto &element : expr->getElements()) {
59635953
if (auto newElement = buildElementConversion(*this, expr->getLoc(),
59645954
cs.getType(element),
@@ -5985,8 +5975,7 @@ void ExprRewriter::peepholeDictionaryUpcast(DictionaryExpr *expr,
59855975
expr->setType(toType);
59865976

59875977
ConstraintLocatorBuilder valueLocator =
5988-
locator.withPathElement(
5989-
ConstraintLocator::PathElement::getGenericArgument(1));
5978+
locator.withPathElement(LocatorPathElt::GenericArgument(1));
59905979

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

lib/Sema/CSDiag.cpp

Lines changed: 13 additions & 13 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].getValue();
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].getValue();
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].getValue() == 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,
@@ -868,12 +870,10 @@ diagnoseUnresolvedDotExprTypeRequirementFailure(ConstraintSystem &cs,
868870
if (!locator)
869871
return false;
870872

871-
auto path = locator->getPath();
872-
if (path.empty())
873-
return false;
874873

875-
auto &last = path.back();
876-
if (last.getKind() != ConstraintLocator::TypeParameterRequirement)
874+
auto reqElt =
875+
locator->getLastElementAs<LocatorPathElt::TypeParameterRequirement>();
876+
if (!reqElt)
877877
return false;
878878

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

902902
auto req = member->getAsGenericContext()
903903
->getGenericSignature()
904-
->getRequirements()[last.getValue()];
904+
->getRequirements()[reqElt->getIndex()];
905905

906906
Diag<Type, Type, Type, Type, StringRef> note;
907907
switch (req.getKind()) {
@@ -1845,7 +1845,7 @@ bool FailureDiagnosis::diagnoseContextualConversionError(
18451845

18461846
ContextualFailure failure(
18471847
expr, CS, CTP, exprType, contextualType,
1848-
CS.getConstraintLocator(expr, LocatorPathElt::getContextualType()));
1848+
CS.getConstraintLocator(expr, LocatorPathElt::ContextualType()));
18491849
return failure.diagnoseAsError();
18501850
}
18511851

@@ -4793,7 +4793,7 @@ bool FailureDiagnosis::diagnoseClosureExpr(
47934793

47944794
MissingArgumentsFailure failure(
47954795
expr, CS, fnType, inferredArgCount - actualArgCount,
4796-
CS.getConstraintLocator(CE, LocatorPathElt::getContextualType()));
4796+
CS.getConstraintLocator(CE, LocatorPathElt::ContextualType()));
47974797
return failure.diagnoseAsError();
47984798
}
47994799

lib/Sema/CSDiagnostics.cpp

Lines changed: 31 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -197,21 +197,18 @@ 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 =
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)
206203
return None;
207204

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?");
211208

212209
// Form a new locator that ends at the apply-arg-to-param element, and
213210
// 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());
215212
auto *argLocator = cs.getConstraintLocator(
216213
anchor, argPath, ConstraintLocator::getSummaryFlagsForPath(argPath));
217214

@@ -271,8 +268,8 @@ FailureDiagnostic::getFunctionArgApplyInfo(ConstraintLocator *locator) const {
271268
fnInterfaceType = resolveInterfaceType(rawFnType);
272269
}
273270

274-
auto argIdx = applyArgElt->getValue();
275-
auto paramIdx = applyArgElt->getValue2();
271+
auto argIdx = applyArgElt->getArgIdx();
272+
auto paramIdx = applyArgElt->getParamIdx();
276273

277274
return FunctionArgApplyInfo(argExpr, argIdx, getType(argExpr), paramIdx,
278275
fnInterfaceType, fnType, callee);
@@ -329,14 +326,11 @@ const Requirement &RequirementFailure::getRequirement() const {
329326
ProtocolConformance *RequirementFailure::getConformanceForConditionalReq(
330327
ConstraintLocator *locator) {
331328
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())
337331
return nullptr;
338-
}
339332

333+
auto path = locator->getPath();
340334
auto *typeReqLoc = getConstraintLocator(getRawAnchor(), path.drop_back());
341335

342336
auto result = llvm::find_if(
@@ -411,12 +405,8 @@ GenericSignature *RequirementFailure::getSignature(ConstraintLocator *locator) {
411405
if (isConditional())
412406
return Conformance->getGenericSignature();
413407

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();
420410

421411
llvm_unreachable("Type requirement failure should always have signature");
422412
}
@@ -775,16 +765,9 @@ bool NoEscapeFuncToTypeConversionFailure::diagnoseAsError() {
775765
return true;
776766
}
777767

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();
788771
emitDiagnostic(anchor->getLoc(), diag::converting_noescape_to_type,
789772
paramTy);
790773
} else {
@@ -1251,14 +1234,13 @@ bool RValueTreatedAsLValueFailure::diagnoseAsError() {
12511234
auto argTuple = dyn_cast<TupleExpr>(argExpr);
12521235
diagExpr = argTuple->getElement(0);
12531236
} 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>();
12571239

12581240
subElementDiagID = diag::cannot_pass_rvalue_inout_subelement;
12591241
rvalueDiagID = diag::cannot_pass_rvalue_inout;
12601242
if (auto argTuple = dyn_cast<TupleExpr>(argExpr))
1261-
diagExpr = argTuple->getElement(lastPathElement.getValue());
1243+
diagExpr = argTuple->getElement(argElt.getArgIdx());
12621244
else if (auto parens = dyn_cast<ParenExpr>(argExpr))
12631245
diagExpr = parens->getSubExpr();
12641246
} else {
@@ -1818,7 +1800,7 @@ AssignmentFailure::getMemberRef(ConstraintLocator *locator) const {
18181800
auto paramTy = fnType->getParams()[0].getPlainType();
18191801
auto keyPath = paramTy->getAnyNominal();
18201802
auto memberLoc = cs.getConstraintLocator(
1821-
locator, LocatorPathElt::getKeyPathDynamicMember(keyPath));
1803+
locator, LocatorPathElt::KeyPathDynamicMember(keyPath));
18221804

18231805
auto memberRef = getOverloadChoiceIfAvailable(memberLoc);
18241806
return memberRef ? Optional<OverloadChoice>(memberRef->choice) : None;
@@ -2403,15 +2385,12 @@ bool TupleContextualFailure::diagnoseAsError() {
24032385
}
24042386

24052387
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>();
24112390

24122391
// We need a raw anchor here because `getAnchor()` is simplified
24132392
// to the argument expression.
2414-
auto *argExpr = getArgumentExpr(getRawAnchor(), last.getValue());
2393+
auto *argExpr = getArgumentExpr(getRawAnchor(), last.getArgIdx());
24152394
emitDiagnostic(argExpr->getLoc(), diag::invalid_autoclosure_forwarding)
24162395
.highlight(argExpr->getSourceRange())
24172396
.fixItInsertAfter(argExpr->getEndLoc(), "()");
@@ -3570,12 +3549,8 @@ bool KeyPathSubscriptIndexHashableFailure::diagnoseAsError() {
35703549
auto loc = anchor->getLoc();
35713550
if (locator->isKeyPathSubscriptComponent()) {
35723551
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();
35793554
}
35803555

35813556
emitDiagnostic(loc, diag::expr_keypath_subscript_index_not_hashable,
@@ -3588,13 +3563,9 @@ SourceLoc InvalidMemberRefInKeyPath::getLoc() const {
35883563

35893564
if (auto *KPE = dyn_cast<KeyPathExpr>(anchor)) {
35903565
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();
35983569
}
35993570

36003571
return anchor->getLoc();
@@ -3681,9 +3652,8 @@ bool CollectionElementContextualFailure::diagnoseAsError() {
36813652
}
36823653

36833654
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()) {
36873657
case 0: // key
36883658
diagnostic.emplace(emitDiagnostic(anchor->getLoc(),
36893659
diag::cannot_convert_dict_key, eltType,

lib/Sema/CSDiagnostics.h

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -237,13 +237,8 @@ class RequirementFailure : public FailureDiagnostic {
237237
assert(isConditional() || Signature);
238238
assert(AffectedDecl);
239239

240-
auto path = locator->getPath();
241-
assert(!path.empty());
242-
243-
auto &last = path.back();
244-
assert(last.isTypeParameterRequirement() ||
245-
last.isConditionalRequirement());
246-
assert(static_cast<RequirementKind>(last.getValue2()) == kind);
240+
auto reqElt = locator->castLastElementTo<LocatorPathElt::AnyRequirement>();
241+
assert(reqElt.getRequirementKind() == kind);
247242

248243
// It's possible sometimes not to have no base expression.
249244
if (!expr)
@@ -254,13 +249,9 @@ class RequirementFailure : public FailureDiagnostic {
254249
}
255250

256251
unsigned getRequirementIndex() const {
257-
auto path = getLocator()->getPath();
258-
assert(!path.empty());
259-
260-
auto &requirementLoc = path.back();
261-
assert(requirementLoc.isTypeParameterRequirement() ||
262-
requirementLoc.isConditionalRequirement());
263-
return requirementLoc.getValue();
252+
auto reqElt =
253+
getLocator()->castLastElementTo<LocatorPathElt::AnyRequirement>();
254+
return reqElt.getIndex();
264255
}
265256

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

0 commit comments

Comments
 (0)