Skip to content

Commit 1fe90db

Browse files
authored
Merge pull request #37086 from ahoppen/pr-5.5/subst-generic-params-mismatch
[5.5][Sema] Fix crash when retrieving typeContextInfo for a partially bound generic type
2 parents f78fe71 + 80fa362 commit 1fe90db

File tree

4 files changed

+78
-26
lines changed

4 files changed

+78
-26
lines changed

lib/Sema/LookupVisibleDecls.cpp

Lines changed: 31 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -913,7 +913,7 @@ class OverrideFilteringConsumer : public VisibleDeclConsumer {
913913
continue;
914914
}
915915

916-
// Does it make sense to substitute types?
916+
ModuleDecl *M = DC->getParentModule();
917917

918918
// If the base type is AnyObject, we might be doing a dynamic
919919
// lookup, so the base type won't match the type of the member's
@@ -930,16 +930,35 @@ class OverrideFilteringConsumer : public VisibleDeclConsumer {
930930
(BaseTy->getNominalOrBoundGenericNominal() ||
931931
BaseTy->is<ArchetypeType>()) &&
932932
VD->getDeclContext()->isTypeContext());
933-
ModuleDecl *M = DC->getParentModule();
933+
934+
/// Substitute generic parameters in the signature of a found decl. The
935+
/// returned type can be used to determine if we have already found a
936+
/// conflicting declaration.
937+
auto substGenericArgs = [&](CanType SignatureType, ValueDecl *VD,
938+
Type BaseTy) -> CanType {
939+
if (!SignatureType || !shouldSubst) {
940+
return SignatureType;
941+
}
942+
if (auto GenFuncSignature =
943+
SignatureType->getAs<GenericFunctionType>()) {
944+
GenericEnvironment *GenEnv;
945+
if (auto *GenCtx = VD->getAsGenericContext()) {
946+
GenEnv = GenCtx->getGenericEnvironment();
947+
} else {
948+
GenEnv = DC->getGenericEnvironmentOfContext();
949+
}
950+
auto subs = BaseTy->getMemberSubstitutionMap(M, VD, GenEnv);
951+
auto CT = GenFuncSignature->substGenericArgs(subs);
952+
if (!CT->hasError()) {
953+
return CT->getCanonicalType();
954+
}
955+
}
956+
return SignatureType;
957+
};
934958

935959
auto FoundSignature = VD->getOverloadSignature();
936-
auto FoundSignatureType = VD->getOverloadSignatureType();
937-
if (FoundSignatureType && shouldSubst) {
938-
auto subs = BaseTy->getMemberSubstitutionMap(M, VD);
939-
auto CT = FoundSignatureType.subst(subs);
940-
if (!CT->hasError())
941-
FoundSignatureType = CT->getCanonicalType();
942-
}
960+
auto FoundSignatureType =
961+
substGenericArgs(VD->getOverloadSignatureType(), VD, BaseTy);
943962

944963
bool FoundConflicting = false;
945964
for (auto I = PossiblyConflicting.begin(), E = PossiblyConflicting.end();
@@ -952,14 +971,9 @@ class OverrideFilteringConsumer : public VisibleDeclConsumer {
952971
continue;
953972

954973
auto OtherSignature = OtherVD->getOverloadSignature();
955-
auto OtherSignatureType = OtherVD->getOverloadSignatureType();
956-
if (OtherSignatureType && shouldSubst) {
957-
auto ActualBaseTy = getBaseTypeForMember(M, OtherVD, BaseTy);
958-
auto subs = ActualBaseTy->getMemberSubstitutionMap(M, OtherVD);
959-
auto CT = OtherSignatureType.subst(subs);
960-
if (!CT->hasError())
961-
OtherSignatureType = CT->getCanonicalType();
962-
}
974+
auto ActualBaseTy = getBaseTypeForMember(M, OtherVD, BaseTy);
975+
auto OtherSignatureType = substGenericArgs(
976+
OtherVD->getOverloadSignatureType(), OtherVD, ActualBaseTy);
963977

964978
if (conflicting(M->getASTContext(), FoundSignature, FoundSignatureType,
965979
OtherSignature, OtherSignatureType,

test/IDE/complete_override_access_control_protocol.swift

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -177,16 +177,21 @@ public class TestPublicDE : ProtocolDPrivate, ProtocolEPublic {
177177
#^TEST_PUBLIC_DE^#
178178
}
179179

180-
// TEST_PRIVATE_DE: Begin completions, 2 items
180+
// FIXME: We should only be suggesting `collidingGeneric` once in all the test cases below.
181+
182+
// TEST_PRIVATE_DE: Begin completions, 3 items
181183
// TEST_PRIVATE_DE-DAG: Decl[InstanceMethod]/Super: func colliding() {|}{{; name=.+$}}
182184
// TEST_PRIVATE_DE-DAG: Decl[InstanceMethod]/Super: func collidingGeneric<T>(x: T) {|}{{; name=.+$}}
185+
// TEST_PRIVATE_DE-DAG: Decl[InstanceMethod]/Super: func collidingGeneric<T>(x: T) {|}{{; name=.+$}}
183186

184-
// TEST_INTERNAL_DE: Begin completions, 2 items
187+
// TEST_INTERNAL_DE: Begin completions, 3 items
185188
// TEST_INTERNAL_DE-DAG: Decl[InstanceMethod]/Super: func colliding() {|}{{; name=.+$}}
186189
// TEST_INTERNAL_DE-DAG: Decl[InstanceMethod]/Super: func collidingGeneric<T>(x: T) {|}{{; name=.+$}}
190+
// TEST_INTERNAL_DE-DAG: Decl[InstanceMethod]/Super: func collidingGeneric<T>(x: T) {|}{{; name=.+$}}
187191

188-
// TEST_PUBLIC_DE: Begin completions, 2 items
192+
// TEST_PUBLIC_DE: Begin completions, 3 items
189193
// TEST_PUBLIC_DE-DAG: Decl[InstanceMethod]/Super: public func colliding() {|}{{; name=.+$}}
194+
// TEST_PUBLIC_DE-DAG: Decl[InstanceMethod]/Super: func collidingGeneric<T>(x: T) {|}{{; name=.+$}}
190195
// TEST_PUBLIC_DE-DAG: Decl[InstanceMethod]/Super: public func collidingGeneric<T>(x: T) {|}{{; name=.+$}}
191196

192197
private class TestPrivateED : ProtocolEPublic, ProtocolDPrivate {
@@ -203,16 +208,19 @@ public class TestPublicED : ProtocolEPublic, ProtocolDPrivate {
203208
#^TEST_PUBLIC_ED^#
204209
}
205210

206-
// TEST_PRIVATE_ED: Begin completions, 2 items
211+
// TEST_PRIVATE_ED: Begin completions, 3 items
207212
// TEST_PRIVATE_ED-DAG: Decl[InstanceMethod]/Super: func colliding() {|}{{; name=.+$}}
208213
// TEST_PRIVATE_ED-DAG: Decl[InstanceMethod]/Super: func collidingGeneric<T>(x: T) {|}{{; name=.+$}}
214+
// TEST_PRIVATE_ED-DAG: Decl[InstanceMethod]/Super: func collidingGeneric<T>(x: T) {|}{{; name=.+$}}
209215

210-
// TEST_INTERNAL_ED: Begin completions, 2 items
216+
// TEST_INTERNAL_ED: Begin completions, 3 items
217+
// TEST_INTERNAL_ED-DAG: Decl[InstanceMethod]/Super: func collidingGeneric<T>(x: T) {|}{{; name=.+$}}
211218
// TEST_INTERNAL_ED-DAG: Decl[InstanceMethod]/Super: func collidingGeneric<T>(x: T) {|}{{; name=.+$}}
212219
// TEST_INTERNAL_ED-DAG: Decl[InstanceMethod]/Super: func colliding() {|}{{; name=.+$}}
213220

214-
// TEST_PUBLIC_ED: Begin completions, 2 items
221+
// TEST_PUBLIC_ED: Begin completions, 3 items
215222
// TEST_PUBLIC_ED-DAG: Decl[InstanceMethod]/Super: public func collidingGeneric<T>(x: T) {|}{{; name=.+$}}
223+
// TEST_PUBLIC_ED-DAG: Decl[InstanceMethod]/Super: func collidingGeneric<T>(x: T) {|}{{; name=.+$}}
216224
// TEST_PUBLIC_ED-DAG: Decl[InstanceMethod]/Super: public func colliding() {|}{{; name=.+$}}
217225

218226
private class TestPrivateEF : ProtocolEPublic, ProtocolFPublic {
@@ -229,14 +237,17 @@ public class TestPublicEF : ProtocolEPublic, ProtocolFPublic {
229237
#^TEST_PUBLIC_EF^#
230238
}
231239

232-
// TEST_PRIVATE_EF: Begin completions, 2 items
240+
// TEST_PRIVATE_EF: Begin completions, 3 items
233241
// TEST_PRIVATE_EF-DAG: Decl[InstanceMethod]/Super: func colliding() {|}{{; name=.+$}}
234242
// TEST_PRIVATE_EF-DAG: Decl[InstanceMethod]/Super: func collidingGeneric<T>(x: T) {|}{{; name=.+$}}
243+
// TEST_PRIVATE_EF-DAG: Decl[InstanceMethod]/Super: func collidingGeneric<T>(x: T) {|}{{; name=.+$}}
235244

236-
// TEST_INTERNAL_EF: Begin completions, 2 items
245+
// TEST_INTERNAL_EF: Begin completions, 3 items
237246
// TEST_INTERNAL_EF-DAG: Decl[InstanceMethod]/Super: func colliding() {|}{{; name=.+$}}
238247
// TEST_INTERNAL_EF-DAG: Decl[InstanceMethod]/Super: func collidingGeneric<T>(x: T) {|}{{; name=.+$}}
248+
// TEST_INTERNAL_EF-DAG: Decl[InstanceMethod]/Super: func collidingGeneric<T>(x: T) {|}{{; name=.+$}}
239249

240-
// TEST_PUBLIC_EF: Begin completions, 2 items
250+
// TEST_PUBLIC_EF: Begin completions, 3 items
241251
// TEST_PUBLIC_EF-DAG: Decl[InstanceMethod]/Super: public func colliding() {|}{{; name=.+$}}
242252
// TEST_PUBLIC_EF-DAG: Decl[InstanceMethod]/Super: public func collidingGeneric<T>(x: T) {|}{{; name=.+$}}
253+
// TEST_PUBLIC_EF-DAG: Decl[InstanceMethod]/Super: public func collidingGeneric<T>(x: T) {|}{{; name=.+$}}

test/SourceKit/TypeContextInfo/typecontext_generics.swift

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,20 @@ struct S<T> {
1919
static var instance: Self = S<T>()
2020
}
2121

22+
struct MyBinding<BindingOuter> {
23+
func someGenericFunc<BindingInner>(x: BindingInner) {}
24+
}
25+
26+
struct MyTextField<TextFieldOuter> {
27+
init<TextFieldInner>(text: MyBinding<TextFieldInner>) {}
28+
}
29+
30+
struct EncodedView {
31+
func foo(model: MyBinding<String>) {
32+
let _ = MyTextField<String>(text: model)
33+
}
34+
}
35+
2236
// RUN: %sourcekitd-test -req=typecontextinfo -pos=7:12 %s -- %s > %t.response.1
2337
// RUN: %diff -u %s.response.1 %t.response.1
2438
// RUN: %sourcekitd-test -req=typecontextinfo -pos=8:12 %s -- %s > %t.response.2
@@ -32,3 +46,6 @@ struct S<T> {
3246
// RUN: %diff -u %s.response.5 %t.response.5
3347
// RUN: %sourcekitd-test -req=typecontextinfo -pos=16:18 %s -- %s > %t.response.6
3448
// RUN: %diff -u %s.response.6 %t.response.6
49+
50+
// RUN: %sourcekitd-test -req=typecontextinfo -pos=32:43 %s -- %s > %t.response.7
51+
// RUN: %diff -u %s.response.7 %t.response.7
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
key.results: [
3+
{
4+
key.typename: "MyBinding<TextFieldInner>",
5+
key.typeusr: "$s20typecontext_generics9MyBindingVyqd__GD",
6+
key.implicitmembers: [
7+
]
8+
}
9+
]
10+
}

0 commit comments

Comments
 (0)