[CodeCompletion] Fix a crash when completing the call pattern of a function that takes a parameter pack

The issue here was that we inferred the contextual type of the `Mixer` call to be the following, inferred from the result type of the partial call to the initializer of `Mixer`

```
(bound_generic_struct_type decl="swift_ide_test.(file).Mixer@/Users/alex/src/swift/test/IDE/complete_parameter_pack_as_call_argument.swift:3:8"
  (pack_type num_elements=1
    (pack_expansion_type
      (pattern=unresolved_type)
      (count=unresolved_type))))
```

Technically, the contextual type that we should have here should be `Any` (from `print`) but getting that information out of the constraint system turns out to be quite hard. https://github.com/apple/swift/pull/72568 makes some improvements in this area but in general the constraint system does not contain enough information to figure out the contextual type of an arbitrary expression.

The important thing right now is that the unresolved type in here trips the constraint system over when comparing types of code completion results with the contextual type. To prevent the crash for now, reset the expected call type if the computed type contains an unresolved type.

rdar://124166587

Co-authored-by: Pavel Yaskevich <pyaskevich@apple.com>
This commit is contained in:
Alex Hoppen
2024-03-25 21:56:12 +01:00
parent 9fca2ff0ff
commit 078e1ea0cc
2 changed files with 16 additions and 2 deletions

View File

@@ -98,8 +98,15 @@ Solution::computeSubstitutions(NullablePtr<ValueDecl> decl,
TypeSubstitutionMap subs;
for (const auto &opened : openedTypes->second) {
auto type = getFixedType(opened.second);
if (opened.first->isParameterPack() && !type->is<PackType>())
type = PackType::getSingletonPackExpansion(type);
if (opened.first->isParameterPack()) {
if (type->is<PlaceholderType>()) {
auto &ctx = type->getASTContext();
type =
PackType::get(ctx, {PackExpansionType::get(ctx.TheUnresolvedType,
ctx.TheUnresolvedType)});
} else if (!type->is<PackType>())
type = PackType::getSingletonPackExpansion(type);
}
subs[opened.first] = type;
}

View File

@@ -0,0 +1,7 @@
// RUN: %batch-code-completion
struct Mixer<each Source: Signal>: Signal {}
print(Mixer(#^COMPLETE^#))
// COMPLETE: Decl[Constructor]/CurrNominal/Flair[ArgLabels]: ['('][')'][#Mixer<repeat each Source>#];