Skip to content

Commit 29398b1

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
1 parent ed17e9d commit 29398b1

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
@@ -3521,24 +3521,28 @@ static Type getMemberForBaseType(LookupConformanceFn lookupConformances,
35213521

35223522
// Retrieve the type witness.
35233523
auto witness =
3524-
conformance.getConcrete()->getTypeWitness(assocType, options);
3525-
if (!witness || witness->hasError())
3524+
conformance.getConcrete()->getTypeWitnessAndDecl(assocType, options);
3525+
3526+
auto witnessTy = witness.getWitnessType();
3527+
if (!witnessTy || witnessTy->hasError())
35263528
return failed();
35273529

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

3538-
if (witness->is<ErrorType>())
3542+
if (witnessTy->is<ErrorType>())
35393543
return failed();
35403544

3541-
return witness;
3545+
return witnessTy;
35423546
}
35433547

35443548
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)