Skip to content

Commit a42bf06

Browse files
committed
[ConstraintSystem] Add a special locator for type of the key path expression
1 parent c34c3e3 commit a42bf06

File tree

3 files changed

+27
-3
lines changed

3 files changed

+27
-3
lines changed

lib/Sema/CSGen.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3084,7 +3084,9 @@ namespace {
30843084
} else {
30853085
// The type of key path depends on the overloads chosen for the key
30863086
// path components.
3087-
kpTy = CS.createTypeVariable(locator, TVO_CanBindToNoEscape);
3087+
auto typeLoc =
3088+
CS.getConstraintLocator(locator, ConstraintLocator::KeyPathType);
3089+
kpTy = CS.createTypeVariable(typeLoc, TVO_CanBindToNoEscape);
30883090
CS.addKeyPathConstraint(kpTy, root, rvalueBase, locator);
30893091
}
30903092
return kpTy;

lib/Sema/ConstraintLocator.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ void ConstraintLocator::Profile(llvm::FoldingSetNodeID &id, Expr *anchor,
7979
case DynamicLookupResult:
8080
case ContextualType:
8181
case SynthesizedArgument:
82+
case KeyPathType:
8283
case KeyPathRoot:
8384
case KeyPathValue:
8485
case KeyPathComponentResult:
@@ -104,6 +105,15 @@ bool ConstraintLocator::isSubscriptMemberRef() const {
104105
return path.back().getKind() == ConstraintLocator::SubscriptMember;
105106
}
106107

108+
bool ConstraintLocator::isKeyPathType() const {
109+
auto *anchor = getAnchor();
110+
auto path = getPath();
111+
// The format of locator should be `<keypath expr> -> key path type`
112+
if (!anchor || !isa<KeyPathExpr>(anchor) || path.size() != 1)
113+
return false;
114+
return path.back().getKind() == ConstraintLocator::KeyPathType;
115+
}
116+
107117
bool ConstraintLocator::isKeyPathRoot() const {
108118
auto *anchor = getAnchor();
109119
auto path = getPath();
@@ -340,6 +350,10 @@ void ConstraintLocator::dump(SourceManager *sm, raw_ostream &out) {
340350
out << "key path dynamic member lookup";
341351
break;
342352

353+
case KeyPathType:
354+
out << "key path type";
355+
break;
356+
343357
case KeyPathRoot:
344358
out << "key path root";
345359
break;

lib/Sema/ConstraintLocator.h

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,9 +129,11 @@ class ConstraintLocator : public llvm::FoldingSetNode {
129129
SynthesizedArgument,
130130
/// The member looked up via keypath based dynamic lookup.
131131
KeyPathDynamicMember,
132-
/// The root of a keypath
132+
/// The type of the key path expression
133+
KeyPathType,
134+
/// The root of a key path
133135
KeyPathRoot,
134-
/// The value of a keypath
136+
/// The value of a key path
135137
KeyPathValue,
136138
/// The result type of a key path component. Not used for subscripts.
137139
KeyPathComponentResult,
@@ -165,6 +167,7 @@ class ConstraintLocator : public llvm::FoldingSetNode {
165167
case ImplicitlyUnwrappedDisjunctionChoice:
166168
case DynamicLookupResult:
167169
case ContextualType:
170+
case KeyPathType:
168171
case KeyPathRoot:
169172
case KeyPathValue:
170173
case KeyPathComponentResult:
@@ -234,6 +237,7 @@ class ConstraintLocator : public llvm::FoldingSetNode {
234237
case ContextualType:
235238
case SynthesizedArgument:
236239
case KeyPathDynamicMember:
240+
case KeyPathType:
237241
case KeyPathRoot:
238242
case KeyPathValue:
239243
case KeyPathComponentResult:
@@ -534,6 +538,10 @@ class ConstraintLocator : public llvm::FoldingSetNode {
534538
/// e.g. `foo[0]` or `\Foo.[0]`
535539
bool isSubscriptMemberRef() const;
536540

541+
/// Determine whether give locator points to the type of the
542+
/// key path expression.
543+
bool isKeyPathType() const;
544+
537545
/// Determine whether given locator points to the keypath root
538546
bool isKeyPathRoot() const;
539547

0 commit comments

Comments
 (0)