blob: 6103e21d2cadcb146fa515e404addb7e360f44fc [file] [log] [blame]
// RUN: %target-typecheck-verify-swift -enable-objc-interop
// Test "near misses" where a member of a class or extension thereof
// nearly matches an optional requirement, but does not exactly match.
@objc protocol P1 {
@objc optional func doSomething(a: Int, b: Double) // expected-note 2{{requirement 'doSomething(a:b:)' declared here}}
}
class C1a : P1 {
@objc func doSomething(a: Int, c: Double) { }
// expected-warning@-1{{instance method 'doSomething(a:c:)' nearly matches optional requirement 'doSomething(a:b:)' of protocol 'P1'}}
// expected-note@-2{{rename to 'doSomething(a:b:)' to satisfy this requirement}}{{34-34=b }}
// expected-note@-3{{move 'doSomething(a:c:)' to an extension to silence this warning}}
// expected-note@-4{{make 'doSomething(a:c:)' private to silence this warning}}{{9-9=private }}
}
class C1b : P1 {
}
extension C1b {
@objc func doSomething(a: Int, c: Double) { } // don't warn
}
class C1c {
}
extension C1c : P1 {
func doSomething(a: Int, c: Double) { }
// expected-warning@-1{{instance method 'doSomething(a:c:)' nearly matches optional requirement 'doSomething(a:b:)' of protocol 'P1'}}
// expected-note@-2{{rename to 'doSomething(a:b:)' to satisfy this requirement}}{{28-28=b }}{{none}}
// expected-note@-3{{move 'doSomething(a:c:)' to another extension to silence this warning}}
// expected-note@-4{{make 'doSomething(a:c:)' private to silence this warning}}{{3-3=private }}
}
class C1d : P1 {
@objc private func doSomething(a: Int, c: Double) { } // don't warn
}
class C1e : P1 {
@nonobjc func doSomething(a: Int, c: Double) { } // don't warn
}
// Don't try to match an optional requirement against a declaration
// that already satisfies one witness.
@objc protocol P2 {
@objc optional func doSomething(a: Int, b: Double)
@objc optional func doSomething(a: Int, d: Double)
}
class C2a : P2 {
@objc func doSomething(a: Int, b: Double) { } // don't warn: this matches something
}
// Cope with base names that change.
@objc protocol P3 {
@objc optional func doSomethingWithPriority(_ a: Int, d: Double) // expected-note{{requirement 'doSomethingWithPriority(_:d:)' declared here}}
}
class C3a : P3 {
func doSomething(priority: Int, d: Double) { }
// expected-warning@-1{{instance method 'doSomething(priority:d:)' nearly matches optional requirement 'doSomethingWithPriority(_:d:)' of protocol 'P3'}}
// expected-note@-2{{rename to 'doSomethingWithPriority(_:d:)' to satisfy this requirement}}{{20-20=_ }}
// expected-note@-3{{move 'doSomething(priority:d:)' to an extension to silence this warning}}
// expected-note@-4{{make 'doSomething(priority:d:)' private to silence this warning}}{{3-3=private }}
}
@objc protocol P4 {
@objc optional func doSomething(priority: Int, d: Double) // expected-note{{requirement 'doSomething(priority:d:)' declared here}}
}
class C4a : P4 {
func doSomethingWithPriority(_ a: Int, d: Double) { }
// expected-warning@-1{{instance method 'doSomethingWithPriority(_:d:)' nearly matches optional requirement 'doSomething(priority:d:)' of protocol 'P4'}}
// expected-note@-2{{rename to 'doSomething(priority:d:)' to satisfy this requirement}}{{32-33=priority}}
// expected-note@-3{{move 'doSomethingWithPriority(_:d:)' to an extension to silence this warning}}
// expected-note@-4{{make 'doSomethingWithPriority(_:d:)' private to silence this warning}}{{3-3=private }}
}
@objc class SomeClass { }
@objc protocol P5 {
@objc optional func methodWithInt(_: Int, forSomeClass: SomeClass, dividingDouble: Double)
// expected-note@-1{{requirement 'methodWithInt(_:forSomeClass:dividingDouble:)' declared here}}
}
class C5a : P5 {
func method(_: Int, for someClass: SomeClass, dividing double: Double) { }
// expected-warning@-1{{instance method 'method(_:for:dividing:)' nearly matches optional requirement 'methodWithInt(_:forSomeClass:dividingDouble:)' of protocol 'P5'}}
// expected-note@-2{{rename to 'methodWithInt(_:forSomeClass:dividingDouble:)' to satisfy this requirement}}{{8-14=methodWithInt}}{{23-26=forSomeClass}}{{49-57=dividingDouble}}{{none}}
// expected-note@-3{{move 'method(_:for:dividing:)' to an extension to silence this warning}}
// expected-note@-4{{make 'method(_:for:dividing:)' private to silence this warning}}{{3-3=private }}
}
@objc protocol P6 {
@objc optional func method(_: Int, for someClass: SomeClass, dividing double: Double)
// expected-note@-1{{requirement 'method(_:for:dividing:)' declared here}}
}
class C6a : P6 {
func methodWithInt(_: Int, forSomeClass: SomeClass, dividingDouble: Double) { }
// expected-warning@-1{{instance method 'methodWithInt(_:forSomeClass:dividingDouble:)' nearly matches optional requirement 'method(_:for:dividing:)' of protocol 'P6'}}
// expected-note@-2{{rename to 'method(_:for:dividing:)' to satisfy this requirement}}{{8-21=method}}{{30-30=for }}{{55-55=dividing }}{{none}}
// expected-note@-3{{move 'methodWithInt(_:forSomeClass:dividingDouble:)' to an extension to silence this warning}}
// expected-note@-4{{make 'methodWithInt(_:forSomeClass:dividingDouble:)' private to silence this warning}}{{3-3=private }}
}
// Use the first note to always describe why it didn't match.
@objc protocol P7 {
@objc optional func method(foo: Float)
// expected-note@-1{{requirement 'method(foo:)' declared here}}
}
class C7a : P7 {
@objc func method(foo: Double) { }
// expected-warning@-1{{instance method 'method(foo:)' nearly matches optional requirement 'method(foo:)' of protocol 'P7'}}
// expected-note@-2{{candidate has non-matching type '(Double) -> ()'}}
// expected-note@-3{{move 'method(foo:)' to an extension to silence this warning}}
// expected-note@-4{{make 'method(foo:)' private to silence this warning}}
}
// Don't complain about near misses that satisfy other protocol
// requirements.
@objc protocol P8 {
@objc optional func foo(exactMatch: Int)
}
@objc protocol P9 : P8 {
@objc optional func foo(nearMatch: Int)
}
class C8Super : P8 { }
class C9Sub : C8Super, P9 {
func foo(exactMatch: Int) { }
}
// Don't complain about overriding methods that are near misses;
// the user cannot make it satisfy the protocol requirement.
class C10Super {
func foo(nearMatch: Int) { }
}
class C10Sub : C10Super, P8 {
override func foo(nearMatch: Int) { }
}
// Be more strict about near misses than we had previously.
@objc protocol P11 {
@objc optional func foo(wibble: Int)
}
class C11 : P11 {
func f(waggle: Int) { } // no warning
}