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
|
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -typecheck -I %S/Inputs/custom-modules -disable-availability-checking %s -verify
// REQUIRES: objc_interop
// REQUIRES: concurrency
import Foundation
import ObjCConcurrency
// Conform via async method
class C1: ConcurrentProtocol {
func askUser(toSolvePuzzle puzzle: String) async throws -> String { "" }
func askUser(toJumpThroughHoop hoop: String) async -> String { "hello" }
}
// try to conform to an objc protocol that has both a sync and async requirement
// that has the same name, and both requirements are optional.
class C2 : NSObject, OptionalObserver {}
extension C2 {
func hello(_ session: NSObject) -> Bool { true }
}
// a version of C2 that requires both sync and async methods (differing only by
// completion handler) in ObjC.
class C3 : NSObject, RequiredObserver {}
extension C3 {
func hello() -> Bool { true }
func hello() async -> Bool { true }
}
// the only way to conform to 'RequiredObserver' in Swift is to not use 'async'
class C4 : NSObject, RequiredObserver {}
extension C4 {
func hello() -> Bool { true }
func hello(_ completion : @escaping (Bool) -> Void) -> Void { completion(true) }
}
protocol Club : ObjCClub {}
class ConformsToSync : NSObject, Club {
func activate( completion: @escaping ( Error? ) -> Void ) { }
}
///////
// selector conflicts
// attempting to satisfy the ObjC async requirement in two ways simultaneously
// is problematic due to a clash in selector names on this ObjC-compatible type
class SelectorConflict : NSObject, RequiredObserverOnlyCompletion {
func hello() async -> Bool { true } // expected-note {{method 'hello()' declared here}}
// expected-error@+1 {{method 'hello' with Objective-C selector 'hello:' conflicts with method 'hello()' with the same Objective-C selector}}
func hello(_ completion : @escaping (Bool) -> Void) -> Void { completion(true) }
}
// making either one of the two methods nonobjc fixes it:
class SelectorOK1 : NSObject, RequiredObserverOnlyCompletion {
@nonobjc func hello() async -> Bool { true }
func hello(_ completion : @escaping (Bool) -> Void) -> Void { completion(true) }
}
class SelectorOK2 : NSObject, RequiredObserverOnlyCompletion {
func hello() async -> Bool { true }
@nonobjc func hello(_ completion : @escaping (Bool) -> Void) -> Void { completion(true) }
}
// can declare an @objc protocol with both selectors...
@objc protocol SelectorBothAsyncProto {
@objc(helloWithCompletion:)
func hello() async -> Bool
@available(*, renamed: "hello()")
@objc(helloWithCompletion:)
func hello(completion: @escaping (Bool) -> Void)
}
// and conform by implementing either one...
class SelectorBothAsync1: NSObject, SelectorBothAsyncProto {
func hello() async -> Bool { true }
}
class SelectorBothAsync2: NSObject, SelectorBothAsyncProto {
func hello(completion: @escaping (Bool) -> Void) { completion(true) }
}
// but not without declaring the async alternative.
@objc protocol BadSelectorBothAsyncProto {
@objc(helloWithCompletion:)
func hello() async -> Bool // expected-note {{method 'hello()' declared here}}
@objc(helloWithCompletion:)
func hello(completion: @escaping (Bool) -> Void) // expected-warning {{method 'hello(completion:)' with Objective-C selector 'helloWithCompletion:' conflicts with method 'hello()' with the same Objective-C selector; this is an error in the Swift 6 language mode}}
}
// additional coverage for situation like C4, where the method names don't
// clash on the ObjC side, but they do on Swift side, BUT their ObjC selectors
// differ, so it's OK.
class Rock : NSObject, Rollable {
func roll(completionHandler: @escaping () -> Void) { completionHandler() }
func roll() { roll(completionHandler: {}) }
}
// additional coverage for a situation where only an argument label differs, excluding the completion handler.
final class Moon : LabellyProtocol {
func myMethod(_ value: Int, foo: Int) {}
func myMethod(_ value: Int, newFoo foo: Int, completion: @escaping (Error?) -> Void) {}
}
// Crash involving actor isolation checking.
class C5 {
@MainActor @objc var allOperations: [String] = []
}
class C6: C5, ServiceProvider {
@MainActor func allOperations() async -> [String] { [] }
}
extension ImplementsLoadable: @retroactive Loadable {
public func loadStuff(withOtherIdentifier otherIdentifier: Int, reply: @escaping () -> Void) {}
}
|