Skip to content

Commit 55f812e

Browse files
authored
Merge pull request #38389 from ahoppen/pr/record-keypath-component-types-in-solution
[CodeCompletion] Record key path component types in the constraint system solution
2 parents 620a541 + 2eeff36 commit 55f812e

File tree

5 files changed

+48
-3
lines changed

5 files changed

+48
-3
lines changed

include/swift/Sema/ConstraintSystem.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1185,6 +1185,10 @@ class Solution {
11851185
/// The node -> type mappings introduced by this solution.
11861186
llvm::DenseMap<ASTNode, Type> nodeTypes;
11871187

1188+
/// The key path component types introduced by this solution.
1189+
llvm::DenseMap<std::pair<const KeyPathExpr *, unsigned>, TypeBase *>
1190+
keyPathComponentTypes;
1191+
11881192
/// Contextual types introduced by this solution.
11891193
std::vector<std::pair<ASTNode, ContextualTypeInfo>> contextualTypes;
11901194

@@ -1300,6 +1304,9 @@ class Solution {
13001304
/// Retrieve the type of the given node, as recorded in this solution.
13011305
Type getType(ASTNode node) const;
13021306

1307+
/// Retrieve the type of the \p ComponentIndex-th component in \p KP.
1308+
Type getType(const KeyPathExpr *KP, unsigned ComponentIndex) const;
1309+
13031310
/// Retrieve the type of the given node as recorded in this solution
13041311
/// and resolve all of the type variables in contains to form a fully
13051312
/// "resolved" concrete type.

lib/Sema/CSApply.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8901,8 +8901,9 @@ bool Solution::hasType(ASTNode node) const {
89018901
}
89028902

89038903
bool Solution::hasType(const KeyPathExpr *KP, unsigned ComponentIndex) const {
8904-
auto &cs = getConstraintSystem();
8905-
return cs.hasType(KP, ComponentIndex);
8904+
assert(KP && "Expected non-null key path parameter!");
8905+
return keyPathComponentTypes.find(std::make_pair(KP, ComponentIndex))
8906+
!= keyPathComponentTypes.end();
89068907
}
89078908

89088909
Type Solution::getType(ASTNode node) const {
@@ -8914,6 +8915,11 @@ Type Solution::getType(ASTNode node) const {
89148915
return cs.getType(node);
89158916
}
89168917

8918+
Type Solution::getType(const KeyPathExpr *KP, unsigned I) const {
8919+
assert(hasType(KP, I) && "Expected type to have been set!");
8920+
return keyPathComponentTypes.find(std::make_pair(KP, I))->second;
8921+
}
8922+
89178923
Type Solution::getResolvedType(ASTNode node) const {
89188924
return simplifyType(getType(node));
89198925
}

lib/Sema/CSSolver.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,9 @@ Solution ConstraintSystem::finalize() {
175175
for (auto &nodeType : NodeTypes) {
176176
solution.nodeTypes.insert(nodeType);
177177
}
178+
for (auto &keyPathComponentType : KeyPathComponentTypes) {
179+
solution.keyPathComponentTypes.insert(keyPathComponentType);
180+
}
178181

179182
// Remember contextual types.
180183
solution.contextualTypes.assign(

lib/Sema/TypeCheckCodeCompletion.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1347,7 +1347,7 @@ void KeyPathTypeCheckCompletionCallback::sawSolution(
13471347
} else {
13481348
// We are completing after a component. Get the previous component's result
13491349
// type.
1350-
BaseType = S.simplifyType(CS.getType(KeyPath, ComponentIndex - 1));
1350+
BaseType = S.simplifyType(S.getType(KeyPath, ComponentIndex - 1));
13511351
}
13521352

13531353
// If ExpectedTy is a duplicate of any other result, ignore this solution.

test/IDE/complete_sr14916.swift

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// RUN: %swift-ide-test -code-completion -code-completion-token COMPLETE -source-filename %s | %FileCheck %s
2+
3+
struct Foo {
4+
var bar: Int
5+
}
6+
7+
protocol View2 {}
8+
struct EmptyView: View2 {}
9+
10+
@resultBuilder public struct ViewBuilder2 {
11+
public static func buildBlock(_ content: EmptyView) -> EmptyView { fatalError() }
12+
}
13+
14+
public struct List2 {
15+
public init(selection: Int?, @ViewBuilder2 content: () -> EmptyView)
16+
public init(selection: String?, @ViewBuilder2 content: () -> EmptyView)
17+
}
18+
19+
func foo(kp: (Foo) -> String) {}
20+
21+
func foo() {
22+
List2 {
23+
foo(kp: \.self#^COMPLETE^#)
24+
// CHECK: Begin completions, 1 items
25+
// CHECK-NEXT: Decl[InstanceVar]/CurrNominal: .bar[#Int#];
26+
// CHECK-NEXT: End completions
27+
}
28+
.unknownMethod()
29+
}

0 commit comments

Comments
 (0)