Skip to content

Commit 27a1d5b

Browse files
committed
[ASTPrinter] Don't print inferred opaque result type witness
Opaque result type syntax is not usable except the declaration of itself. In other places, users need to let them inferred. If they are inferred associated type, they need to reffered by the name of the associated type. rdar://problem/59817674 (cherry picked from commit 29398b1)
1 parent 6916fcf commit 27a1d5b

File tree

3 files changed

+84
-9
lines changed

3 files changed

+84
-9
lines changed

lib/AST/Type.cpp

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3519,24 +3519,28 @@ static Type getMemberForBaseType(LookupConformanceFn lookupConformances,
35193519

35203520
// Retrieve the type witness.
35213521
auto witness =
3522-
conformance.getConcrete()->getTypeWitness(assocType, options);
3523-
if (!witness || witness->hasError())
3522+
conformance.getConcrete()->getTypeWitnessAndDecl(assocType, options);
3523+
3524+
auto witnessTy = witness.getWitnessType();
3525+
if (!witnessTy || witnessTy->hasError())
35243526
return failed();
35253527

35263528
// This is a hacky feature allowing code completion to migrate to
35273529
// using Type::subst() without changing output.
35283530
if (options & SubstFlags::DesugarMemberTypes) {
3529-
if (auto *aliasType =
3530-
dyn_cast<TypeAliasType>(witness.getPointer())) {
3531-
if (!aliasType->is<ErrorType>())
3532-
witness = aliasType->getSinglyDesugaredType();
3533-
}
3531+
if (auto *aliasType = dyn_cast<TypeAliasType>(witnessTy.getPointer()))
3532+
witnessTy = aliasType->getSinglyDesugaredType();
3533+
3534+
// Another hack. If the type witness is a opaque result type. They can
3535+
// only be referred using the name of the associated type.
3536+
if (witnessTy->is<OpaqueTypeArchetypeType>())
3537+
witnessTy = witness.getWitnessDecl()->getDeclaredInterfaceType();
35343538
}
35353539

3536-
if (witness->is<ErrorType>())
3540+
if (witnessTy->is<ErrorType>())
35373541
return failed();
35383542

3539-
return witness;
3543+
return witnessTy;
35403544
}
35413545

35423546
return failed();

test/IDE/complete_opaque_result.swift

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@
2222
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=POSTFIX_TestProtocol_DOT | %FileCheck %s -check-prefix=POSTFIX_TestProtocol_DOT
2323
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=POSTFIX_TestProtocol_NODOT | %FileCheck %s -check-prefix=POSTFIX_TestProtocol_NODOT
2424

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
27+
2528
protocol MyProtocol {
2629
associatedtype Mistery
2730
}
@@ -200,3 +203,36 @@ func postfixExpr() {
200203
// POSTFIX_TestProtocol_NODOT-DAG: BuiltinOperator/None: = {#TestProtocol#}[#Void#]; name={{.*$}}
201204
// POSTFIX_TestProtocol_NODOT-DAG: Keyword[self]/CurrNominal: .self[#TestProtocol#]; name={{.*$}}
202205
// POSTFIX_TestProtocol_NODOT-DAG: End completions
206+
207+
protocol TestProtocol2 {
208+
associatedtype Assoc: Comparable
209+
func foo() -> Assoc
210+
func bar() -> Assoc
211+
func baz(x: @autoclosure () -> Assoc) -> (Assoc) -> Assoc
212+
}
213+
extension TestProtocol2 {
214+
func inExt() -> Assoc { fatalError() }
215+
}
216+
struct ConcreteTestProtocol2: TestProtocol2 {
217+
func foo() -> some Comparable { 1 }
218+
#^OVERRIDE_TestProtocol2^#
219+
// OVERRIDE_TestProtocol2: Begin completions
220+
// OVERRIDE_TestProtocol2-NOT: foo()
221+
// OVERRIDE_TestProtocol2-NOT: inExt()
222+
// OVERRIDE_TestProtocol2-DAG: Decl[InstanceMethod]/Super: func bar() -> Assoc {|};
223+
// OVERRIDE_TestProtocol2-DAG: Decl[InstanceMethod]/Super: func baz(x: @autoclosure () -> Assoc) -> (Assoc) -> Assoc {|};
224+
// OVERRIDE_TestProtocol2-DAG: Decl[AssociatedType]/Super: typealias Assoc = {#(Type)#};
225+
// OVERRIDE_TestProtocol2-NOT: foo()
226+
// OVERRIDE_TestProtocol2-NOT: inExt()
227+
// OVERRIDE_TestProtocol2: End completions
228+
}
229+
func testUseTestProtocol2(value: ConcreteTestProtocol2) {
230+
value.#^POSTFIX_ConcreteTestProtocol2^#
231+
// POSTFIX_ConcreteTestProtocol2: Begin completions
232+
// POSTFIX_ConcreteTestProtocol2-DAG: Keyword[self]/CurrNominal: self[#ConcreteTestProtocol2#];
233+
// POSTFIX_ConcreteTestProtocol2-DAG: Decl[InstanceMethod]/CurrNominal: foo()[#Comparable#];
234+
// POSTFIX_ConcreteTestProtocol2-DAG: Decl[InstanceMethod]/Super: bar()[#ConcreteTestProtocol2.Assoc#];
235+
// POSTFIX_ConcreteTestProtocol2-DAG: Decl[InstanceMethod]/Super: baz({#x: ConcreteTestProtocol2.Assoc#})[#(ConcreteTestProtocol2.Assoc) -> ConcreteTestProtocol2.Assoc#];
236+
// POSTFIX_ConcreteTestProtocol2-DAG: Decl[InstanceMethod]/Super: inExt()[#ConcreteTestProtocol2.Assoc#];
237+
// POSTFIX_ConcreteTestProtocol2: End completions
238+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
public protocol P {
2+
associatedtype Assoc
3+
func foo() -> Assoc
4+
}
5+
extension P {
6+
func bar() -> Assoc { fatalError() }
7+
}
8+
9+
public struct MyStruct: P {
10+
public func foo() -> some Comparable { 1 }
11+
}
12+
func test(value: MyStruct) {
13+
value.foo()
14+
value.bar()
15+
}
16+
17+
// RUN: %sourcekitd-test -req=cursor -pos=13:9 %s -- %s -module-name MyModule | %FileCheck --check-prefix=OPAQUE %s
18+
// RUN: %sourcekitd-test -req=cursor -pos=14:9 %s -- %s -module-name MyModule | %FileCheck --check-prefix=ASSOC %s
19+
20+
// OPAQUE: foo()
21+
// OPAQUE-NEXT: s:8MyModule0A6StructV3fooQryF
22+
// OPAQUE-NEXT: (MyStruct) -> () -> some Comparable
23+
// OPAQUE-NEXT: $sQrycD
24+
// OPAQUE-NEXT: <Container>$s8MyModule0A6StructVD</Container>
25+
// OPAQUE-NEXT: <Declaration>public func foo() -&gt; some <Type usr="s:SL">Comparable</Type></Declaration>
26+
// OPAQUE-NEXT: <decl.function.method.instance><syntaxtype.keyword>public</syntaxtype.keyword> <syntaxtype.keyword>func</syntaxtype.keyword> <decl.name>foo</decl.name>() -&gt; <decl.function.returntype><syntaxtype.keyword>some</syntaxtype.keyword> <ref.protocol usr="s:SL">Comparable</ref.protocol></decl.function.returntype></decl.function.method.instance>
27+
28+
29+
// ASSOC: bar()
30+
// ASSOC-NEXT: s:8MyModule1PPAAE3bar5AssocQzyF
31+
// ASSOC-NEXT: <Self where Self : P> (Self) -> () -> Self.Assoc
32+
// ASSOC-NEXT: $s5AssocQzycD
33+
// ASSOC-NEXT: <Container>$s8MyModule0A6StructVD</Container>
34+
// ASSOC-NEXT: <Declaration>func bar() -&gt; <Type usr="s:8MyModule0A6StructV5Assoca">Assoc</Type></Declaration>
35+
// ASSOC-NEXT: <decl.function.method.instance><syntaxtype.keyword>func</syntaxtype.keyword> <decl.name>bar</decl.name>() -&gt; <decl.function.returntype><ref.typealias usr="s:8MyModule0A6StructV5Assoca">Assoc</ref.typealias></decl.function.returntype></decl.function.method.instance>

0 commit comments

Comments
 (0)