Skip to content
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
48 changes: 39 additions & 9 deletions lib/Sema/TypeCheckProtocol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2650,25 +2650,55 @@ diagnoseMissingWitnesses(MissingWitnessDiagnosisKind Kind) {
}
return;
}
auto &SM = DC->getASTContext().SourceMgr;
auto FixitBufferId = SM.findBufferContainingLoc(FixitLocation);
for (auto VD : MissingWitnesses) {
// Whether this VD has a stub printed.
bool AddFixit = !NoStubRequirements.count(VD);
bool SameFile = VD->getLoc().isValid() ?
SM.findBufferContainingLoc(VD->getLoc()) == FixitBufferId : false;

// Issue diagnostics for witness types.
if (auto MissingTypeWitness = dyn_cast<AssociatedTypeDecl>(VD)) {
Diags.diagnose(MissingTypeWitness, diag::no_witnesses_type,
MissingTypeWitness->getName()).
fixItInsertAfter(FixitLocation, FixIt);
if (SameFile) {
// If the protocol member decl is in the same file of the stub,
// we can directly associate the fixit with the note issued to the
// requirement.
Diags.diagnose(MissingTypeWitness, diag::no_witnesses_type,
MissingTypeWitness->getName()).fixItInsertAfter(FixitLocation, FixIt);
} else {
// Otherwise, we have to issue another note to carry the fixit,
// because editor may assume the fixit is in the same file with the note.
Diags.diagnose(MissingTypeWitness, diag::no_witnesses_type,
MissingTypeWitness->getName());
Diags.diagnose(ComplainLoc, diag::missing_witnesses_general).
fixItInsertAfter(FixitLocation, FixIt);
}
continue;
}
// Issue diagnostics for witness values.
Type RequirementType =
getRequirementTypeForDisplay(DC->getParentModule(), Conf, VD);
auto Diag = Diags.diagnose(VD, diag::no_witnesses,
getRequirementKind(VD), VD->getFullName(),
RequirementType, AddFixit);
if (AddFixit)
Diag.fixItInsertAfter(FixitLocation, FixIt);
getRequirementTypeForDisplay(DC->getParentModule(), Conf, VD);
if (AddFixit) {
if (SameFile) {
// If the protocol member decl is in the same file of the stub,
// we can directly associate the fixit with the note issued to the
// requirement.
Diags.diagnose(VD, diag::no_witnesses, getRequirementKind(VD),
VD->getFullName(), RequirementType, true).
fixItInsertAfter(FixitLocation, FixIt);
} else {
// Otherwise, we have to issue another note to carry the fixit,
// because editor may assume the fixit is in the same file with the note.
Diags.diagnose(VD, diag::no_witnesses, getRequirementKind(VD),
VD->getFullName(), RequirementType, false);
Diags.diagnose(ComplainLoc, diag::missing_witnesses_general).
fixItInsertAfter(FixitLocation, FixIt);
}
} else {
Diags.diagnose(VD, diag::no_witnesses, getRequirementKind(VD),
VD->getFullName(), RequirementType, true);
}
}
};

Expand Down
6 changes: 3 additions & 3 deletions test/ClangImporter/objc_parse.swift
Original file line number Diff line number Diff line change
Expand Up @@ -365,13 +365,13 @@ class ProtocolAdopter2 : FooProto {
set { /* do nothing! */ }
}
}
class ProtocolAdopterBad1 : FooProto { // expected-error {{type 'ProtocolAdopterBad1' does not conform to protocol 'FooProto'}}
class ProtocolAdopterBad1 : FooProto { // expected-error {{type 'ProtocolAdopterBad1' does not conform to protocol 'FooProto'}} expected-note {{do you want to add protocol stubs?}}
@objc var bar: Int = 0 // expected-note {{candidate has non-matching type 'Int'}}
}
class ProtocolAdopterBad2 : FooProto { // expected-error {{type 'ProtocolAdopterBad2' does not conform to protocol 'FooProto'}}
class ProtocolAdopterBad2 : FooProto { // expected-error {{type 'ProtocolAdopterBad2' does not conform to protocol 'FooProto'}} expected-note {{do you want to add protocol stubs?}}
let bar: CInt = 0 // expected-note {{candidate is not settable, but protocol requires it}}
}
class ProtocolAdopterBad3 : FooProto { // expected-error {{type 'ProtocolAdopterBad3' does not conform to protocol 'FooProto'}}
class ProtocolAdopterBad3 : FooProto { // expected-error {{type 'ProtocolAdopterBad3' does not conform to protocol 'FooProto'}} expected-note {{do you want to add protocol stubs?}}
var bar: CInt { // expected-note {{candidate is not settable, but protocol requires it}}
return 42
}
Expand Down
2 changes: 1 addition & 1 deletion test/ClangImporter/subclass_existentials.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class SwiftLaundryService : NSLaundry {

// FIXME: Consider better diagnostics here.

class OldSwiftLaundryService : NSLaundry {
class OldSwiftLaundryService : NSLaundry { // expected-note 3 {{do you want to add protocol stubs?}}
// expected-error@-1 {{type 'OldSwiftLaundryService' does not conform to protocol 'NSLaundry'}}

var g: Coat? = nil
Expand Down
2 changes: 1 addition & 1 deletion test/Constraints/invalid_stdlib_2.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// RUN: %target-typecheck-verify-swift

class Dictionary<K, V> : ExpressibleByDictionaryLiteral { // expected-error {{type 'Dictionary<K, V>' does not conform to protocol 'ExpressibleByDictionaryLiteral'}}
class Dictionary<K, V> : ExpressibleByDictionaryLiteral { // expected-error {{type 'Dictionary<K, V>' does not conform to protocol 'ExpressibleByDictionaryLiteral'}} expected-note {{do you want to add protocol stubs?}}
typealias Key = K
typealias Value = V
init(dictionaryLiteral xs: (K)...){} // expected-note {{candidate has non-matching type '(dictionaryLiteral: (K)...)'}}
Expand Down
4 changes: 2 additions & 2 deletions test/Generics/inheritance.swift
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,10 @@ func testGenericInherit() {


struct SS<T> : T { } // expected-error{{inheritance from non-protocol type 'T'}}
enum SE<T> : T { case X } // expected-error{{raw type 'T' is not expressible by a string, integer, or floating-point literal}} // expected-error {{SE<T>' declares raw type 'T', but does not conform to RawRepresentable and conformance could not be synthesized}} expected-error{{RawRepresentable conformance cannot be synthesized because raw type 'T' is not Equatable}}
enum SE<T> : T { case X } // expected-error{{raw type 'T' is not expressible by a string, integer, or floating-point literal}} // expected-error {{SE<T>' declares raw type 'T', but does not conform to RawRepresentable and conformance could not be synthesized}} expected-error{{RawRepresentable conformance cannot be synthesized because raw type 'T' is not Equatable}} expected-note {{do you want to add protocol stubs?}}

// Also need Equatable for init?(RawValue)
enum SE2<T : ExpressibleByIntegerLiteral>
enum SE2<T : ExpressibleByIntegerLiteral> // expected-note {{do you want to add protocol stubs?}}
: T // expected-error {{'SE2<T>' declares raw type 'T', but does not conform to RawRepresentable and conformance could not be synthesized}} expected-error{{RawRepresentable conformance cannot be synthesized because raw type 'T' is not Equatable}}
{ case X }

Expand Down
6 changes: 3 additions & 3 deletions test/IDE/print_ast_tc_decls_errors.swift
Original file line number Diff line number Diff line change
Expand Up @@ -117,19 +117,19 @@ enum EnumWithInheritance2 : FooNonExistentProtocol, BarNonExistentProtocol {} //
// NO-TYREPR: {{^}}enum EnumWithInheritance2 : <<error type>>, <<error type>> {{{$}}
// TYREPR: {{^}}enum EnumWithInheritance2 : FooNonExistentProtocol, BarNonExistentProtocol {{{$}}

enum EnumWithInheritance3 : FooClass { case X } // expected-error {{raw type 'FooClass' is not expressible by a string, integer, or floating-point literal}}
enum EnumWithInheritance3 : FooClass { case X } // expected-error {{raw type 'FooClass' is not expressible by a string, integer, or floating-point literal}} expected-note {{do you want to add protocol stubs?}}
// expected-error@-1{{'EnumWithInheritance3' declares raw type 'FooClass', but does not conform to RawRepresentable and conformance could not be synthesized}}
// expected-error@-2{{RawRepresentable conformance cannot be synthesized because raw type 'FooClass' is not Equatable}}
// NO-TYREPR: {{^}}enum EnumWithInheritance3 : <<error type>> {{{$}}
// TYREPR: {{^}}enum EnumWithInheritance3 : FooClass {{{$}}

enum EnumWithInheritance4 : FooClass, FooProtocol { case X } // expected-error {{raw type 'FooClass' is not expressible by a string, integer, or floating-point literal}}
enum EnumWithInheritance4 : FooClass, FooProtocol { case X } // expected-error {{raw type 'FooClass' is not expressible by a string, integer, or floating-point literal}} expected-note {{do you want to add protocol stubs?}}
// expected-error@-1{{'EnumWithInheritance4' declares raw type 'FooClass', but does not conform to RawRepresentable and conformance could not be synthesized}}
// expected-error@-2{{RawRepresentable conformance cannot be synthesized because raw type 'FooClass' is not Equatable}}
// NO-TYREPR: {{^}}enum EnumWithInheritance4 : <<error type>>, FooProtocol {{{$}}
// TYREPR: {{^}}enum EnumWithInheritance4 : FooClass, FooProtocol {{{$}}

enum EnumWithInheritance5 : FooClass, BarClass { case X } // expected-error {{raw type 'FooClass' is not expressible by a string, integer, or floating-point literal}} expected-error {{multiple enum raw types 'FooClass' and 'BarClass'}}
enum EnumWithInheritance5 : FooClass, BarClass { case X } // expected-error {{raw type 'FooClass' is not expressible by a string, integer, or floating-point literal}} expected-error {{multiple enum raw types 'FooClass' and 'BarClass'}} expected-note {{do you want to add protocol stubs?}}
// expected-error@-1{{'EnumWithInheritance5' declares raw type 'FooClass', but does not conform to RawRepresentable and conformance could not be synthesized}}
// expected-error@-2{{RawRepresentable conformance cannot be synthesized because raw type 'FooClass' is not Equatable}}
// NO-TYREPR: {{^}}enum EnumWithInheritance5 : <<error type>>, <<error type>> {{{$}}
Expand Down
28 changes: 14 additions & 14 deletions test/Parse/enum.swift
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ enum Recovery6 {
case Tusk, // expected-error {{expected pattern}}
} // expected-error {{expected identifier after comma in enum 'case' declaration}}

enum RawTypeEmpty : Int {} // expected-error {{an enum with no cases cannot declare a raw type}}
enum RawTypeEmpty : Int {} // expected-error {{an enum with no cases cannot declare a raw type}} expected-note {{do you want to add protocol stubs?}}
// expected-error@-1{{'RawTypeEmpty' declares raw type 'Int', but does not conform to RawRepresentable and conformance could not be synthesized}}

enum Raw : Int {
Expand All @@ -143,7 +143,7 @@ enum RawTypeNotFirst : RawTypeNotFirstProtocol, Int { // expected-error {{raw ty
case E
}

enum ExpressibleByRawTypeNotLiteral : Array<Int> { // expected-error {{raw type 'Array<Int>' is not expressible by a string, integer, or floating-point literal}}
enum ExpressibleByRawTypeNotLiteral : Array<Int> { // expected-error {{raw type 'Array<Int>' is not expressible by a string, integer, or floating-point literal}} expected-note {{do you want to add protocol stubs?}}
// expected-error@-1{{'ExpressibleByRawTypeNotLiteral' declares raw type 'Array<Int>', but does not conform to RawRepresentable and conformance could not be synthesized}}
case Ladd, Elliott, Sixteenth, Harrison
}
Expand All @@ -167,7 +167,7 @@ enum RawTypeCircularityB : RawTypeCircularityA, ExpressibleByIntegerLiteral { //
struct ExpressibleByFloatLiteralOnly : ExpressibleByFloatLiteral {
init(floatLiteral: Double) {}
}
enum ExpressibleByRawTypeNotIntegerLiteral : ExpressibleByFloatLiteralOnly { // expected-error {{'ExpressibleByRawTypeNotIntegerLiteral' declares raw type 'ExpressibleByFloatLiteralOnly', but does not conform to RawRepresentable and conformance could not be synthesized}} expected-error {{RawRepresentable conformance cannot be synthesized because raw type 'ExpressibleByFloatLiteralOnly' is not Equatable}}
enum ExpressibleByRawTypeNotIntegerLiteral : ExpressibleByFloatLiteralOnly { // expected-error {{'ExpressibleByRawTypeNotIntegerLiteral' declares raw type 'ExpressibleByFloatLiteralOnly', but does not conform to RawRepresentable and conformance could not be synthesized}} expected-error {{RawRepresentable conformance cannot be synthesized because raw type 'ExpressibleByFloatLiteralOnly' is not Equatable}} expected-note {{do you want to add protocol stubs?}}
case Everett // expected-error {{enum cases require explicit raw values when the raw type is not expressible by integer or string literal}}
case Flanders
}
Expand All @@ -181,13 +181,13 @@ enum RawTypeWithNegativeValues : Int {
case AutoIncAcrossZero = -1, Zero, One
}

enum RawTypeWithUnicodeScalarValues : UnicodeScalar { // expected-error {{'RawTypeWithUnicodeScalarValues' declares raw type 'UnicodeScalar' (aka 'Unicode.Scalar'), but does not conform to RawRepresentable and conformance could not be synthesized}}
enum RawTypeWithUnicodeScalarValues : UnicodeScalar { // expected-error {{'RawTypeWithUnicodeScalarValues' declares raw type 'UnicodeScalar' (aka 'Unicode.Scalar'), but does not conform to RawRepresentable and conformance could not be synthesized}} expected-note {{do you want to add protocol stubs?}}
case Kearney = "K"
case Lovejoy // expected-error {{enum cases require explicit raw values when the raw type is not expressible by integer or string literal}}
case Marshall = "M"
}

enum RawTypeWithCharacterValues : Character { // expected-error {{'RawTypeWithCharacterValues' declares raw type 'Character', but does not conform to RawRepresentable and conformance could not be synthesized}}
enum RawTypeWithCharacterValues : Character { // expected-error {{'RawTypeWithCharacterValues' declares raw type 'Character', but does not conform to RawRepresentable and conformance could not be synthesized}} expected-note {{do you want to add protocol stubs?}}
case First = "い"
case Second // expected-error {{enum cases require explicit raw values when the raw type is not expressible by integer or string literal}}
case Third = "は"
Expand All @@ -200,11 +200,11 @@ enum RawTypeWithCharacterValues_Correct : Character {
case Fourth = "\u{1F3F4}\u{E0067}\u{E0062}\u{E0065}\u{E006E}\u{E0067}\u{E007F}" // ok
}

enum RawTypeWithCharacterValues_Error1 : Character { // expected-error {{'RawTypeWithCharacterValues_Error1' declares raw type 'Character', but does not conform to RawRepresentable and conformance could not be synthesized}}
enum RawTypeWithCharacterValues_Error1 : Character { // expected-error {{'RawTypeWithCharacterValues_Error1' declares raw type 'Character', but does not conform to RawRepresentable and conformance could not be synthesized}} expected-note {{do you want to add protocol stubs?}}
case First = "abc" // expected-error {{cannot convert value of type 'String' to raw type 'Character'}}
}

enum RawTypeWithFloatValues : Float { // expected-error {{'RawTypeWithFloatValues' declares raw type 'Float', but does not conform to RawRepresentable and conformance could not be synthesized}}
enum RawTypeWithFloatValues : Float { // expected-error {{'RawTypeWithFloatValues' declares raw type 'Float', but does not conform to RawRepresentable and conformance could not be synthesized}} expected-note {{do you want to add protocol stubs?}}
case Northrup = 1.5
case Overton // expected-error {{enum case must declare a raw value when the preceding raw value is not an integer}}
case Pettygrove = 2.25
Expand Down Expand Up @@ -315,12 +315,12 @@ enum NonliteralRawValue : Int {
case Yeon = 100 + 20 + 3 // expected-error {{raw value for enum case must be a literal}}
}

enum RawTypeWithPayload : Int { // expected-error {{'RawTypeWithPayload' declares raw type 'Int', but does not conform to RawRepresentable and conformance could not be synthesized}} expected-note {{declared raw type 'Int' here}} expected-note {{declared raw type 'Int' here}}
enum RawTypeWithPayload : Int { // expected-error {{'RawTypeWithPayload' declares raw type 'Int', but does not conform to RawRepresentable and conformance could not be synthesized}} expected-note {{declared raw type 'Int' here}} expected-note {{declared raw type 'Int' here}} expected-note {{do you want to add protocol stubs?}}
case Powell(Int) // expected-error {{enum with raw type cannot have cases with arguments}}
case Terwilliger(Int) = 17 // expected-error {{enum with raw type cannot have cases with arguments}}
}

enum RawTypeMismatch : Int { // expected-error {{'RawTypeMismatch' declares raw type 'Int', but does not conform to RawRepresentable and conformance could not be synthesized}}
enum RawTypeMismatch : Int { // expected-error {{'RawTypeMismatch' declares raw type 'Int', but does not conform to RawRepresentable and conformance could not be synthesized}} expected-note {{do you want to add protocol stubs?}}
case Barbur = "foo" // expected-error {{}}
}

Expand All @@ -340,12 +340,12 @@ enum DuplicateMembers3 {
case Foo(Int) // expected-error {{invalid redeclaration of 'Foo'}}
}

enum DuplicateMembers4 : Int { // expected-error {{'DuplicateMembers4' declares raw type 'Int', but does not conform to RawRepresentable and conformance could not be synthesized}}
enum DuplicateMembers4 : Int { // expected-error {{'DuplicateMembers4' declares raw type 'Int', but does not conform to RawRepresentable and conformance could not be synthesized}} expected-note {{do you want to add protocol stubs?}}
case Foo = 1 // expected-note {{'Foo' previously declared here}}
case Foo = 2 // expected-error {{invalid redeclaration of 'Foo'}}
}

enum DuplicateMembers5 : Int { // expected-error {{'DuplicateMembers5' declares raw type 'Int', but does not conform to RawRepresentable and conformance could not be synthesized}}
enum DuplicateMembers5 : Int { // expected-error {{'DuplicateMembers5' declares raw type 'Int', but does not conform to RawRepresentable and conformance could not be synthesized}} expected-note {{do you want to add protocol stubs?}}
case Foo = 1 // expected-note {{'Foo' previously declared here}}
case Foo = 1 + 1 // expected-error {{invalid redeclaration of 'Foo'}} expected-error {{raw value for enum case must be a literal}}
}
Expand All @@ -356,7 +356,7 @@ enum DuplicateMembers6 {
case Foo // expected-error {{invalid redeclaration of 'Foo'}}
}

enum DuplicateMembers7 : String { // expected-error {{'DuplicateMembers7' declares raw type 'String', but does not conform to RawRepresentable and conformance could not be synthesized}}
enum DuplicateMembers7 : String { // expected-error {{'DuplicateMembers7' declares raw type 'String', but does not conform to RawRepresentable and conformance could not be synthesized}} expected-note {{do you want to add protocol stubs?}}
case Foo // expected-note {{'Foo' previously declared here}}
case Foo = "Bar" // expected-error {{invalid redeclaration of 'Foo'}}
}
Expand Down Expand Up @@ -408,7 +408,7 @@ enum ManyLiteralA : ManyLiteralable {
case B = 0 // expected-error {{raw value for enum case is not unique}}
}

enum ManyLiteralB : ManyLiteralable { // expected-error {{'ManyLiteralB' declares raw type 'ManyLiteralable', but does not conform to RawRepresentable and conformance could not be synthesized}}
enum ManyLiteralB : ManyLiteralable { // expected-error {{'ManyLiteralB' declares raw type 'ManyLiteralable', but does not conform to RawRepresentable and conformance could not be synthesized}} expected-note {{do you want to add protocol stubs?}}
case A = "abc"
case B // expected-error {{enum case must declare a raw value when the preceding raw value is not an integer}}
}
Expand Down Expand Up @@ -437,7 +437,7 @@ enum RawValueBTest: Double, RawValueB {
case A, B
}

enum foo : String { // expected-error {{'foo' declares raw type 'String', but does not conform to RawRepresentable and conformance could not be synthesized}}
enum foo : String { // expected-error {{'foo' declares raw type 'String', but does not conform to RawRepresentable and conformance could not be synthesized}} expected-note {{do you want to add protocol stubs?}}
case bar = nil // expected-error {{cannot convert 'nil' to raw type 'String'}}
}

Expand Down
Loading