Skip to content

Commit 0804105

Browse files
committed
[CodeCompletion] Don't fail in ArgumentCompltion if no overload was found
1 parent 2392117 commit 0804105

File tree

1 file changed

+43
-36
lines changed

1 file changed

+43
-36
lines changed

lib/IDE/ArgumentCompletion.cpp

Lines changed: 43 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -104,34 +104,39 @@ void ArgumentTypeCheckCompletionCallback::sawSolutionImpl(const Solution &S) {
104104

105105
auto *CallLocator = CS.getConstraintLocator(ParentCall);
106106
auto *CalleeLocator = S.getCalleeLocator(CallLocator);
107-
auto SelectedOverload = S.getOverloadChoiceIfAvailable(CalleeLocator);
108-
if (!SelectedOverload) {
109-
return;
110-
}
111-
112-
Type CallBaseTy = SelectedOverload->choice.getBaseType();
113-
if (CallBaseTy) {
114-
CallBaseTy = S.simplifyType(CallBaseTy)->getRValueType();
115-
}
107+
ValueDecl *FuncD = nullptr;
108+
Type FuncTy;
109+
Type CallBaseTy;
110+
// If we are calling a closure in-place there is no overload choice, but we
111+
// still have all the other required information (like the argument's
112+
// expected type) to provide useful code completion results.
113+
if (auto SelectedOverload = S.getOverloadChoiceIfAvailable(CalleeLocator)) {
114+
115+
CallBaseTy = SelectedOverload->choice.getBaseType();
116+
if (CallBaseTy) {
117+
CallBaseTy = S.simplifyType(CallBaseTy)->getRValueType();
118+
}
116119

117-
ValueDecl *FuncD = SelectedOverload->choice.getDeclOrNull();
118-
Type FuncTy = S.simplifyTypeForCodeCompletion(SelectedOverload->openedType);
119-
120-
// For completion as the arg in a call to the implicit [keypath: _] subscript
121-
// the solver can't know what kind of keypath is expected without an actual
122-
// argument (e.g. a KeyPath vs WritableKeyPath) so it ends up as a hole.
123-
// Just assume KeyPath so we show the expected keypath's root type to users
124-
// rather than '_'.
125-
if (SelectedOverload->choice.getKind() ==
126-
OverloadChoiceKind::KeyPathApplication) {
127-
auto Params = FuncTy->getAs<AnyFunctionType>()->getParams();
128-
if (Params.size() == 1 && Params[0].getPlainType()->is<UnresolvedType>()) {
129-
auto *KPDecl = CS.getASTContext().getKeyPathDecl();
130-
Type KPTy =
131-
KPDecl->mapTypeIntoContext(KPDecl->getDeclaredInterfaceType());
132-
Type KPValueTy = KPTy->castTo<BoundGenericType>()->getGenericArgs()[1];
133-
KPTy = BoundGenericType::get(KPDecl, Type(), {CallBaseTy, KPValueTy});
134-
FuncTy = FunctionType::get({Params[0].withType(KPTy)}, KPValueTy);
120+
FuncD = SelectedOverload->choice.getDeclOrNull();
121+
FuncTy = S.simplifyTypeForCodeCompletion(SelectedOverload->openedType);
122+
123+
// For completion as the arg in a call to the implicit [keypath: _]
124+
// subscript the solver can't know what kind of keypath is expected without
125+
// an actual argument (e.g. a KeyPath vs WritableKeyPath) so it ends up as a
126+
// hole. Just assume KeyPath so we show the expected keypath's root type to
127+
// users rather than '_'.
128+
if (SelectedOverload->choice.getKind() ==
129+
OverloadChoiceKind::KeyPathApplication) {
130+
auto Params = FuncTy->getAs<AnyFunctionType>()->getParams();
131+
if (Params.size() == 1 &&
132+
Params[0].getPlainType()->is<UnresolvedType>()) {
133+
auto *KPDecl = CS.getASTContext().getKeyPathDecl();
134+
Type KPTy =
135+
KPDecl->mapTypeIntoContext(KPDecl->getDeclaredInterfaceType());
136+
Type KPValueTy = KPTy->castTo<BoundGenericType>()->getGenericArgs()[1];
137+
KPTy = BoundGenericType::get(KPDecl, Type(), {CallBaseTy, KPValueTy});
138+
FuncTy = FunctionType::get({Params[0].withType(KPTy)}, KPValueTy);
139+
}
135140
}
136141
}
137142

@@ -244,15 +249,17 @@ void ArgumentTypeCheckCompletionCallback::deliverResults(
244249
SemanticContext = SemanticContextKind::CurrentModule;
245250
}
246251
}
247-
if (Result.IsSubscript) {
248-
assert(SemanticContext != SemanticContextKind::None);
249-
auto *SD = dyn_cast_or_null<SubscriptDecl>(Result.FuncD);
250-
Lookup.addSubscriptCallPattern(Result.FuncTy->getAs<AnyFunctionType>(),
251-
SD, SemanticContext);
252-
} else {
253-
auto *FD = dyn_cast_or_null<AbstractFunctionDecl>(Result.FuncD);
254-
Lookup.addFunctionCallPattern(Result.FuncTy->getAs<AnyFunctionType>(),
255-
FD, SemanticContext);
252+
if (Result.FuncTy) {
253+
if (Result.IsSubscript) {
254+
assert(SemanticContext != SemanticContextKind::None);
255+
auto *SD = dyn_cast_or_null<SubscriptDecl>(Result.FuncD);
256+
Lookup.addSubscriptCallPattern(
257+
Result.FuncTy->getAs<AnyFunctionType>(), SD, SemanticContext);
258+
} else {
259+
auto *FD = dyn_cast_or_null<AbstractFunctionDecl>(Result.FuncD);
260+
Lookup.addFunctionCallPattern(Result.FuncTy->getAs<AnyFunctionType>(),
261+
FD, SemanticContext);
262+
}
256263
}
257264
}
258265
Lookup.setHaveLParen(false);

0 commit comments

Comments
 (0)