Skip to content

Commit 2ab53b5

Browse files
authored
Merge pull request #4585 from rintaro/nowitness-access
[Sema] Emit only "public" access modifier in fix-it for missing witness
2 parents 24f422e + 3be5e89 commit 2ab53b5

File tree

2 files changed

+77
-22
lines changed

2 files changed

+77
-22
lines changed

lib/Sema/TypeCheckProtocol.cpp

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2032,9 +2032,19 @@ static void diagnoseNoWitness(ValueDecl *Requirement, Type RequirementType,
20322032
std::string FixitString;
20332033
llvm::raw_string_ostream FixitStream(FixitString);
20342034
ExtraIndentStreamPrinter Printer(FixitStream, StubIndent);
2035+
Printer.printNewline();
2036+
2037+
Accessibility Access = std::min(
2038+
/* Access of the context */
2039+
Conformance->getDeclContext()
2040+
->getAsGenericTypeOrGenericTypeExtensionContext()->getFormalAccess(),
2041+
/* Access of the protocol */
2042+
Requirement->getDeclContext()
2043+
->getAsProtocolOrProtocolExtensionContext()->getFormalAccess());
2044+
if (Access == Accessibility::Public)
2045+
Printer << "public ";
20352046

20362047
if (auto MissingTypeWitness = dyn_cast<AssociatedTypeDecl>(Requirement)) {
2037-
Printer.printNewline();
20382048
Printer << "typealias " << MissingTypeWitness->getName() << " = <#type#>";
20392049
Printer << "\n";
20402050

@@ -2045,6 +2055,7 @@ static void diagnoseNoWitness(ValueDecl *Requirement, Type RequirementType,
20452055

20462056
PrintOptions Options = PrintOptions::printForDiagnostics();
20472057
Options.AccessibilityFilter = Accessibility::Private;
2058+
Options.PrintAccessibility = false;
20482059
Options.FunctionBody = [](const ValueDecl *VD) { return "<#code#>"; };
20492060
if (isa<ClassDecl>(Conformance->getDeclContext())) {
20502061
Type SelfType = Conformance->getDeclContext()->getSelfTypeInContext();
@@ -2062,7 +2073,6 @@ static void diagnoseNoWitness(ValueDecl *Requirement, Type RequirementType,
20622073
Options.PrintPropertyAccessors = false;
20632074
}
20642075

2065-
Printer.printNewline();
20662076
Requirement->print(Printer, Options);
20672077
Printer << "\n";
20682078

test/decl/protocol/conforms/fixit_stub.swift

Lines changed: 65 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
// RUN: %target-parse-verify-swift
22

33
protocol Protocol1 {
4-
func foo(arg1: Int, arg2: String) -> String // expected-note{{protocol requires function 'foo(arg1:arg2:)' with type '(Int, String) -> String'; do you want to add a stub?}} {{27-27=\n internal func foo(arg1: Int, arg2: String) -> String {\n <#code#>\n \}\n}}
5-
func bar() throws -> String // expected-note{{protocol requires function 'bar()' with type '() throws -> String'; do you want to add a stub?}} {{27-27=\n internal func bar() throws -> String {\n <#code#>\n \}\n}}
6-
init(arg: Int) // expected-note{{protocol requires initializer 'init(arg:)' with type '(arg: Int)'; do you want to add a stub?}} {{27-27=\n internal init(arg: Int) {\n <#code#>\n \}\n}}
7-
var baz: Int { get } // expected-note{{protocol requires property 'baz' with type 'Int'; do you want to add a stub?}} {{27-27=\n internal var baz: Int\n}}
8-
var baz2: Int { get set } // expected-note{{protocol requires property 'baz2' with type 'Int'; do you want to add a stub?}} {{27-27=\n internal var baz2: Int\n}}
9-
subscript(arg: Int) -> String { get } //expected-note{{rotocol requires subscript with type '(Int) -> String'; do you want to add a stub?}} {{27-27=\n internal subscript(arg: Int) -> String {\n <#code#>\n \}\n}}
10-
subscript(arg1: Int, arg2: Int) -> String { get set } //expected-note{{protocol requires subscript with type '(Int, Int) -> String'; do you want to add a stub?}} {{27-27=\n internal subscript(arg1: Int, arg2: Int) -> String {\n get {\n <#code#>\n \}\n set {\n <#code#>\n \}\n \}\n}}
4+
func foo(arg1: Int, arg2: String) -> String // expected-note{{protocol requires function 'foo(arg1:arg2:)' with type '(Int, String) -> String'; do you want to add a stub?}} {{27-27=\n func foo(arg1: Int, arg2: String) -> String {\n <#code#>\n \}\n}}
5+
func bar() throws -> String // expected-note{{protocol requires function 'bar()' with type '() throws -> String'; do you want to add a stub?}} {{27-27=\n func bar() throws -> String {\n <#code#>\n \}\n}}
6+
init(arg: Int) // expected-note{{protocol requires initializer 'init(arg:)' with type '(arg: Int)'; do you want to add a stub?}} {{27-27=\n init(arg: Int) {\n <#code#>\n \}\n}}
7+
var baz: Int { get } // expected-note{{protocol requires property 'baz' with type 'Int'; do you want to add a stub?}} {{27-27=\n var baz: Int\n}}
8+
var baz2: Int { get set } // expected-note{{protocol requires property 'baz2' with type 'Int'; do you want to add a stub?}} {{27-27=\n var baz2: Int\n}}
9+
subscript(arg: Int) -> String { get } //expected-note{{rotocol requires subscript with type '(Int) -> String'; do you want to add a stub?}} {{27-27=\n subscript(arg: Int) -> String {\n <#code#>\n \}\n}}
10+
subscript(arg1: Int, arg2: Int) -> String { get set } //expected-note{{protocol requires subscript with type '(Int, Int) -> String'; do you want to add a stub?}} {{27-27=\n subscript(arg1: Int, arg2: Int) -> String {\n get {\n <#code#>\n \}\n set {\n <#code#>\n \}\n \}\n}}
1111
}
1212

1313
class Adopter: Protocol1 { // expected-error{{type 'Adopter' does not conform to protocol 'Protocol1'}} expected-note{{candidate has non-matching type '()'}}
@@ -16,13 +16,13 @@ class Adopter: Protocol1 { // expected-error{{type 'Adopter' does not conform to
1616

1717

1818
protocol Protocol2 {
19-
func foo(arg1: Int, arg2: String) -> String // expected-note{{protocol requires function 'foo(arg1:arg2:)' with type '(Int, String) -> String'; do you want to add a stub?}} {{32-32=\n internal func foo(arg1: Int, arg2: String) -> String {\n <#code#>\n \}\n}}
20-
func bar() throws -> String // expected-note{{protocol requires function 'bar()' with type '() throws -> String'; do you want to add a stub?}} {{32-32=\n internal func bar() throws -> String {\n <#code#>\n \}\n}}
21-
init(arg: Int) // expected-note{{protocol requires initializer 'init(arg:)' with type '(arg: Int)'; do you want to add a stub?}} {{32-32=\n internal init(arg: Int) {\n <#code#>\n \}\n}}
22-
var baz: Int { get } // expected-note{{protocol requires property 'baz' with type 'Int'; do you want to add a stub?}} {{32-32=\n internal var baz: Int {\n <#code#>\n \}\n}}
23-
var baz2: Int { get set } // expected-note{{protocol requires property 'baz2' with type 'Int'; do you want to add a stub?}} {{32-32=\n internal var baz2: Int {\n get {\n <#code#>\n \}\n set {\n <#code#>\n \}\n \}\n}}
24-
subscript(arg: Int) -> String { get } //expected-note{{rotocol requires subscript with type '(Int) -> String'; do you want to add a stub?}} {{32-32=\n internal subscript(arg: Int) -> String {\n <#code#>\n \}\n}}
25-
subscript(arg1: Int, arg2: Int) -> String { get set } //expected-note{{protocol requires subscript with type '(Int, Int) -> String'; do you want to add a stub?}} {{32-32=\n internal subscript(arg1: Int, arg2: Int) -> String {\n get {\n <#code#>\n \}\n set {\n <#code#>\n \}\n \}\n}}
19+
func foo(arg1: Int, arg2: String) -> String // expected-note{{protocol requires function 'foo(arg1:arg2:)' with type '(Int, String) -> String'; do you want to add a stub?}} {{32-32=\n func foo(arg1: Int, arg2: String) -> String {\n <#code#>\n \}\n}}
20+
func bar() throws -> String // expected-note{{protocol requires function 'bar()' with type '() throws -> String'; do you want to add a stub?}} {{32-32=\n func bar() throws -> String {\n <#code#>\n \}\n}}
21+
init(arg: Int) // expected-note{{protocol requires initializer 'init(arg:)' with type '(arg: Int)'; do you want to add a stub?}} {{32-32=\n init(arg: Int) {\n <#code#>\n \}\n}}
22+
var baz: Int { get } // expected-note{{protocol requires property 'baz' with type 'Int'; do you want to add a stub?}} {{32-32=\n var baz: Int {\n <#code#>\n \}\n}}
23+
var baz2: Int { get set } // expected-note{{protocol requires property 'baz2' with type 'Int'; do you want to add a stub?}} {{32-32=\n var baz2: Int {\n get {\n <#code#>\n \}\n set {\n <#code#>\n \}\n \}\n}}
24+
subscript(arg: Int) -> String { get } //expected-note{{rotocol requires subscript with type '(Int) -> String'; do you want to add a stub?}} {{32-32=\n subscript(arg: Int) -> String {\n <#code#>\n \}\n}}
25+
subscript(arg1: Int, arg2: Int) -> String { get set } //expected-note{{protocol requires subscript with type '(Int, Int) -> String'; do you want to add a stub?}} {{32-32=\n subscript(arg1: Int, arg2: Int) -> String {\n get {\n <#code#>\n \}\n set {\n <#code#>\n \}\n \}\n}}
2626
}
2727

2828
class Adopter2 {} // expected-note{{candidate has non-matching type '()'}}
@@ -54,8 +54,8 @@ extension Adopter4: ProtocolWithAssocType2 { //expected-error{{type 'Adopter4' d
5454

5555

5656
protocol ProtocolWithSelfRequirement {
57-
func foo() -> Self // expected-note{{protocol requires function 'foo()' with type '() -> Self'; do you want to add a stub?}} {{47-47=\n internal func foo() -> Adopter5 {\n <#code#>\n \}\n}}
58-
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 internal func foo(lhs: Adopter5, rhs: Adopter5) -> Adopter5 {\n <#code#>\n \}\n}}
57+
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}}
58+
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}}
5959
}
6060

6161
struct Adopter5: ProtocolWithSelfRequirement { //expected-error{{type 'Adopter5' does not conform to protocol 'ProtocolWithSelfRequirement'}}
@@ -64,8 +64,8 @@ struct Adopter5: ProtocolWithSelfRequirement { //expected-error{{type 'Adopter5'
6464

6565

6666
protocol ProtocolWithSelfRequirement2 {
67-
func foo() -> Self // expected-note{{protocol requires function 'foo()' with type '() -> Self'; do you want to add a stub?}} {{51-51=\n internal func foo() -> Adopter6 {\n <#code#>\n \}\n}}
68-
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 internal func foo(lhs: Adopter6, rhs: Adopter6) -> Adopter6 {\n <#code#>\n \}\n}}
67+
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}}
68+
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}}
6969
}
7070

7171
struct Adopter6 {}
@@ -75,9 +75,54 @@ extension Adopter6: ProtocolWithSelfRequirement2 { //expected-error{{type 'Adopt
7575

7676

7777
protocol ProtocolWithSelfRequirement3 {
78-
func foo() -> Self // expected-note{{protocol requires function 'foo()' with type '() -> Self'; do you want to add a stub?}} {{47-47=\n internal func foo() -> Self {\n <#code#>\n \}\n}}
79-
func foo(lhs: Self, rhs: Self) -> Self //expected-note{{protocol requires function 'foo(lhs:rhs:)' with type '(Adopter7, Adopter7) -> Self'; do you want to add a stub?}} {{47-47=\n internal func foo(lhs: Adopter7, rhs: Adopter7) -> Self {\n <#code#>\n \}\n}}
78+
func foo() -> Self // expected-note{{protocol requires function 'foo()' with type '() -> Self'; do you want to add a stub?}} {{47-47=\n func foo() -> Self {\n <#code#>\n \}\n}}
79+
func foo(lhs: Self, rhs: Self) -> Self //expected-note{{protocol requires function 'foo(lhs:rhs:)' with type '(Adopter7, Adopter7) -> Self'; do you want to add a stub?}} {{47-47=\n func foo(lhs: Adopter7, rhs: Adopter7) -> Self {\n <#code#>\n \}\n}}
8080
}
8181

8282
class Adopter7: ProtocolWithSelfRequirement3 { //expected-error{{type 'Adopter7' does not conform to protocol 'ProtocolWithSelfRequirement3'}}
8383
}
84+
85+
86+
public protocol ProtocolWithPublicAccess1 {
87+
func foo() // expected-note{{protocol requires function 'foo()' with type '() -> ()'; do you want to add a stub?}} {{71-71=\n func foo() {\n <#code#>\n \}\n}}
88+
}
89+
public protocol ProtocolWithPublicAccess2 {
90+
associatedtype AssocType //expected-note{{protocol requires nested type 'AssocType'}} {71-71=\n typealias AssocType = <#type#>\n}}
91+
}
92+
class Adopter8: ProtocolWithPublicAccess1, ProtocolWithPublicAccess2 {
93+
// expected-error@-1{{type 'Adopter8' does not conform to protocol 'ProtocolWithPublicAccess1'}}
94+
// expected-error@-2{{type 'Adopter8' does not conform to protocol 'ProtocolWithPublicAccess2'}}
95+
}
96+
97+
public protocol ProtocolWithPublicAccess3 {
98+
func foo() // expected-note{{protocol requires function 'foo()' with type '() -> ()'; do you want to add a stub?}} {{78-78=\n public func foo() {\n <#code#>\n \}\n}}
99+
}
100+
public protocol ProtocolWithPublicAccess4 {
101+
associatedtype AssocType //expected-note{{protocol requires nested type 'AssocType'}} {{78-78=\n public typealias AssocType = <#type#>\n}}
102+
}
103+
public class Adopter9: ProtocolWithPublicAccess3, ProtocolWithPublicAccess4 {
104+
// expected-error@-1{{type 'Adopter9' does not conform to protocol 'ProtocolWithPublicAccess3'}}
105+
// expected-error@-2{{type 'Adopter9' does not conform to protocol 'ProtocolWithPublicAccess4'}}
106+
}
107+
108+
private protocol ProtocolWithPrivateAccess1 {
109+
func foo() // expected-note{{protocol requires function 'foo()' with type '() -> ()'; do you want to add a stub?}} {{74-74=\n func foo() {\n <#code#>\n \}\n}}
110+
}
111+
private protocol ProtocolWithPrivateAccess2 {
112+
associatedtype AssocType //expected-note{{protocol requires nested type 'AssocType'}} {{74-74=\n typealias AssocType = <#type#>\n}}
113+
}
114+
class Adopter10: ProtocolWithPrivateAccess1, ProtocolWithPrivateAccess2 {
115+
// expected-error@-1{{type 'Adopter10' does not conform to protocol 'ProtocolWithPrivateAccess1'}}
116+
// expected-error@-2{{type 'Adopter10' does not conform to protocol 'ProtocolWithPrivateAccess2'}}
117+
}
118+
119+
private protocol ProtocolWithPrivateAccess3 {
120+
func foo() // expected-note{{protocol requires function 'foo()' with type '() -> ()'; do you want to add a stub?}} {{81-81=\n func foo() {\n <#code#>\n \}\n}}
121+
}
122+
private protocol ProtocolWithPrivateAccess4 {
123+
associatedtype AssocType //expected-note{{protocol requires nested type 'AssocType'}} {{81-81=\n typealias AssocType = <#type#>\n}}
124+
}
125+
public class Adopter11: ProtocolWithPrivateAccess3, ProtocolWithPrivateAccess4 {
126+
// expected-error@-1{{type 'Adopter11' does not conform to protocol 'ProtocolWithPrivateAccess3'}}
127+
// expected-error@-2{{type 'Adopter11' does not conform to protocol 'ProtocolWithPrivateAccess4'}}
128+
}

0 commit comments

Comments
 (0)