[Diagnostics] Remove argument handling from conformance failures

Argument-to-Parameter mismatch handles conformance failures
related to arguments, so the logic in `MissingConformanceFailure`
which wasn't entirely correct is now completely obsolete.

Resolves: rdar://problem/56234611
This commit is contained in:
Pavel Yaskevich
2019-10-14 00:27:41 -07:00
parent 36c5c2f2ea
commit d90117bb8a
19 changed files with 66 additions and 90 deletions

View File

@@ -542,26 +542,11 @@ void RequirementFailure::emitRequirementNote(const Decl *anchor, Type lhs,
bool MissingConformanceFailure::diagnoseAsError() {
auto *anchor = getAnchor();
auto ownerType = getOwnerType();
auto nonConformingType = getLHS();
auto protocolType = getRHS();
auto getArgumentAt = [](const ApplyExpr *AE, unsigned index) -> Expr * {
assert(AE);
auto *arg = AE->getArg();
if (auto *TE = dyn_cast<TupleExpr>(arg))
return TE->getElement(index);
assert(index == 0);
if (auto *PE = dyn_cast<ParenExpr>(arg))
return PE->getSubExpr();
return arg;
};
// If this is a requirement of a pattern-matching operator,
// let's see whether argument is already has a fix associated
// let's see whether argument already has a fix associated
// with it and if so skip conformance error, otherwise we'd
// produce an unrelated `<type> doesn't conform to Equatable protocol`
// diagnostic.
@@ -588,43 +573,14 @@ bool MissingConformanceFailure::diagnoseAsError() {
if (diagnoseAsAmbiguousOperatorRef())
return true;
Optional<unsigned> atParameterPos;
// Sometimes fix is recorded by type-checking sub-expression
// during normal diagnostics, in such case call expression
// is unavailable.
if (Apply) {
if (auto *fnType = ownerType->getAs<AnyFunctionType>()) {
auto parameters = fnType->getParams();
for (auto index : indices(parameters)) {
if (parameters[index].getOldType()->isEqual(nonConformingType)) {
atParameterPos = index;
break;
}
}
}
}
if (nonConformingType->isObjCExistentialType()) {
emitDiagnostic(anchor->getLoc(), diag::protocol_does_not_conform_static,
nonConformingType, protocolType);
return true;
}
if (diagnoseTypeCannotConform((atParameterPos ?
getArgumentAt(Apply, *atParameterPos) : anchor),
nonConformingType, protocolType)) {
return true;
}
if (atParameterPos) {
// Requirement comes from one of the parameter types,
// let's try to point diagnostic to the argument expression.
auto *argExpr = getArgumentAt(Apply, *atParameterPos);
emitDiagnostic(argExpr->getLoc(),
diag::cannot_convert_argument_value_protocol,
nonConformingType, protocolType);
if (diagnoseTypeCannotConform(anchor, nonConformingType, protocolType))
return true;
}
// If none of the special cases could be diagnosed,
// let's fallback to the most general diagnostic.

View File

@@ -13,12 +13,15 @@ import MoreSwiftNewtypes
func acceptEquatable<T: Equatable>(_: T) {}
func acceptHashable<T: Hashable>(_: T) {}
// expected-note@-1 {{where 'T' = 'WrappedRef'}}
// expected-note@-2 {{where 'T' = 'WrappedValue'}}
func acceptComparable<T: Comparable>(_: T) {}
// expected-note@-1 {{where 'T' = 'NSNotification.Name'}}
func testNewTypeWrapper(x: NSNotification.Name, y: NSNotification.Name) {
acceptEquatable(x)
acceptHashable(x)
acceptComparable(x) // expected-error {{does not conform to expected type 'Comparable'}}
acceptComparable(x) // expected-error {{global function 'acceptComparable' requires that 'NSNotification.Name' conform to 'Comparable'}}
_ = x == y
_ = x != y
@@ -30,6 +33,6 @@ func testNewTypeWrapper(x: NSNotification.Name, y: NSNotification.Name) {
func testCustomWrappers(wrappedRef: WrappedRef, wrappedValue: WrappedValue) {
acceptEquatable(wrappedRef)
acceptEquatable(wrappedValue)
acceptHashable(wrappedRef) // expected-error {{does not conform to expected type 'Hashable'}}
acceptHashable(wrappedValue) // expected-error {{does not conform to expected type 'Hashable'}}
acceptHashable(wrappedRef) // expected-error {{global function 'acceptHashable' requires that 'WrappedRef' conform to 'Hashable'}}
acceptHashable(wrappedValue) // expected-error {{global function 'acceptHashable' requires that 'WrappedValue' conform to 'Hashable'}}
}

View File

@@ -31,6 +31,7 @@ func f5<T : P2>(_ : T) { }
// expected-note@-1 {{required by global function 'f5' where 'T' = '(Int) -> Int'}}
// expected-note@-2 {{required by global function 'f5' where 'T' = '(Int, String)'}}
// expected-note@-3 {{required by global function 'f5' where 'T' = 'Int.Type'}}
// expected-note@-4 {{where 'T' = 'Int'}}
func f6<T : P, U : P>(_ t: T, _ u: U) where T.SomeType == U.SomeType {}
@@ -75,10 +76,10 @@ i.wobble() // expected-error{{value of type 'Int' has no member 'wobble'}}
// Generic member does not conform.
extension Int {
func wibble<T: P2>(_ x: T, _ y: T) -> T { return x }
func wibble<T: P2>(_ x: T, _ y: T) -> T { return x } // expected-note {{where 'T' = 'Int'}}
func wubble<T>(_ x: (Int) -> T) -> T { return x(self) }
}
i.wibble(3, 4) // expected-error {{argument type 'Int' does not conform to expected type 'P2'}}
i.wibble(3, 4) // expected-error {{instance method 'wibble' requires that 'Int' conform to 'P2'}}
// Generic member args correct, but return type doesn't match.
struct A : P2 {
@@ -98,9 +99,9 @@ func f7() -> (c: Int, v: A) {
return f6(g) // expected-error {{cannot convert return expression of type '(c: Int, i: A)' to return type '(c: Int, v: A)'}}
}
func f8<T:P2>(_ n: T, _ f: @escaping (T) -> T) {}
func f8<T:P2>(_ n: T, _ f: @escaping (T) -> T) {} // expected-note {{where 'T' = 'Int'}}
// expected-note@-1 {{required by global function 'f8' where 'T' = 'Tup' (aka '(Int, Double)')}}
f8(3, f4) // expected-error {{argument type 'Int' does not conform to expected type 'P2'}}
f8(3, f4) // expected-error {{global function 'f8' requires that 'Int' conform to 'P2'}}
typealias Tup = (Int, Double)
func f9(_ x: Tup) -> Tup { return x }
f8((1,2.0), f9) // expected-error {{type 'Tup' (aka '(Int, Double)') cannot conform to 'P2'; only struct/enum/class types can conform to protocols}}
@@ -111,7 +112,7 @@ f8((1,2.0), f9) // expected-error {{type 'Tup' (aka '(Int, Double)') cannot conf
"awfawf".doesntExist(0) // expected-error {{value of type 'String' has no member 'doesntExist'}}
// Does not conform to protocol.
f5(i) // expected-error {{argument type 'Int' does not conform to expected type 'P2'}}
f5(i) // expected-error {{global function 'f5' requires that 'Int' conform to 'P2'}}
// Make sure we don't leave open existentials when diagnosing.
// <rdar://problem/20598568>

View File

@@ -2,7 +2,7 @@
infix operator +++
protocol ConcatToAnything {
protocol ConcatToAnything { // expected-note {{where 'Self' = 'U'}}
static func +++ <T>(lhs: Self, other: T)
}
@@ -14,7 +14,7 @@ func min<T : Comparable>(_ x: T, y: T) -> T {
func weirdConcat<T : ConcatToAnything, U>(_ t: T, u: U) {
t +++ u
t +++ 1
u +++ t // expected-error{{argument type 'U' does not conform to expected type 'ConcatToAnything'}}
u +++ t // expected-error{{referencing operator function '+++' on 'ConcatToAnything' requires that 'U' conform to 'ConcatToAnything'}}
}
// Make sure that the protocol operators don't get in the way.
@@ -647,7 +647,7 @@ struct BottleLayout {
}
let arr = [BottleLayout]()
let layout = BottleLayout(count:1)
let ix = arr.firstIndex(of:layout) // expected-error {{argument type 'BottleLayout' does not conform to expected type 'Equatable'}}
let ix = arr.firstIndex(of:layout) // expected-error {{referencing instance method 'firstIndex(of:)' on 'Collection' requires that 'BottleLayout' conform to 'Equatable'}}
let _: () -> UInt8 = { .init("a" as Unicode.Scalar) } // expected-error {{missing argument label 'ascii:' in call}}

View File

@@ -414,3 +414,10 @@ func rdar_50512161() {
foo(item: item) // expected-error {{generic parameter 'I' could not be inferred}}
}
}
// SR-11609: Compiler crash on missing conformance for default param
func test_sr_11609() {
func foo<T : Initable>(_ x: T = .init()) -> T { x } // expected-note {{where 'T' = 'String'}}
let _: String = foo()
// expected-error@-1 {{local function 'foo' requires that 'String' conform to 'Initable'}}
}

View File

@@ -6,6 +6,6 @@ import Foundation
struct S {
init<T: NSNumber>(_ num: T) { // expected-note {{where 'T' = 'Bool'}}
self.init(num != 0) // expected-error {{initializer 'init(_:)' requires that 'Bool' inherit from 'NSNumber'}}
// expected-error@-1 {{argument type 'T' does not conform to expected type 'BinaryInteger'}}
// expected-error@-1 {{referencing operator function '!=' on 'BinaryInteger' requires that 'T' conform to 'BinaryInteger'}}
}
}

View File

@@ -181,7 +181,7 @@ variadicWithTrailingClosure(fn: +)
func gcd_23700031<T>(_ a: T, b: T) {
var a = a
var b = b
(a, b) = (b, a % b) // expected-error {{argument type 'T' does not conform to expected type 'BinaryInteger'}}
(a, b) = (b, a % b) // expected-error {{protocol 'BinaryInteger' requires that 'T' conform to 'BinaryInteger'}}
}
// <rdar://problem/24210190>

View File

@@ -194,7 +194,7 @@ protocol IsBefore {
func isBefore(_ other: Self) -> Bool
}
func min2<T : IsBefore>(_ x: T, _ y: T) -> T {
func min2<T : IsBefore>(_ x: T, _ y: T) -> T { // expected-note {{where 'T' = 'Float'}}
if y.isBefore(x) { return y }
return x
}
@@ -205,7 +205,7 @@ extension Int : IsBefore {
func callMin(_ x: Int, y: Int, a: Float, b: Float) {
_ = min2(x, y)
min2(a, b) // expected-error{{argument type 'Float' does not conform to expected type 'IsBefore'}}
min2(a, b) // expected-error{{global function 'min2' requires that 'Float' conform to 'IsBefore'}}
}
func rangeOfIsBefore<R : IteratorProtocol>(_ range: R) where R.Element : IsBefore {} // expected-note {{where 'R.Element' = 'IndexingIterator<[Double]>.Element' (aka 'Double')}}
@@ -241,11 +241,11 @@ genericInheritsA(C_GI())
//===----------------------------------------------------------------------===//
// Deduction for member operators
//===----------------------------------------------------------------------===//
protocol Addable {
protocol Addable { // expected-note {{where 'Self' = 'U'}}
static func +(x: Self, y: Self) -> Self
}
func addAddables<T : Addable, U>(_ x: T, y: T, u: U) -> T {
u + u // expected-error{{argument type 'U' does not conform to expected type 'Addable'}}
u + u // expected-error{{protocol 'Addable' requires that 'U' conform to 'Addable'}}
return x+y
}
@@ -314,7 +314,7 @@ func foo() {
for i in min(1,2) { // expected-error{{type 'Int' does not conform to protocol 'Sequence'}}
}
let j = min(Int(3), Float(2.5)) // expected-error{{cannot convert value of type 'Float' to expected argument type 'Int'}}
let k = min(A(), A()) // expected-error{{argument type 'A' does not conform to expected type 'Comparable'}}
let k = min(A(), A()) // expected-error{{global function 'min' requires that 'A' conform to 'Comparable'}}
let oi : Int? = 5
let l = min(3, oi) // expected-error{{value of optional type 'Int?' must be unwrapped}}
// expected-note@-1{{coalesce}}

View File

@@ -59,14 +59,14 @@ class SomeClassWithInvalidMethod {
// <rdar://problem/20792596> QoI: Cannot invoke with argument list (T), expected an argument list of (T)
protocol r20792596P {}
func foor20792596<T: r20792596P>(x: T) -> T {
func foor20792596<T: r20792596P>(x: T) -> T { // expected-note {{where 'T' = 'T'}}
return x
}
func callfoor20792596<T>(x: T) -> T {
return foor20792596(x)
// expected-error@-1 {{missing argument label 'x:' in call}}
// expected-error@-2 {{argument type 'T' does not conform to expected type 'r20792596P'}}
// expected-error@-2 {{global function 'foor20792596(x:)' requires that 'T' conform to 'r20792596P'}}
}
// <rdar://problem/31181895> parameter "not used in function signature" when part of a superclass constraint

View File

@@ -71,14 +71,14 @@ _ = sr7918_Suit.foo(&myRNG) // expected-error {{cannot pass immutable value as i
//=-------------- SR-7786 --------------=/
struct sr7786 {
func foo() -> UInt { return 0 }
func foo<T: UnsignedInteger>(bar: T) -> T {
func foo<T: UnsignedInteger>(bar: T) -> T { // expected-note {{where 'T' = 'Int'}}
return bar
}
}
let s = sr7786()
let a = s.foo()
let b = s.foo(bar: 123) // expected-error {{argument type 'Int' does not conform to expected type 'UnsignedInteger'}}
let b = s.foo(bar: 123) // expected-error {{instance method 'foo(bar:)' requires that 'Int' conform to 'UnsignedInteger'}}
let c: UInt = s.foo(bar: 123)
let d = s.foo(bar: 123 as UInt)

View File

@@ -603,7 +603,7 @@ func keypath_with_incorrect_return_type(_ arr: Lens<Array<Int>>) {
// expected-error@-1 {{operator function '..<' requires that 'Lens<Int>' conform to 'Strideable'}}
// expected-error@-2 {{operator function '..<' requires that 'Lens<Int>.Stride' conform to 'SignedInteger'}}
// expected-error@-3 {{cannot convert value of type 'Int' to expected argument type 'Lens<Int>'}}
// expected-error@-4 {{argument type 'Lens<Int>' does not conform to expected type 'Comparable'}}
// expected-error@-4 {{referencing operator function '..<' on 'Comparable' requires that 'Lens<Int>' conform to 'Comparable'}}
let _ = arr[idx]
}
}

View File

@@ -4,7 +4,7 @@
import Foundation
func acceptBridgeableNSError<E : _ObjectiveCBridgeableError>(_ e: E) { }
func acceptBridgeableNSError<E : _ObjectiveCBridgeableError>(_ e: E) { } // expected-note {{where 'E' = 'E3'}}
@objc enum E2 : Int, Error {
case A = 1
@@ -18,4 +18,4 @@ acceptBridgeableNSError(E2.A)
}
acceptBridgeableNSError(E3.A)
// expected-error@-1{{argument type 'E3' does not conform to expected type '_ObjectiveCBridgeableError'}}
// expected-error@-1{{global function 'acceptBridgeableNSError' requires that 'E3' conform to '_ObjectiveCBridgeableError'}}

View File

@@ -131,7 +131,7 @@ func intArray(_ x: [Int]) {
class GenericClass<T> { }
extension GenericClass where T : Equatable {
extension GenericClass where T : Equatable { // expected-note {{where 'T' = 'T'}}
func foo(_ x: T, y: T) -> Bool { return x == y }
}
@@ -140,7 +140,7 @@ func genericClassEquatable<T : Equatable>(_ gc: GenericClass<T>, x: T, y: T) {
}
func genericClassNotEquatable<T>(_ gc: GenericClass<T>, x: T, y: T) {
gc.foo(x, y: y) // expected-error{{argument type 'T' does not conform to expected type 'Equatable'}}
gc.foo(x, y: y) // expected-error{{referencing instance method 'foo(_:y:)' on 'GenericClass' requires that 'T' conform to 'Equatable'}}
}

View File

@@ -783,7 +783,7 @@ func testNilCoalescePrecedence(cond: Bool, a: Int?, r: ClosedRange<Int>?) {
// ?? should have lower precedence than range and arithmetic operators.
let r1 = r ?? (0...42) // ok
let r2 = (r ?? 0)...42 // not ok: expected-error 2 {{cannot convert value of type 'Int' to expected argument type 'ClosedRange<Int>'}}
// expected-error@-1 {{argument type 'ClosedRange<Int>' does not conform to expected type 'Comparable'}}
// expected-error@-1 {{referencing operator function '...' on 'Comparable' requires that 'ClosedRange<Int>' conform to 'Comparable'}}
let r3 = r ?? 0...42 // parses as the first one, not the second.

View File

@@ -13,7 +13,7 @@ struct S {
protocol K { }
func + <Object>(lhs: KeyPath<A, Object>, rhs: String) -> P<Object> {
func + <Object>(lhs: KeyPath<A, Object>, rhs: String) -> P<Object> { // expected-note {{where 'Object' = 'String'}}
fatalError()
}
@@ -27,7 +27,7 @@ struct A {
}
extension A: K {
static let j = S(\A.id + "id") // expected-error {{argument type 'String' does not conform to expected type 'K'}}
static let j = S(\A.id + "id") // expected-error {{operator function '+' requires that 'String' conform to 'K'}}
}
// SR-5034

View File

@@ -63,23 +63,27 @@ func testStringDeprecation(hello: String) {
func acceptsCollection<C: Collection>(_: C) {}
func acceptsBidirectionalCollection<C: BidirectionalCollection>(_: C) {}
func acceptsRandomAccessCollection<C: RandomAccessCollection>(_: C) {}
// expected-note@-1 {{where 'C' = 'String.UTF8View'}}
// expected-note@-2 {{where 'C' = 'String.UnicodeScalarView'}}
// expected-note@-3 {{where 'C' = 'String.UTF16View'}}
// expected-note@-4 {{where 'C' = 'String'}}
func testStringCollectionTypes(s: String) {
acceptsCollection(s.utf8)
acceptsBidirectionalCollection(s.utf8)
acceptsRandomAccessCollection(s.utf8) // expected-error{{argument type 'String.UTF8View' does not conform to expected type 'RandomAccessCollection'}}
acceptsRandomAccessCollection(s.utf8) // expected-error{{global function 'acceptsRandomAccessCollection' requires that 'String.UTF8View' conform to 'RandomAccessCollection'}}
acceptsCollection(s.utf16)
acceptsBidirectionalCollection(s.utf16)
acceptsRandomAccessCollection(s.utf16) // expected-error{{argument type 'String.UTF16View' does not conform to expected type 'RandomAccessCollection'}}
acceptsRandomAccessCollection(s.utf16) // expected-error{{global function 'acceptsRandomAccessCollection' requires that 'String.UTF16View' conform to 'RandomAccessCollection'}}
acceptsCollection(s.unicodeScalars)
acceptsBidirectionalCollection(s.unicodeScalars)
acceptsRandomAccessCollection(s.unicodeScalars) // expected-error{{argument type 'String.UnicodeScalarView' does not conform to expected type 'RandomAccessCollection'}}
acceptsRandomAccessCollection(s.unicodeScalars) // expected-error{{global function 'acceptsRandomAccessCollection' requires that 'String.UnicodeScalarView' conform to 'RandomAccessCollection'}}
acceptsCollection(s)
acceptsBidirectionalCollection(s)
acceptsRandomAccessCollection(s) // expected-error{{argument type 'String' does not conform to expected type 'RandomAccessCollection'}}
acceptsRandomAccessCollection(s) // expected-error{{global function 'acceptsRandomAccessCollection' requires that 'String' conform to 'RandomAccessCollection'}}
}
// In previous versions of Swift, code would accidentally select

View File

@@ -4,22 +4,26 @@
func acceptsCollection<I: Collection>(_: I) {}
func acceptsBidirectionalCollection<I: BidirectionalCollection>(_: I) {}
func acceptsRandomAccessCollection<I: RandomAccessCollection>(_: I) {}
// expected-note@-1 {{where 'I' = 'String.UTF8View'}}
// expected-note@-2 {{where 'I' = 'String.UnicodeScalarView'}}
// expected-note@-3 {{where 'I' = 'String.UTF16View'}}
// expected-note@-4 {{where 'I' = 'String'}}
func testStringCollectionTypes(s: String) {
acceptsCollection(s.utf8)
acceptsBidirectionalCollection(s.utf8)
acceptsRandomAccessCollection(s.utf8) // expected-error{{argument type 'String.UTF8View' does not conform to expected type 'RandomAccessCollection'}}
acceptsRandomAccessCollection(s.utf8) // expected-error{{global function 'acceptsRandomAccessCollection' requires that 'String.UTF8View' conform to 'RandomAccessCollection'}}
// UTF16View is random-access with Foundation, bidirectional without
acceptsCollection(s.utf16)
acceptsBidirectionalCollection(s.utf16)
acceptsRandomAccessCollection(s.utf16) // expected-error{{argument type 'String.UTF16View' does not conform to expected type 'RandomAccessCollection'}}
acceptsRandomAccessCollection(s.utf16) // expected-error{{global function 'acceptsRandomAccessCollection' requires that 'String.UTF16View' conform to 'RandomAccessCollection'}}
acceptsCollection(s.unicodeScalars)
acceptsBidirectionalCollection(s.unicodeScalars)
acceptsRandomAccessCollection(s.unicodeScalars) // expected-error{{argument type 'String.UnicodeScalarView' does not conform to expected type 'RandomAccessCollection'}}
acceptsRandomAccessCollection(s.unicodeScalars) // expected-error{{global function 'acceptsRandomAccessCollection' requires that 'String.UnicodeScalarView' conform to 'RandomAccessCollection'}}
acceptsCollection(s)
acceptsBidirectionalCollection(s)
acceptsRandomAccessCollection(s) // expected-error{{argument type 'String' does not conform to expected type 'RandomAccessCollection'}}
acceptsRandomAccessCollection(s) // expected-error{{global function 'acceptsRandomAccessCollection' requires that 'String' conform to 'RandomAccessCollection'}}
}

View File

@@ -305,6 +305,7 @@ func conformsToP2<T : P2>(_: T) {}
func conformsToBaseIntAndP2<T : Base<Int> & P2>(_: T) {}
// expected-note@-1 {{where 'T' = 'FakeDerived'}}
// expected-note@-2 {{where 'T' = 'T1'}}
// expected-note@-3 2 {{where 'T' = 'Base<Int>'}}
func conformsToBaseIntAndP2WithWhereClause<T>(_: T) where T : Base<Int> & P2 {}
// expected-note@-1 {{where 'T' = 'FakeDerived'}}
@@ -420,10 +421,10 @@ func conformsTo<T1 : P2, T2 : Base<Int> & P2>(
// about `& P2` in generic parameter.
conformsToBaseIntAndP2(base)
// expected-error@-1 {{argument type 'Base<Int>' does not conform to expected type 'P2'}}
// expected-error@-1 {{global function 'conformsToBaseIntAndP2' requires that 'Base<Int>' conform to 'P2'}}
conformsToBaseIntAndP2(badBase)
// expected-error@-1 {{argument type 'Base<Int>' does not conform to expected type 'P2'}}
// expected-error@-1 {{global function 'conformsToBaseIntAndP2' requires that 'Base<Int>' conform to 'P2'}}
// expected-error@-2 {{cannot convert value of type 'Base<String>' to expected argument type 'Base<Int>'}}
conformsToBaseIntAndP2(fakeDerived)

View File

@@ -25,20 +25,20 @@ class SomeMethods {
// Test self-conformance
func takesObjCClass<T : ObjCClass>(_: T) {} // expected-note {{where 'T' = 'ObjCProtocol'}}
func takesObjCProtocol<T : ObjCProtocol>(_: T) {}
func takesObjCClassAndProtocol<T : ObjCClass & ObjCProtocol>(_: T) {} // expected-note {{where 'T' = 'ObjCProtocol'}}
func takesObjCProtocol<T : ObjCProtocol>(_: T) {} // expected-note {{where 'T' = 'ObjCClass'}}
func takesObjCClassAndProtocol<T : ObjCClass & ObjCProtocol>(_: T) {} // expected-note {{where 'T' = 'ObjCProtocol'}} expected-note {{where 'T' = 'ObjCClass'}}
func testSelfConformance(c: ObjCClass, p: ObjCProtocol, cp: ObjCClass & ObjCProtocol) {
takesObjCClass(c)
takesObjCClass(p) // expected-error {{global function 'takesObjCClass' requires that 'ObjCProtocol' inherit from 'ObjCClass'}}
takesObjCClass(cp)
takesObjCProtocol(c) // expected-error {{argument type 'ObjCClass' does not conform to expected type 'ObjCProtocol'}}
takesObjCProtocol(c) // expected-error {{global function 'takesObjCProtocol' requires that 'ObjCClass' conform to 'ObjCProtocol'}}
takesObjCProtocol(p)
takesObjCProtocol(cp)
// FIXME: Bad diagnostics
takesObjCClassAndProtocol(c) // expected-error {{argument type 'ObjCClass' does not conform to expected type 'ObjCProtocol'}}
takesObjCClassAndProtocol(c) // expected-error {{global function 'takesObjCClassAndProtocol' requires that 'ObjCClass' conform to 'ObjCProtocol'}}
takesObjCClassAndProtocol(p) // expected-error {{global function 'takesObjCClassAndProtocol' requires that 'ObjCProtocol' inherit from 'ObjCClass'}}
takesObjCClassAndProtocol(cp)
}