[CodeCompletion] Record key path component types in the constraint system solution

The added test case fails because the result builder inside `List2` is being type checked twice: Once for every overload of `List2`. Because of the way that result builders are being type checked right now, each overload of `List2` creates a new type variable for the key components in `foo` and the constraint system only keeps track of the key path component -> type mapping for the last solution discovered.

When we are now trying to look up the type of the first key path component for the first solution, the constraint system returns the type variable that is being used by the second solution and simplifying that type variable through the first solution fails because it doesn’t know about the type variable.

To fix the issue, make sure that the solutions keep track of the their type variables associated to key path components. That way the first solution owns its own key path component -> type variable mapping and is thus also able to simplify the type variable it has associated with the component.

Fixes rdar://80522345 [SR-14916]
This commit is contained in:
Alex Hoppen
2021-07-14 17:57:29 +02:00
parent b7633a1129
commit 2eeff365b1
5 changed files with 48 additions and 3 deletions

View File

@@ -8900,8 +8900,9 @@ bool Solution::hasType(ASTNode node) const {
}
bool Solution::hasType(const KeyPathExpr *KP, unsigned ComponentIndex) const {
auto &cs = getConstraintSystem();
return cs.hasType(KP, ComponentIndex);
assert(KP && "Expected non-null key path parameter!");
return keyPathComponentTypes.find(std::make_pair(KP, ComponentIndex))
!= keyPathComponentTypes.end();
}
Type Solution::getType(ASTNode node) const {
@@ -8913,6 +8914,11 @@ Type Solution::getType(ASTNode node) const {
return cs.getType(node);
}
Type Solution::getType(const KeyPathExpr *KP, unsigned I) const {
assert(hasType(KP, I) && "Expected type to have been set!");
return keyPathComponentTypes.find(std::make_pair(KP, I))->second;
}
Type Solution::getResolvedType(ASTNode node) const {
return simplifyType(getType(node));
}