Skip to content

Commit 11cc0e2

Browse files
committed
[CodeCompletion] Use substGenericArgs in getTypeOfMember
For a GenericFunctionType, use `substGenericArgs` instead of `subst`, as the latter would form a bad generic signature if there were UnresolvedTypes present in the base type, causing the GSB to blow up when attempting to canonicalize it. rdar://80635105
1 parent b059298 commit 11cc0e2

File tree

4 files changed

+35
-6
lines changed

4 files changed

+35
-6
lines changed

include/swift/AST/Types.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3513,7 +3513,8 @@ class GenericFunctionType final : public AnyFunctionType,
35133513

35143514
/// Substitute the given generic arguments into this generic
35153515
/// function type and return the resulting non-generic type.
3516-
FunctionType *substGenericArgs(SubstitutionMap subs);
3516+
FunctionType *substGenericArgs(SubstitutionMap subs,
3517+
SubstOptions options = None);
35173518
FunctionType *substGenericArgs(llvm::function_ref<Type(Type)> substFn) const;
35183519

35193520
void Profile(llvm::FoldingSetNodeID &ID) {

lib/AST/Type.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3657,9 +3657,10 @@ bool SILFunctionType::hasSameExtInfoAs(const SILFunctionType *otherFn) {
36573657
}
36583658

36593659
FunctionType *
3660-
GenericFunctionType::substGenericArgs(SubstitutionMap subs) {
3660+
GenericFunctionType::substGenericArgs(SubstitutionMap subs,
3661+
SubstOptions options) {
36613662
return substGenericArgs(
3662-
[=](Type t) { return t.subst(subs); });
3663+
[=](Type t) { return t.subst(subs, options); });
36633664
}
36643665

36653666
FunctionType *GenericFunctionType::substGenericArgs(

lib/IDE/CodeCompletion.cpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2601,9 +2601,16 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
26012601
// For everything else, substitute in the base type.
26022602
auto Subs = MaybeNominalType->getMemberSubstitutionMap(CurrModule, VD);
26032603

2604-
// Pass in DesugarMemberTypes so that we see the actual
2605-
// concrete type witnesses instead of type alias types.
2606-
T = T.subst(Subs, SubstFlags::DesugarMemberTypes);
2604+
// For a GenericFunctionType, we only want to substitute the
2605+
// param/result types, as otherwise we might end up with a bad generic
2606+
// signature if there are UnresolvedTypes present in the base type. Note
2607+
// we pass in DesugarMemberTypes so that we see the actual concrete type
2608+
// witnesses instead of type alias types.
2609+
if (auto *GFT = T->getAs<GenericFunctionType>()) {
2610+
T = GFT->substGenericArgs(Subs, SubstFlags::DesugarMemberTypes);
2611+
} else {
2612+
T = T.subst(Subs, SubstFlags::DesugarMemberTypes);
2613+
}
26072614
}
26082615
}
26092616

test/IDE/complete_crashes.swift

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -389,3 +389,23 @@ struct StructWithCallAsFunction: HasCallAsFunctionRequirement {
389389
}
390390
// CRASH_CALL_AS_FUNCTION: Begin completion
391391
// CRASH_CALL_AS_FUNCTION: End completions
392+
393+
// rdar://80635105
394+
protocol P_80635105 {
395+
associatedtype T
396+
}
397+
struct S_80635105<T> {}
398+
extension S_80635105 : P_80635105 {}
399+
extension P_80635105 {
400+
func foo<U : P_80635105>(_ x: U.T) where U == Self.T {}
401+
}
402+
403+
// RUN: %target-swift-ide-test -code-completion -code-completion-token=RDAR_80635105 -source-filename=%s | %FileCheck %s -check-prefix=RDAR_80635105
404+
func test_80635105() {
405+
let fn = { x in
406+
S_80635105.#^RDAR_80635105^#
407+
// RDAR_80635105: Begin completions
408+
// RDAR_80635105: Decl[InstanceMethod]/Super: foo({#(self): S_80635105<_>#})[#(P_80635105.T) -> Void#]; name=foo
409+
// RDAR_80635105: End completions
410+
}
411+
}

0 commit comments

Comments
 (0)