Skip to content

[Sema] Emit only "public" access modifier in fix-it for missing witness #4585

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Sep 1, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions lib/Sema/TypeCheckProtocol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2032,9 +2032,19 @@ static void diagnoseNoWitness(ValueDecl *Requirement, Type RequirementType,
std::string FixitString;
llvm::raw_string_ostream FixitStream(FixitString);
ExtraIndentStreamPrinter Printer(FixitStream, StubIndent);
Printer.printNewline();

Accessibility Access = std::min(
/* Access of the context */
Conformance->getDeclContext()
->getAsGenericTypeOrGenericTypeExtensionContext()->getFormalAccess(),
/* Access of the protocol */
Requirement->getDeclContext()
->getAsProtocolOrProtocolExtensionContext()->getFormalAccess());
if (Access == Accessibility::Public)
Printer << "public ";

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

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

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

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

Expand Down
85 changes: 65 additions & 20 deletions test/decl/protocol/conforms/fixit_stub.swift
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
// RUN: %target-parse-verify-swift

protocol Protocol1 {
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}}
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}}
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}}
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}}
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}}
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}}
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}}
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}}
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}}
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}}
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}}
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}}
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}}
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}}
}

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


protocol Protocol2 {
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}}
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}}
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}}
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}}
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}}
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}}
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}}
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}}
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}}
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}}
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}}
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}}
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}}
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}}
}

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


protocol ProtocolWithSelfRequirement {
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}}
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}}
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}}
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}}
}

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


protocol ProtocolWithSelfRequirement2 {
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}}
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}}
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}}
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}}
}

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


protocol ProtocolWithSelfRequirement3 {
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}}
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}}
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}}
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}}
}

class Adopter7: ProtocolWithSelfRequirement3 { //expected-error{{type 'Adopter7' does not conform to protocol 'ProtocolWithSelfRequirement3'}}
}


public protocol ProtocolWithPublicAccess1 {
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}}
}
public protocol ProtocolWithPublicAccess2 {
associatedtype AssocType //expected-note{{protocol requires nested type 'AssocType'}} {71-71=\n typealias AssocType = <#type#>\n}}
}
class Adopter8: ProtocolWithPublicAccess1, ProtocolWithPublicAccess2 {
// expected-error@-1{{type 'Adopter8' does not conform to protocol 'ProtocolWithPublicAccess1'}}
// expected-error@-2{{type 'Adopter8' does not conform to protocol 'ProtocolWithPublicAccess2'}}
}

public protocol ProtocolWithPublicAccess3 {
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}}
Copy link
Member Author

@rintaro rintaro Sep 1, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jrose-apple Here's non-associatedtype test that emits public. Do we need init(), var, or subscript too?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, I'm sorry, somehow I missed this one. All good, please feel free to merge.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:)
Sorry, I'm not authorized to merge. Could you?

Or @shahmishal, Could you authorize me to merge?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instructions for getting commit access are at https://swift.org/contributing/#contributing-code "Commit Access" 😃

}
public protocol ProtocolWithPublicAccess4 {
associatedtype AssocType //expected-note{{protocol requires nested type 'AssocType'}} {{78-78=\n public typealias AssocType = <#type#>\n}}
}
public class Adopter9: ProtocolWithPublicAccess3, ProtocolWithPublicAccess4 {
// expected-error@-1{{type 'Adopter9' does not conform to protocol 'ProtocolWithPublicAccess3'}}
// expected-error@-2{{type 'Adopter9' does not conform to protocol 'ProtocolWithPublicAccess4'}}
}

private protocol ProtocolWithPrivateAccess1 {
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}}
}
private protocol ProtocolWithPrivateAccess2 {
associatedtype AssocType //expected-note{{protocol requires nested type 'AssocType'}} {{74-74=\n typealias AssocType = <#type#>\n}}
}
class Adopter10: ProtocolWithPrivateAccess1, ProtocolWithPrivateAccess2 {
// expected-error@-1{{type 'Adopter10' does not conform to protocol 'ProtocolWithPrivateAccess1'}}
// expected-error@-2{{type 'Adopter10' does not conform to protocol 'ProtocolWithPrivateAccess2'}}
}

private protocol ProtocolWithPrivateAccess3 {
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}}
}
private protocol ProtocolWithPrivateAccess4 {
associatedtype AssocType //expected-note{{protocol requires nested type 'AssocType'}} {{81-81=\n typealias AssocType = <#type#>\n}}
}
public class Adopter11: ProtocolWithPrivateAccess3, ProtocolWithPrivateAccess4 {
// expected-error@-1{{type 'Adopter11' does not conform to protocol 'ProtocolWithPrivateAccess3'}}
// expected-error@-2{{type 'Adopter11' does not conform to protocol 'ProtocolWithPrivateAccess4'}}
}