Skip to content

Commit b5b41a5

Browse files
committed
[CS] Add specific accessors for path element info
This commit replaces the `getValue()` and `getValue2()` members on `ConstraintLocator::PathElement` with specific accessors for each expected path component kind. IMO this adds some clarity to the call sites, especially for `getArgIdx()` and `getParamIdx()`. In addition, this commit adds a private `getValue` member that can access a value at a given index, which will make it easier to add a third value in the future.
1 parent 541a717 commit b5b41a5

File tree

7 files changed

+89
-56
lines changed

7 files changed

+89
-56
lines changed

lib/Sema/CSApply.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1549,7 +1549,7 @@ namespace {
15491549
[](ConstraintLocator *locator) -> unsigned {
15501550
for (const auto &elt : locator->getPath()) {
15511551
if (elt.getKind() == ConstraintLocator::KeyPathComponent)
1552-
return elt.getValue();
1552+
return elt.getKeyPathComponentIdx();
15531553
}
15541554
llvm_unreachable("no keypath component node");
15551555
};

lib/Sema/CSDiag.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ void constraints::simplifyLocator(Expr *&anchor,
175175
case ConstraintLocator::NamedTupleElement:
176176
case ConstraintLocator::TupleElement: {
177177
// Extract tuple element.
178-
unsigned index = path[0].getValue();
178+
unsigned index = path[0].getTupleElementIdx();
179179
if (auto tupleExpr = dyn_cast<TupleExpr>(anchor)) {
180180
if (index < tupleExpr->getNumElements()) {
181181
anchor = tupleExpr->getElement(index);
@@ -197,7 +197,7 @@ void constraints::simplifyLocator(Expr *&anchor,
197197
case ConstraintLocator::ApplyArgToParam:
198198
// Extract tuple element.
199199
if (auto tupleExpr = dyn_cast<TupleExpr>(anchor)) {
200-
unsigned index = path[0].getValue();
200+
unsigned index = path[0].getArgIdx();
201201
if (index < tupleExpr->getNumElements()) {
202202
anchor = tupleExpr->getElement(index);
203203
path = path.slice(1);
@@ -207,7 +207,7 @@ void constraints::simplifyLocator(Expr *&anchor,
207207

208208
// Extract subexpression in parentheses.
209209
if (auto parenExpr = dyn_cast<ParenExpr>(anchor)) {
210-
assert(path[0].getValue() == 0);
210+
assert(path[0].getArgIdx() == 0);
211211

212212
anchor = parenExpr->getSubExpr();
213213
path = path.slice(1);
@@ -901,7 +901,7 @@ diagnoseUnresolvedDotExprTypeRequirementFailure(ConstraintSystem &cs,
901901

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

906906
Diag<Type, Type, Type, Type, StringRef> note;
907907
switch (req.getKind()) {

lib/Sema/CSDiagnostics.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -271,8 +271,8 @@ FailureDiagnostic::getFunctionArgApplyInfo(ConstraintLocator *locator) const {
271271
fnInterfaceType = resolveInterfaceType(rawFnType);
272272
}
273273

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

277277
return FunctionArgApplyInfo(argExpr, argIdx, getType(argExpr), paramIdx,
278278
fnInterfaceType, fnType, callee);
@@ -1263,7 +1263,7 @@ bool RValueTreatedAsLValueFailure::diagnoseAsError() {
12631263
subElementDiagID = diag::cannot_pass_rvalue_inout_subelement;
12641264
rvalueDiagID = diag::cannot_pass_rvalue_inout;
12651265
if (auto argTuple = dyn_cast<TupleExpr>(argExpr))
1266-
diagExpr = argTuple->getElement(lastPathElement.getValue());
1266+
diagExpr = argTuple->getElement(lastPathElement.getArgIdx());
12671267
else if (auto parens = dyn_cast<ParenExpr>(argExpr))
12681268
diagExpr = parens->getSubExpr();
12691269
} else {
@@ -2417,7 +2417,7 @@ bool AutoClosureForwardingFailure::diagnoseAsError() {
24172417

24182418
// We need a raw anchor here because `getAnchor()` is simplified
24192419
// to the argument expression.
2420-
auto *argExpr = getArgumentExpr(getRawAnchor(), last.getValue());
2420+
auto *argExpr = getArgumentExpr(getRawAnchor(), last.getArgIdx());
24212421
emitDiagnostic(argExpr->getLoc(), diag::invalid_autoclosure_forwarding)
24222422
.highlight(argExpr->getSourceRange())
24232423
.fixItInsertAfter(argExpr->getEndLoc(), "()");
@@ -3578,7 +3578,7 @@ bool KeyPathSubscriptIndexHashableFailure::diagnoseAsError() {
35783578
auto *KPE = cast<KeyPathExpr>(anchor);
35793579
for (auto &elt : locator->getPath()) {
35803580
if (elt.isKeyPathComponent()) {
3581-
loc = KPE->getComponents()[elt.getValue()].getLoc();
3581+
loc = KPE->getComponents()[elt.getKeyPathComponentIdx()].getLoc();
35823582
break;
35833583
}
35843584
}
@@ -3600,7 +3600,7 @@ SourceLoc InvalidMemberRefInKeyPath::getLoc() const {
36003600
});
36013601

36023602
assert(component != locator->getPath().end());
3603-
return KPE->getComponents()[component->getValue()].getLoc();
3603+
return KPE->getComponents()[component->getKeyPathComponentIdx()].getLoc();
36043604
}
36053605

36063606
return anchor->getLoc();
@@ -3689,7 +3689,7 @@ bool CollectionElementContextualFailure::diagnoseAsError() {
36893689
if (isa<DictionaryExpr>(getRawAnchor())) {
36903690
const auto &eltLoc = locator->getPath().back();
36913691

3692-
switch (eltLoc.getValue()) {
3692+
switch (eltLoc.getTupleElementIdx()) {
36933693
case 0: // key
36943694
diagnostic.emplace(emitDiagnostic(anchor->getLoc(),
36953695
diag::cannot_convert_dict_key, eltType,

lib/Sema/CSDiagnostics.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,7 @@ class RequirementFailure : public FailureDiagnostic {
243243
auto &last = path.back();
244244
assert(last.isTypeParameterRequirement() ||
245245
last.isConditionalRequirement());
246-
assert(static_cast<RequirementKind>(last.getValue2()) == kind);
246+
assert(last.getRequirementKind() == kind);
247247

248248
// It's possible sometimes not to have no base expression.
249249
if (!expr)
@@ -258,9 +258,7 @@ class RequirementFailure : public FailureDiagnostic {
258258
assert(!path.empty());
259259

260260
auto &requirementLoc = path.back();
261-
assert(requirementLoc.isTypeParameterRequirement() ||
262-
requirementLoc.isConditionalRequirement());
263-
return requirementLoc.getValue();
261+
return requirementLoc.getRequirementIdx();
264262
}
265263

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

lib/Sema/CSSimplify.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -769,7 +769,7 @@ getCalleeDeclAndArgs(ConstraintSystem &cs,
769769
return std::make_tuple(nullptr, /*hasAppliedSelf=*/false, argLabels,
770770
hasTrailingClosure, nullptr);
771771

772-
auto componentIndex = path[0].getValue();
772+
auto componentIndex = path[0].getKeyPathComponentIdx();
773773
if (componentIndex >= keyPath->getComponents().size())
774774
return std::make_tuple(nullptr, /*hasAppliedSelf=*/false, argLabels,
775775
hasTrailingClosure, nullptr);
@@ -2106,8 +2106,7 @@ static ConstraintFix *fixRequirementFailure(ConstraintSystem &cs, Type type1,
21062106

21072107
auto *reqLoc = cs.getConstraintLocator(anchor, path);
21082108

2109-
auto reqKind = static_cast<RequirementKind>(req.getValue2());
2110-
switch (reqKind) {
2109+
switch (req.getRequirementKind()) {
21112110
case RequirementKind::SameType: {
21122111
return SkipSameTypeRequirement::create(cs, type1, type2, reqLoc);
21132112
}
@@ -5692,7 +5691,8 @@ ConstraintSystem::simplifyKeyPathConstraint(Type keyPathTy,
56925691
if (locator->getAnchor() == keyPath
56935692
&& locator->getPath().size() <= 2
56945693
&& locator->getPath()[0].getKind() == ConstraintLocator::KeyPathComponent) {
5695-
choices[locator->getPath()[0].getValue()] = resolvedItem->Choice;
5694+
auto idx = locator->getPath()[0].getKeyPathComponentIdx();
5695+
choices[idx] = resolvedItem->Choice;
56965696
}
56975697
}
56985698

lib/Sema/ConstraintLocator.cpp

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -84,11 +84,9 @@ void ConstraintLocator::Profile(llvm::FoldingSetNodeID &id, Expr *anchor,
8484
case KeyPathRoot:
8585
case KeyPathValue:
8686
case KeyPathComponentResult:
87-
if (unsigned numValues = numNumericValuesInPathElement(elt.getKind())) {
88-
id.AddInteger(elt.getValue());
89-
if (numValues > 1)
90-
id.AddInteger(elt.getValue2());
91-
}
87+
auto numValues = numNumericValuesInPathElement(elt.getKind());
88+
for (unsigned i = 0; i < numValues; ++i)
89+
id.AddInteger(elt.getValue(i));
9290
break;
9391
}
9492
}
@@ -152,7 +150,7 @@ bool ConstraintLocator::isKeyPathSubscriptComponent() const {
152150
if (!elt.isKeyPathComponent())
153151
return false;
154152

155-
auto index = elt.getValue();
153+
auto index = elt.getKeyPathComponentIdx();
156154
auto &component = KPE->getComponents()[index];
157155
return component.getKind() == ComponentKind::Subscript ||
158156
component.getKind() == ComponentKind::UnresolvedSubscript;
@@ -255,8 +253,8 @@ void ConstraintLocator::dump(SourceManager *sm, raw_ostream &out) {
255253
break;
256254

257255
case ApplyArgToParam:
258-
out << "comparing call argument #" << llvm::utostr(elt.getValue())
259-
<< " to parameter #" << llvm::utostr(elt.getValue2());
256+
out << "comparing call argument #" << llvm::utostr(elt.getArgIdx())
257+
<< " to parameter #" << llvm::utostr(elt.getParamIdx());
260258
break;
261259

262260
case ClosureResult:
@@ -284,7 +282,7 @@ void ConstraintLocator::dump(SourceManager *sm, raw_ostream &out) {
284282
break;
285283

286284
case GenericArgument:
287-
out << "generic argument #" << llvm::utostr(elt.getValue());
285+
out << "generic argument #" << llvm::utostr(elt.getGenericArgIdx());
288286
break;
289287

290288
case InstanceType:
@@ -304,7 +302,7 @@ void ConstraintLocator::dump(SourceManager *sm, raw_ostream &out) {
304302
break;
305303

306304
case NamedTupleElement:
307-
out << "named tuple element #" << llvm::utostr(elt.getValue());
305+
out << "named tuple element #" << llvm::utostr(elt.getTupleElementIdx());
308306
break;
309307

310308
case UnresolvedMember:
@@ -332,11 +330,12 @@ void ConstraintLocator::dump(SourceManager *sm, raw_ostream &out) {
332330
break;
333331

334332
case TupleElement:
335-
out << "tuple element #" << llvm::utostr(elt.getValue());
333+
out << "tuple element #" << llvm::utostr(elt.getTupleElementIdx());
336334
break;
337335

338336
case KeyPathComponent:
339-
out << "key path component #" << llvm::utostr(elt.getValue());
337+
out << "key path component #"
338+
<< llvm::utostr(elt.getKeyPathComponentIdx());
340339
break;
341340

342341
case Requirement:
@@ -354,13 +353,15 @@ void ConstraintLocator::dump(SourceManager *sm, raw_ostream &out) {
354353
break;
355354

356355
case ConditionalRequirement:
357-
out << "conditional requirement #" << llvm::utostr(elt.getValue());
358-
dumpReqKind(static_cast<RequirementKind>(elt.getValue2()));
356+
out << "conditional requirement #"
357+
<< llvm::utostr(elt.getRequirementIdx());
358+
dumpReqKind(elt.getRequirementKind());
359359
break;
360360

361361
case TypeParameterRequirement: {
362-
out << "type parameter requirement #" << llvm::utostr(elt.getValue());
363-
dumpReqKind(static_cast<RequirementKind>(elt.getValue2()));
362+
out << "type parameter requirement #"
363+
<< llvm::utostr(elt.getRequirementIdx());
364+
dumpReqKind(elt.getRequirementKind());
364365
break;
365366
}
366367

@@ -380,7 +381,7 @@ void ConstraintLocator::dump(SourceManager *sm, raw_ostream &out) {
380381
break;
381382

382383
case SynthesizedArgument:
383-
out << "synthesized argument #" << llvm::utostr(elt.getValue());
384+
out << "synthesized argument #" << llvm::utostr(elt.getArgIdx());
384385
break;
385386

386387
case KeyPathDynamicMember:

lib/Sema/ConstraintLocator.h

Lines changed: 53 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,19 @@ class ConstraintLocator : public llvm::FoldingSetNode {
296296
return { (PathElementKind)((unsigned)storage & 0xFF), storage >> 8 };
297297
}
298298

299+
/// Retrieve a value associated with the path element.
300+
unsigned getValue(unsigned index) const {
301+
unsigned numValues = numNumericValuesInPathElement(getKind());
302+
assert(index < numValues && "Index out of range for path element value");
303+
304+
// We pack values into 16 bit components of the storage, with value0
305+
// being stored in the upper bits, valueN in the lower bits. Therefore we
306+
// need to shift out any extra values in the lower bits.
307+
auto extraValues = numValues - index - 1;
308+
auto value = decodeStorage(storage).second >> (extraValues * 16);
309+
return value & 0xFFFF;
310+
}
311+
299312
PathElement(PathElementKind kind, unsigned value)
300313
: storage(encodeStorage(kind, value)), storedKind(StoredKindAndValue)
301314
{
@@ -431,29 +444,50 @@ class ConstraintLocator : public llvm::FoldingSetNode {
431444
llvm_unreachable("Unhandled StoredKind in switch.");
432445
}
433446

434-
/// Retrieve the value associated with this path element,
435-
/// if it has one.
436-
unsigned getValue() const {
437-
unsigned numValues = numNumericValuesInPathElement(getKind());
438-
assert(numValues > 0 && "No value in path element!");
447+
/// Retrieve the index for a function argument path element.
448+
unsigned getArgIdx() const {
449+
assert((getKind() == ApplyArgToParam || isSynthesizedArgument()) &&
450+
"Not an argument path element");
451+
return getValue(0);
452+
}
439453

440-
auto value = decodeStorage(storage).second;
441-
if (numValues == 1) {
442-
return value;
443-
}
454+
/// Retrieve the parameter index for an apply-arg-to-param path element.
455+
unsigned getParamIdx() const {
456+
assert(getKind() == ApplyArgToParam && "Not a parameter application");
457+
return getValue(1);
458+
}
444459

445-
return value >> 16;
460+
/// Retrieve the index for a tuple element.
461+
unsigned getTupleElementIdx() const {
462+
assert((getKind() == TupleElement || getKind() == NamedTupleElement) &&
463+
"Not a tuple element");
464+
return getValue(0);
446465
}
447466

448-
/// Retrieve the second value associated with this path element,
449-
/// if it has one.
450-
unsigned getValue2() const {
451-
unsigned numValues = numNumericValuesInPathElement(getKind());
452-
(void)numValues;
453-
assert(numValues == 2 && "No second value in path element!");
467+
/// Retrieve the index for a key path component path element.
468+
unsigned getKeyPathComponentIdx() const {
469+
assert(isKeyPathComponent() && "Not a key path component");
470+
return getValue(0);
471+
}
472+
473+
/// Retrieve the index for a generic argument path element.
474+
unsigned getGenericArgIdx() const {
475+
assert(getKind() == GenericArgument && "Not a generic argument");
476+
return getValue(0);
477+
}
478+
479+
/// Retrieve the index for a generic requirement path element.
480+
unsigned getRequirementIdx() const {
481+
assert((isTypeParameterRequirement() || isConditionalRequirement()) &&
482+
"Not a requirement");
483+
return getValue(0);
484+
}
454485

455-
auto value = decodeStorage(storage).second;
456-
return value & 0x00FFFF;
486+
/// Retrieve the kind of generic requirement path element.
487+
RequirementKind getRequirementKind() const {
488+
assert((isTypeParameterRequirement() || isConditionalRequirement()) &&
489+
"Not a requirement");
490+
return static_cast<RequirementKind>(getValue(1));
457491
}
458492

459493
/// Retrieve the declaration for a witness path element.
@@ -522,7 +556,7 @@ class ConstraintLocator : public llvm::FoldingSetNode {
522556
/// Determine whether this element points to the contextual type
523557
/// associated with result of a single expression function.
524558
bool isResultOfSingleExprFunction() const {
525-
return getKind() == PathElementKind::ContextualType ? bool(getValue())
559+
return getKind() == PathElementKind::ContextualType ? bool(getValue(0))
526560
: false;
527561
}
528562
};

0 commit comments

Comments
 (0)