1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231
|
// RUN: %target-typecheck-verify-swift -enable-objc-interop
// -----------------------------------------------------------------------
// Declaring optional requirements
// -----------------------------------------------------------------------
@objc class ObjCClass { }
@objc protocol P1 {
@objc optional func method(_ x: Int) // expected-note {{requirement 'method' declared here}}
@objc optional var prop: Int { get }
@objc optional subscript (i: Int) -> ObjCClass? { get }
}
@objc protocol P2 {
@objc(objcMethodWithInt:)
optional func method(y: Int) // expected-note 1{{requirement 'method(y:)' declared here}}
}
// -----------------------------------------------------------------------
// Providing witnesses for optional requirements
// -----------------------------------------------------------------------
// One does not have provide a witness for an optional requirement
class C1 : P1 { }
// ... but it's okay to do so.
class C2 : P1 {
@objc func method(_ x: Int) { }
@objc var prop: Int = 0
@objc subscript (i: Int) -> ObjCClass? {
get {
return nil
}
set {}
}
}
class C3 : P1 {
func method(_ x: Int) { }
var prop: Int = 0
subscript (i: Int) -> ObjCClass? {
get {
return nil
}
set {}
}
}
class C4 { }
extension C4 : P1 {
func method(_ x: Int) { }
var prop: Int { return 5 }
subscript (i: Int) -> ObjCClass? {
get {
return nil
}
set {}
}
}
// -----------------------------------------------------------------------
// Okay to match via extensions.
// -----------------------------------------------------------------------
class C5 : P1 { }
extension C5 {
func method(_ x: Int) { }
var prop: Int { return 5 }
subscript (i: Int) -> ObjCClass? {
get {
return nil
}
set {}
}
}
// Note: @nonobjc suppresses witness match.
class C6 { }
extension C6 : P1 {
@nonobjc func method(_ x: Int) { }
@nonobjc var prop: Int { return 5 }
@nonobjc subscript (i: Int) -> ObjCClass? {
get {
return nil
}
set {}
}
}
// -----------------------------------------------------------------------
// "Near" matches.
// -----------------------------------------------------------------------
// Note: warn about selector matches where the Swift names didn't match.
@objc class C7 : P1 { // expected-note{{class 'C7' declares conformance to protocol 'P1' here}}
@objc(method:) func otherMethod(x: Int) { } // expected-error{{Objective-C method 'method:' provided by method 'otherMethod(x:)' conflicts with optional requirement method 'method' in protocol 'P1'}}
// expected-note@-1{{rename method to match requirement 'method'}}{{23-34=method}}{{35-35=_ }}
}
@objc class C8 : P2 { // expected-note{{class 'C8' declares conformance to protocol 'P2' here}}
@objc func objcMethod(int x: Int) { } // expected-error{{Objective-C method 'objcMethodWithInt:' provided by method 'objcMethod(int:)' conflicts with optional requirement method 'method(y:)' in protocol 'P2'}}
// expected-note@-1{{rename method to match requirement 'method(y:)'}}{{14-24=method}}{{25-28=y}}{{none}}
}
// -----------------------------------------------------------------------
// Using optional requirements
// -----------------------------------------------------------------------
// Optional method references in generics.
func optionalMethodGeneric<T : P1>(_ t: T) {
// Infers a value of optional type.
var methodRef = t.method
// Make sure it's an optional
methodRef = .none
// ... and that we can call it.
methodRef!(5)
}
// Optional property references in generics.
func optionalPropertyGeneric<T : P1>(_ t: T) {
// Infers a value of optional type.
var propertyRef = t.prop
// Make sure it's an optional
propertyRef = .none
// ... and that we can use it
let i = propertyRef!
_ = i as Int
}
// Optional subscript references in generics.
func optionalSubscriptGeneric<T : P1>(_ t: T) {
// Infers a value of optional type.
var subscriptRef = t[5]
// Make sure it's an optional
subscriptRef = .none
// ... and that we can use it
let i = subscriptRef!
_ = i as ObjCClass?
}
// Optional method references in existentials.
func optionalMethodExistential(_ t: P1) {
// Infers a value of optional type.
var methodRef = t.method
// Make sure it's an optional
methodRef = .none
// ... and that we can call it.
methodRef!(5)
}
// Optional property references in existentials.
func optionalPropertyExistential(_ t: P1) {
// Infers a value of optional type.
var propertyRef = t.prop
// Make sure it's an optional
propertyRef = .none
// ... and that we can use it
let i = propertyRef!
_ = i as Int
}
// Optional subscript references in existentials.
func optionalSubscriptExistential(_ t: P1) {
// Infers a value of optional type.
var subscriptRef = t[5]
// Make sure it's an optional
subscriptRef = .none
// ... and that we can use it
let i = subscriptRef!
_ = i as ObjCClass?
}
// -----------------------------------------------------------------------
// Restrictions on the application of optional
// -----------------------------------------------------------------------
// optional cannot be used on non-protocol declarations
optional var optError: Int = 10 // expected-error{{'optional' can only be applied to protocol members}} {{1-10=}}
optional struct optErrorStruct { // expected-error{{'optional' modifier cannot be applied to this declaration}} {{1-10=}}
optional var ivar: Int // expected-error{{'optional' can only be applied to protocol members}} {{3-12=}}
optional func foo() { } // expected-error{{'optional' can only be applied to protocol members}} {{3-12=}}
}
optional class optErrorClass { // expected-error{{'optional' modifier cannot be applied to this declaration}} {{1-10=}}
optional var ivar: Int = 0 // expected-error{{'optional' can only be applied to protocol members}} {{3-12=}}
optional func foo() { } // expected-error{{'optional' can only be applied to protocol members}} {{3-12=}}
}
protocol optErrorProtocol {
optional func foo(_ x: Int) // expected-error{{'optional' can only be applied to members of an @objc protocol}}
}
@objc protocol optObjcAttributeProtocol {
optional func foo(_ x: Int) // expected-error{{'optional' requirements are an Objective-C compatibility feature; add '@objc'}}{{3-3=@objc }}
optional var bar: Int { get } // expected-error{{'optional' requirements are an Objective-C compatibility feature; add '@objc'}}{{3-3=@objc }}
optional associatedtype Assoc // expected-error{{'optional' modifier cannot be applied to this declaration}} {{3-12=}}
// expected-error@-1 {{associated type 'Assoc' cannot be declared inside '@objc' protocol 'optObjcAttributeProtocol'}}
}
@objc protocol optionalInitProto {
@objc optional init() // expected-error{{'optional' cannot be applied to an initializer}}
}
|