Skip to content

Commit 1df6e51

Browse files
committed
AST: Only print DynamicSelfType as 'Self' for class types
This fixes a regression from the previous patch which got rid of PrintOptions::StripDynamicSelf. When printing protocol declarations with a BaseType set in PrintOptions, we can end up with a DynamicSelfType wrapping a non-class type, if the protocol requirement returned Self. Note that this changes the diagnostic for missing protocol requirements slightly; we used to sometimes refer to 'Self' even if the conforming type is not a class, which is not accepted by the type checker anyway. I believe the new diagnostics are more correct.
1 parent b8feb3d commit 1df6e51

File tree

3 files changed

+16
-8
lines changed

3 files changed

+16
-8
lines changed

lib/AST/ASTPrinter.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3643,9 +3643,11 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
36433643
auto staticSelfT = T->getSelfType();
36443644

36453645
if (auto *NTD = staticSelfT->getAnyNominal()) {
3646-
auto Name = T->getASTContext().Id_Self;
3647-
Printer.printTypeRef(T, NTD, Name);
3648-
return;
3646+
if (isa<ClassDecl>(NTD)) {
3647+
auto Name = T->getASTContext().Id_Self;
3648+
Printer.printTypeRef(T, NTD, Name);
3649+
return;
3650+
}
36493651
}
36503652

36513653
visit(staticSelfT);

test/decl/protocol/conforms/fixit_stub.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,8 @@ extension Adopter4: ProtocolWithAssocType2 { //expected-error{{type 'Adopter4' d
5555

5656

5757
protocol ProtocolWithSelfRequirement {
58-
func foo() -> Self // expected-note{{protocol requires function 'foo()' with type '() -> Self'; do you want to add a stub?}} {{47-47=\n func foo() -> Adopter5 {\n <#code#>\n \}\n}}
59-
func foo(lhs: Self, rhs: Self) -> Self //expected-note{{protocol requires function 'foo(lhs:rhs:)' with type '(Adopter5, Adopter5) -> Self'; do you want to add a stub?}} {{47-47=\n func foo(lhs: Adopter5, rhs: Adopter5) -> Adopter5 {\n <#code#>\n \}\n}}
58+
func foo() -> Self // expected-note{{protocol requires function 'foo()' with type '() -> Adopter5'; do you want to add a stub?}} {{47-47=\n func foo() -> Adopter5 {\n <#code#>\n \}\n}}
59+
func foo(lhs: Self, rhs: Self) -> Self //expected-note{{protocol requires function 'foo(lhs:rhs:)' with type '(Adopter5, Adopter5) -> Adopter5'; do you want to add a stub?}} {{47-47=\n func foo(lhs: Adopter5, rhs: Adopter5) -> Adopter5 {\n <#code#>\n \}\n}}
6060
}
6161

6262
struct Adopter5: ProtocolWithSelfRequirement { //expected-error{{type 'Adopter5' does not conform to protocol 'ProtocolWithSelfRequirement'}}
@@ -65,8 +65,8 @@ struct Adopter5: ProtocolWithSelfRequirement { //expected-error{{type 'Adopter5'
6565

6666

6767
protocol ProtocolWithSelfRequirement2 {
68-
func foo() -> Self // expected-note{{protocol requires function 'foo()' with type '() -> Self'; do you want to add a stub?}} {{51-51=\n func foo() -> Adopter6 {\n <#code#>\n \}\n}}
69-
func foo(lhs: Self, rhs: Self) -> Self //expected-note{{protocol requires function 'foo(lhs:rhs:)' with type '(Adopter6, Adopter6) -> Self'; do you want to add a stub?}} {{51-51=\n func foo(lhs: Adopter6, rhs: Adopter6) -> Adopter6 {\n <#code#>\n \}\n}}
68+
func foo() -> Self // expected-note{{protocol requires function 'foo()' with type '() -> Adopter6'; do you want to add a stub?}} {{51-51=\n func foo() -> Adopter6 {\n <#code#>\n \}\n}}
69+
func foo(lhs: Self, rhs: Self) -> Self //expected-note{{protocol requires function 'foo(lhs:rhs:)' with type '(Adopter6, Adopter6) -> Adopter6'; do you want to add a stub?}} {{51-51=\n func foo(lhs: Adopter6, rhs: Adopter6) -> Adopter6 {\n <#code#>\n \}\n}}
7070
}
7171

7272
struct Adopter6 {}

test/decl/protocol/req/dynamic_self.swift

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,15 @@
11
// RUN: %target-parse-verify-swift
22

33
protocol P {
4-
func f() -> Self // expected-note 2{{protocol requires function 'f()' with type '() -> Self'}}
4+
func f() -> Self
5+
// expected-note@-1{{protocol requires function 'f()' with type '() -> Self'}}
6+
// expected-note@-2{{protocol requires function 'f()' with type '() -> EError'}}
7+
// expected-note@-3{{protocol requires function 'f()' with type '() -> SError'}}
58
}
69

10+
// Error: Missing Self method in a class.
11+
class W : P {} // expected-error{{type 'W' does not conform to protocol 'P'}}
12+
713
// Okay: Self method in class.
814
class X : P {
915
func f() -> Self { return self }

0 commit comments

Comments
 (0)