Skip to content

Commit dcb1db2

Browse files
committed
[AST] Don't return decls from unsatisfied conformance
When a type conditionally conforms to a protocol, it used to provide symbols from extension to that protocol. e.g.: protocol P {} extension P { func foo() {} } struct S<T> {} extension S: P where T == Int {} func test(val: S<String>) { val.#^COMPLETE^# } This should not provide `foo()` method. rdar://problem/36594731
1 parent 4d7d2ef commit dcb1db2

File tree

2 files changed

+21
-2
lines changed

2 files changed

+21
-2
lines changed

lib/Sema/LookupVisibleDecls.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -388,12 +388,18 @@ static void lookupDeclsFromProtocolsBeingConformedTo(
388388
NominalTypeDecl *CurrNominal = BaseTy->getAnyNominal();
389389
if (!CurrNominal)
390390
return;
391+
ModuleDecl *Module = FromContext->getParentModule();
391392

392393
for (auto Conformance : CurrNominal->getAllConformances()) {
393394
auto Proto = Conformance->getProtocol();
394395
if (!Proto->isAccessibleFrom(FromContext))
395396
continue;
396397

398+
// Skip unsatisfied conditional conformances.
399+
if (Conformance->getConditionalRequirementsIfAvailable() &&
400+
!Module->conformsToProtocol(BaseTy, Proto))
401+
continue;
402+
397403
DeclVisibilityKind ReasonForThisProtocol;
398404
if (Reason == DeclVisibilityKind::MemberOfCurrentNominal)
399405
ReasonForThisProtocol =

test/IDE/complete_constrained.swift

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,19 +45,31 @@ extension MyStruct {
4545
func concreteExt_None_TConformsToSomeProto<U>(_ x: U) -> Int where T: SomeProto { return 1 }
4646
}
4747

48+
protocol Proto_Int {}
49+
extension Proto_Int {
50+
func conditional_Int() -> Int { return 1 }
51+
}
52+
protocol Proto_String {}
53+
extension Proto_String {
54+
func conditional_String() -> Int { return 1 }
55+
}
56+
extension MyStruct: Proto_Int where T == Int{}
57+
extension MyStruct: Proto_String where T == String {}
58+
4859
func foo(s: MyStruct<Int>) {
4960
let _ = s.#^MYSTRUCT_INT_DOT^#
50-
// MYSTRUCT_INT_DOT: Begin completions, 6 items
61+
// MYSTRUCT_INT_DOT: Begin completions, 7 items
5162
// MYSTRUCT_INT_DOT-DAG: Keyword[self]/CurrNominal: self[#MyStruct<Int>#]; name=self
5263
// MYSTRUCT_INT_DOT-DAG: Decl[InstanceMethod]/CurrNominal: methodWithConstrainedGenericParam({#x: SomeProto#})[#Int#]; name=methodWithConstrainedGenericParam(x: SomeProto)
5364
// MYSTRUCT_INT_DOT-DAG: Decl[InstanceMethod]/CurrNominal: concreteExt_TEqInt_None()[#Int#]; name=concreteExt_TEqInt_None()
5465
// MYSTRUCT_INT_DOT-DAG: Decl[InstanceMethod]/CurrNominal: concreteExt_None_TEqInt({#(x): U#})[#Int#]; name=concreteExt_None_TEqInt(x: U)
5566
// MYSTRUCT_INT_DOT-DAG: Decl[InstanceMethod]/Super: protoExt_AssocEqInt_None()[#Int#]; name=protoExt_AssocEqInt_None()
5667
// MYSTRUCT_INT_DOT-DAG: Decl[InstanceMethod]/Super: protoExt_None_AssocEqInt({#(x): U#})[#Int#]; name=protoExt_None_AssocEqInt(x: U)
68+
// MYSTRUCT_INT_DOT-DAG: Decl[InstanceMethod]/Super: conditional_Int()[#Int#]; name=conditional_Int()
5769
// MYSTRUCT_INT_DOT: End completions
5870

5971
let _ = MyStruct<Int>.#^META_MYSTRUCT_INT_DOT^#
60-
// META_MYSTRUCT_INT_DOT: Begin completions, 10 items
72+
// META_MYSTRUCT_INT_DOT: Begin completions, 11 items
6173
// META_MYSTRUCT_INT_DOT-DAG: Keyword[self]/CurrNominal: self[#MyStruct<Int>.Type#]; name=self
6274
// META_MYSTRUCT_INT_DOT-DAG: Keyword/CurrNominal: Type[#MyStruct<Int>.Type#]; name=Type
6375
// META_MYSTRUCT_INT_DOT-DAG: Decl[TypeAlias]/CurrNominal: Assoc[#T#]; name=Assoc
@@ -68,5 +80,6 @@ func foo(s: MyStruct<Int>) {
6880
// META_MYSTRUCT_INT_DOT-DAG: Decl[InstanceMethod]/CurrNominal: concreteExt_None_TEqInt({#(self): MyStruct<Int>#})[#(U) -> Int#]; name=concreteExt_None_TEqInt(self: MyStruct<Int>)
6981
// META_MYSTRUCT_INT_DOT-DAG: Decl[InstanceMethod]/Super: protoExt_AssocEqInt_None({#(self): MyStruct<Int>#})[#() -> Int#]; name=protoExt_AssocEqInt_None(self: MyStruct<Int>)
7082
// META_MYSTRUCT_INT_DOT-DAG: Decl[InstanceMethod]/Super: protoExt_None_AssocEqInt({#(self): MyStruct<Int>#})[#(U) -> Int#]; name=protoExt_None_AssocEqInt(self: MyStruct<Int>)
83+
// META_MYSTRUCT_INT_DOT-DAG: Decl[InstanceMethod]/Super: conditional_Int({#(self): MyStruct<Int>#})[#() -> Int#]; name=conditional_Int(self: MyStruct<Int>)
7184
// META_MYSTRUCT_INT_DOT: End completions
7285
}

0 commit comments

Comments
 (0)