Skip to content

Commit 6aa0d5b

Browse files
authored
Merge pull request #65176 from rintaro/5.9-ide-completion-rdar107669173
[5.9][CodeCompletion] Don't take opaque types subst map into account
2 parents 8fc19f3 + f5db307 commit 6aa0d5b

File tree

3 files changed

+50
-43
lines changed

3 files changed

+50
-43
lines changed

include/swift/IDE/CompletionLookup.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -461,13 +461,17 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
461461
DynamicLookupInfo dynamicLookupInfo);
462462

463463
private:
464+
/// Normalize the type for 'isDupelicate' check.
465+
Type normalizeTypeForDuplicationCheck(Type Ty);
466+
464467
/// Returns true if duplicate checking is enabled (via
465468
/// \c shouldCheckForDuplicates) and this decl + type combination has been
466469
/// checked previously. Returns false otherwise.
467470
bool isDuplicate(const ValueDecl *D, Type Ty) {
468471
if (!CheckForDuplicates)
469472
return false;
470-
return !PreviouslySeen.insert({D, Ty}).second;
473+
return !PreviouslySeen.insert({D, normalizeTypeForDuplicationCheck(Ty)})
474+
.second;
471475
}
472476

473477
/// Returns true if duplicate checking is enabled (via
@@ -477,7 +481,8 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
477481
if (!CheckForDuplicates)
478482
return false;
479483
Type Ty = getTypeOfMember(D, dynamicLookupInfo);
480-
return !PreviouslySeen.insert({D, Ty}).second;
484+
return !PreviouslySeen.insert({D, normalizeTypeForDuplicationCheck(Ty)})
485+
.second;
481486
}
482487

483488
public:

lib/IDE/CompletionLookup.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1940,6 +1940,19 @@ void CompletionLookup::onLookupNominalTypeMembers(NominalTypeDecl *NTD,
19401940
CompletionContext->LookedupNominalTypeNames.push_back(qualifiedName);
19411941
}
19421942

1943+
Type CompletionLookup::normalizeTypeForDuplicationCheck(Type Ty) {
1944+
return Ty.transform([](Type T) {
1945+
if (auto opaque = T->getAs<OpaqueTypeArchetypeType>()) {
1946+
/// Opaque type has a _invisible_ substitution map. Since IDE can't
1947+
/// differentiate them, replace it with empty substitution map.
1948+
return OpaqueTypeArchetypeType::get(opaque->getDecl(),
1949+
opaque->getInterfaceType(),
1950+
/*Substitutions=*/{});
1951+
}
1952+
return T;
1953+
});
1954+
}
1955+
19431956
void CompletionLookup::foundDecl(ValueDecl *D, DeclVisibilityKind Reason,
19441957
DynamicLookupInfo dynamicLookupInfo) {
19451958
assert(Reason !=

test/IDE/complete_opaque_result.swift

Lines changed: 30 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,5 @@
1-
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=GLOBAL_FUNC | %FileCheck %s -check-prefix=BEGINNING_WITH_SOME
2-
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=GLOBAL_VAR | %FileCheck %s -check-prefix=BEGINNING_WITHOUT_SOME
3-
4-
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=PROTOCOL_ASSOCIATEDTYPE | %FileCheck %s -check-prefix=BEGINNING_WITHOUT_SOME
5-
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=PROTOCOL_METHOD_REQUIREMENT | %FileCheck %s -check-prefix=BEGINNING_WITHOUT_SOME
6-
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=PROTOCOL_VAR_REQUIREMENT | %FileCheck %s -check-prefix=BEGINNING_WITHOUT_SOME
7-
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=PROTOCOL_SUBSCRIPT_REQUIREMENT | %FileCheck %s -check-prefix=BEGINNING_WITHOUT_SOME
8-
9-
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=PROTOCOL_METHOD_EXTENSION | %FileCheck %s -check-prefix=BEGINNING_WITH_SOME
10-
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=PROTOCOL_VAR_EXTENSION | %FileCheck %s -check-prefix=BEGINNING_WITH_SOME
11-
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=PROTOCOL_SUBSCRIPT_EXTENSION | %FileCheck %s -check-prefix=BEGINNING_WITH_SOME
12-
13-
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=STRUCT_METHOD | %FileCheck %s -check-prefix=BEGINNING_WITH_SOME
14-
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=STRUCT_VAR | %FileCheck %s -check-prefix=BEGINNING_WITH_SOME
15-
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=STRUCT_SUBSCRIPT | %FileCheck %s -check-prefix=BEGINNING_WITH_SOME
16-
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=STRUCT_TYPEALIAS_RHS | %FileCheck %s -check-prefix=BEGINNING_WITHOUT_SOME
17-
18-
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=OVERRIDE_TestClass | %FileCheck %s -check-prefix=OVERRIDE
19-
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=OVERRIDE_TestStruct | %FileCheck %s -check-prefix=OVERRIDE
20-
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=OVERRIDE_HasTypealias | %FileCheck %s -check-prefix=OVERRIDE_HasTypealias
21-
22-
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=POSTFIX_TestProtocol_DOT | %FileCheck %s -check-prefix=POSTFIX_TestProtocol_DOT
23-
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=POSTFIX_TestProtocol_NODOT | %FileCheck %s -check-prefix=POSTFIX_TestProtocol_NODOT
24-
25-
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=OVERRIDE_TestProtocol2 | %FileCheck %s -check-prefix=OVERRIDE_TestProtocol2
26-
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=POSTFIX_ConcreteTestProtocol2 | %FileCheck %s -check-prefix=POSTFIX_ConcreteTestProtocol2
1+
// RUN: %empty-directory(%t)
2+
// RUN: %target-swift-ide-test -batch-code-completion -source-filename %s -filecheck %raw-FileCheck -completion-output-dir %t
273

284
protocol MyProtocol {
295
associatedtype Mistery
@@ -52,27 +28,27 @@ struct ConcreteMyProtocol : MyProtocol {
5228
// BEGINNING_WITHOUT_SOME-DAG: Decl[Struct]/CurrModule: MyStruct[#MyStruct#]; name=MyStruct
5329
// BEGINNING_WITHOUT_SOME-NOT: Keyword/None: some
5430

55-
func gloabalFunc() -> #^GLOBAL_FUNC^#
56-
var globalVar: #^GLOBAL_VAR^#
31+
func gloabalFunc() -> #^GLOBAL_FUNC?check=BEGINNING_WITH_SOME^#
32+
var globalVar: #^GLOBAL_VAR?check=BEGINNING_WITHOUT_SOME^#
5733

5834
protocol SomeProto {
59-
associatedtype protoAssocTy: #^PROTOCOL_ASSOCIATEDTYPE^#
60-
func protoMethodReq() -> #^PROTOCOL_METHOD_REQUIREMENT^#
61-
var protoVarReq: #^PROTOCOL_VAR_REQUIREMENT^#
62-
subscript(req: Int) -> #^PROTOCOL_SUBSCRIPT_REQUIREMENT^#
35+
associatedtype protoAssocTy: #^PROTOCOL_ASSOCIATEDTYPE?check=BEGINNING_WITHOUT_SOME^#
36+
func protoMethodReq() -> #^PROTOCOL_METHOD_REQUIREMENT?check=BEGINNING_WITHOUT_SOME^#
37+
var protoVarReq: #^PROTOCOL_VAR_REQUIREMENT?check=BEGINNING_WITHOUT_SOME^#
38+
subscript(req: Int) -> #^PROTOCOL_SUBSCRIPT_REQUIREMENT?check=BEGINNING_WITHOUT_SOME^#
6339
}
6440

6541
extension SomeProto {
66-
func protoMethodExt() -> #^PROTOCOL_METHOD_EXTENSION^#
67-
var protoVarExt: #^PROTOCOL_VAR_EXTENSION^#
68-
subscript(ext: Int) -> #^PROTOCOL_SUBSCRIPT_EXTENSION^#
42+
func protoMethodExt() -> #^PROTOCOL_METHOD_EXTENSION?check=BEGINNING_WITH_SOME^#
43+
var protoVarExt: #^PROTOCOL_VAR_EXTENSION?check=BEGINNING_WITH_SOME^#
44+
subscript(ext: Int) -> #^PROTOCOL_SUBSCRIPT_EXTENSION?check=BEGINNING_WITH_SOME^#
6945
}
7046

7147
struct SomeStruct {
72-
typealias TyAlias = #^STRUCT_TYPEALIAS_RHS^#
73-
func structMethodExt() -> #^STRUCT_METHOD^#
74-
var structVarExt: #^STRUCT_VAR^#
75-
subscript(struct: Int) -> #^STRUCT_SUBSCRIPT^#
48+
typealias TyAlias = #^STRUCT_TYPEALIAS_RHS?check=BEGINNING_WITHOUT_SOME^#
49+
func structMethodExt() -> #^STRUCT_METHOD?check=BEGINNING_WITH_SOME^#
50+
var structVarExt: #^STRUCT_VAR?check=BEGINNING_WITH_SOME^#
51+
subscript(struct: Int) -> #^STRUCT_SUBSCRIPT?check=BEGINNING_WITH_SOME^#
7652
}
7753

7854
// MARK: Conformance.
@@ -129,7 +105,7 @@ class TestClass :
129105
HasAssocWithConstraintOnProto,
130106
HasAssocWithSameTypeConstraint,
131107
HasAssocWithConformanceConstraintGeneric {
132-
#^OVERRIDE_TestClass^#
108+
#^OVERRIDE_TestClass?check=OVERRIDE^#
133109
// OVERRIDE-DAG: Decl[InstanceMethod]/Super: func returnAssocPlain() -> AssocPlain {|};
134110
// OVERRIDE-DAG: Decl[InstanceMethod]/Super: func returnAssocWithConformanceConstraint(fn: (Int) -> Int) -> some MyProtocol {|};
135111
// OVERRIDE-DAG: Decl[InstanceVar]/Super: var valAssocWithSuperClassConstraint: some MyClass;
@@ -153,7 +129,7 @@ struct TestStruct :
153129
HasAssocWithConstraintOnProto,
154130
HasAssocWithSameTypeConstraint,
155131
HasAssocWithConformanceConstraintGeneric {
156-
#^OVERRIDE_TestStruct^#
132+
#^OVERRIDE_TestStruct?check=OVERRIDE^#
157133
}
158134

159135
class HasTypealias : HasAssocWithConformanceConstraint {
@@ -222,3 +198,16 @@ func testUseTestProtocol2(value: ConcreteTestProtocol2) {
222198
// POSTFIX_ConcreteTestProtocol2-DAG: Decl[InstanceMethod]/Super: baz({#x: ConcreteTestProtocol2.Assoc#})[#(ConcreteTestProtocol2.Assoc) -> ConcreteTestProtocol2.Assoc#];
223199
// POSTFIX_ConcreteTestProtocol2-DAG: Decl[InstanceMethod]/Super: inExt()[#ConcreteTestProtocol2.Assoc#];
224200
}
201+
202+
struct Generic<T> {
203+
func returnMyProto() -> some MyProtocol { ConcreteMyProtocol() }
204+
}
205+
func overloaded() -> Generic<Int> { fatalError() }
206+
func overloaded() -> Generic<Float> { fatalError() }
207+
// Tests that ambiguous doesn't result duplicated 'returnMyProto()'.
208+
func testDupGenericReturningOpaque() {
209+
overloaded().#^DupGenericReturningOpaque^#
210+
// DupGenericReturningOpaque-NOT: returnMyProto()
211+
// DupGenericReturningOpaque: Decl[InstanceMethod]/CurrNominal: returnMyProto()[#MyProtocol#]; name=returnMyProto()
212+
// DupGenericReturningOpaque-NOT: returnMyProto()
213+
}

0 commit comments

Comments
 (0)