// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -typecheck -parse-as-library -verify -verify-ignore-unrelated -swift-version 4 -I %S/Inputs/custom-modules %s // REQUIRES: objc_interop import Foundation import objc_generics import ObjCBridgeNonconforming func testNSArrayBridging(_ hive: Hive) { _ = hive.bees as [Bee] } func testNSDictionaryBridging(_ hive: Hive) { _ = hive.beesByName as [String : Bee] // expected-error{{value of optional type '[String : Bee]?' must be unwrapped to a value of type '[String : Bee]'}} // expected-note@-1 {{force-unwrap using '!' to abort execution if the optional value contains 'nil'}} // expected-note@-2 {{coalesce using '??' to provide a default when the optional value contains 'nil'}} var dict1 = hive.anythingToBees let dict2: [AnyHashable : Bee] = dict1 dict1 = dict2 } func testNSSetBridging(_ hive: Hive) { _ = hive.allBees as Set } public func expectType(_: T.Type, _ x: inout T) {} func testNSMutableDictionarySubscript( _ dict: NSMutableDictionary, key: NSCopying, value: Any) { var oldValue = dict[key] expectType(Optional.self, &oldValue) dict[key] = value } class C {} struct S {} func f(_ x: GenericClass) -> NSString? { return x.thing() } func f1(_ x: GenericClass) -> NSString? { return x.otherThing() } func f2(_ x: GenericClass) -> Int32 { return x.count() } func f3(_ x: GenericClass) -> NSString? { return x.propertyThing } func f4(_ x: GenericClass) -> [NSString] { return x.arrayOfThings() } func f5(_ x: GenericClass) -> [C] { return x.arrayOfThings() } func f6(_ x: GenericSubclass) -> NSString? { return x.thing() } func f6(_ x: GenericSubclass) -> C? { return x.thing() } func g() -> NSString? { return GenericClass.classThing() } func g1() -> NSString? { return GenericClass.otherClassThing() } func h(_ s: NSString?) -> GenericClass { return GenericClass(thing: s) } func j(_ x: GenericClass?) { takeGenericClass(x) } class Desk {} class Rock: NSObject, Pettable { required init(fur: Any) {} func other() -> Self { return self } class func adopt() -> Self { fatalError("") } func pet() {} func pet(with other: Pettable) {} class var needingMostPets: Pettable { get { fatalError("") } set { } } } class Porcupine: Animal { } class Cat: Animal, Pettable { required init(fur: Any) {} func other() -> Self { return self } class func adopt() -> Self { fatalError("") } func pet() {} func pet(with other: Pettable) {} class var needingMostPets: Pettable { get { fatalError("") } set { } } } func testImportedTypeParamRequirements() { let _ = PettableContainer() // expected-error{{type 'Desk' does not conform to protocol 'Pettable'}} let _ = PettableContainer() let _ = PettableContainer() // expected-error{{type 'Porcupine' does not conform to protocol 'Pettable'}} let _ = PettableContainer() let _ = AnimalContainer() // expected-error{{'AnimalContainer' requires that 'Desk' inherit from 'Animal'}} // TODO: add test for note appearing in Obj-c header. let _ = AnimalContainer() // expected-error{{'AnimalContainer' requires that 'Rock' inherit from 'Animal'}} // TODO: add test for note appearing in Obj-c header. let _ = AnimalContainer() let _ = AnimalContainer() let _ = PettableAnimalContainer() // expected-error{{'PettableAnimalContainer' requires that 'Desk' inherit from 'Animal'}} // TODO: add test for note appearing in Obj-c header. let _ = PettableAnimalContainer() // expected-error{{'PettableAnimalContainer' requires that 'Rock' inherit from 'Animal'}} // TODO: add test for note appearing in Obj-c header. let _ = PettableAnimalContainer() // expected-error{{type 'Porcupine' does not conform to protocol 'Pettable'}} let _ = PettableAnimalContainer() } extension GenericClass { @objc func doesntUseGenericParam() {} @objc func doesntUseGenericParam2() -> Self {} // Doesn't use 'T', since ObjC class type params are type-erased @objc func doesntUseGenericParam3() -> GenericClass {} // Doesn't use 'T', since its metadata isn't necessary to pass around instance @objc func doesntUseGenericParam4(_ x: T, _ y: T.Type) -> T { _ = x _ = y return x } // Doesn't use 'T', since its metadata isn't necessary to erase to AnyObject // or to existential metatype @objc func doesntUseGenericParam5(_ x: T, _ y: T.Type) -> T { _ = y as AnyObject.Type _ = y as Any.Type _ = y as AnyObject _ = x as AnyObject } // expected-error@+1{{extension of a generic Objective-C class cannot access the class's generic parameters}} func usesGenericParamC(_ x: [(T, T)]?) {} // expected-note{{used here}} // expected-error@+1{{extension of a generic Objective-C class cannot access the class's generic parameters}} @objc func usesGenericParamD(_ x: Int) { _ = T.self // expected-note{{used here}} } // expected-error@+1{{extension of a generic Objective-C class cannot access the class's generic parameters}} @objc func usesGenericParamE(_ x: Int) { _ = x as? T // expected-note{{used here}} } // expected-error@+1{{extension of a generic Objective-C class cannot access the class's generic parameters}} @objc func usesGenericParamF(_ x: Int) { _ = x is T // expected-note{{used here}} } // expected-error@+1{{extension of a generic Objective-C class cannot access the class's generic parameters}} @objc func usesGenericParamG(_ x: T) { _ = T.self // expected-note{{used here}} } @objc func doesntUseGenericParamH(_ x: T) { _ = x as Any } // expected-error@+1{{extension of a generic Objective-C class cannot access the class's generic parameters}} @objc func usesGenericParamI(_ y: T.Type) { _ = y as Any // expected-note{{used here}} } // expected-error@+1{{extension of a generic Objective-C class cannot access the class's generic parameters}} func usesGenericParamJ() -> [(T, T)]? {} // expected-note{{used here}} @objc static func doesntUseGenericParam() {} @objc static func doesntUseGenericParam2() -> Self {} // Doesn't technically use 'T', since it's type-erased at runtime @objc static func doesntUseGenericParam3() -> GenericClass {} // expected-error@+1{{extension of a generic Objective-C class cannot access the class's generic parameters}} static func usesGenericParamC(_ x: [(T, T)]?) {} // expected-note{{used here}} // expected-error@+1{{extension of a generic Objective-C class cannot access the class's generic parameters}} @objc static func usesGenericParamD(_ x: Int) { _ = T.self // expected-note{{used here}} } // expected-error@+1{{extension of a generic Objective-C class cannot access the class's generic parameters}} @objc static func usesGenericParamE(_ x: Int) { _ = x as? T // expected-note{{used here}} } // expected-error@+1{{extension of a generic Objective-C class cannot access the class's generic parameters}} @objc static func usesGenericParamF(_ x: Int) { _ = x is T // expected-note{{used here}} } @objc func checkThatMethodsAreObjC() { _ = #selector(GenericClass.doesntUseGenericParam) _ = #selector(GenericClass.doesntUseGenericParam2) _ = #selector(GenericClass.doesntUseGenericParam3) _ = #selector(GenericClass.doesntUseGenericParam4) _ = #selector(GenericClass.doesntUseGenericParam5) } } func swiftFunction(x: T) {} extension AnimalContainer { @objc func doesntUseGenericParam1(_ x: T, _ y: T.Type) { _ = #selector(x.another) _ = #selector(y.create) } @objc func doesntUseGenericParam2(_ x: T, _ y: T.Type) { let a = x.another() _ = a.another() _ = x.another().another() _ = type(of: x).create().another() _ = type(of: x).init(noise: x).another() _ = y.create().another() _ = y.init(noise: x).another() _ = y.init(noise: x.another()).another() x.eat(a) } @objc func doesntUseGenericParam3(_ x: T, _ y: T.Type) { let sup: Animal = x sup.eat(x) _ = x.buddy _ = x[0] x[0] = x } @objc func doesntUseGenericParam4(_ x: T, _ y: T.Type) { _ = type(of: x).apexPredator.another() type(of: x).apexPredator = x _ = y.apexPredator.another() y.apexPredator = x } @objc func doesntUseGenericParam5(y: T) { var x = y x = y _ = x } @objc func doesntUseGenericParam6(y: T?) { var x = y x = y _ = x } // Doesn't use 'T', since dynamic casting to an ObjC generic class doesn't // check its generic parameters @objc func doesntUseGenericParam7() { _ = (self as AnyObject) as! GenericClass _ = (self as AnyObject) as? GenericClass _ = (self as AnyObject) as! AnimalContainer _ = (self as AnyObject) as? AnimalContainer _ = (self as AnyObject) is AnimalContainer _ = (self as AnyObject) is AnimalContainer } // Dynamic casting to the generic parameter would require its generic params, // though // expected-error@+1{{extension of a generic Objective-C class cannot access the class's generic parameters}} @objc func usesGenericParamZ1() { _ = (self as AnyObject) as! T //expected-note{{here}} } // expected-error@+1{{extension of a generic Objective-C class cannot access the class's generic parameters}} @objc func usesGenericParamZ2() { _ = (self as AnyObject) as? T //expected-note{{here}} } // expected-error@+1{{extension of a generic Objective-C class cannot access the class's generic parameters}} @objc func usesGenericParamZ3() { _ = (self as AnyObject) is T //expected-note{{here}} } // expected-note@+2{{add '@objc' to allow uses of 'self' within the function body}}{{3-3=@objc }} // expected-error@+1{{extension of a generic Objective-C class cannot access the class's generic parameters}} func usesGenericParamA(_ x: T) { _ = T(noise: x) // expected-note{{used here}} } // expected-note@+2{{add '@objc' to allow uses of 'self' within the function body}}{{3-3=@objc }} // expected-error@+1{{extension of a generic Objective-C class cannot access the class's generic parameters}} func usesGenericParamB() { _ = T.create() // expected-note{{used here}} } // expected-note@+2{{add '@objc' to allow uses of 'self' within the function body}}{{3-3=@objc }} // expected-error@+1{{extension of a generic Objective-C class cannot access the class's generic parameters}} func usesGenericParamC() { _ = T.apexPredator // expected-note{{used here}} } // expected-note@+2{{add '@objc' to allow uses of 'self' within the function body}}{{3-3=@objc }} // expected-error@+1{{extension of a generic Objective-C class cannot access the class's generic parameters}} func usesGenericParamD(_ x: T) { T.apexPredator = x // expected-note{{used here}} } // rdar://problem/27796375 -- allocating init entry points for ObjC // initializers are generated as true Swift generics, so reify type // parameters. // expected-note@+2{{add '@objc' to allow uses of 'self' within the function body}}{{3-3=@objc }} // expected-error@+1{{extension of a generic Objective-C class cannot access the class's generic parameters}} func usesGenericParamE(_ x: T) { _ = GenericClass(thing: x) // expected-note{{used here}} } @objc func checkThatMethodsAreObjC() { _ = #selector(AnimalContainer.doesntUseGenericParam1) _ = #selector(AnimalContainer.doesntUseGenericParam2) _ = #selector(AnimalContainer.doesntUseGenericParam3) _ = #selector(AnimalContainer.doesntUseGenericParam4) } // rdar://problem/26283886 @objc func funcWithWrongArgType(x: NSObject) {} @objc func crashWithInvalidSubscript(x: NSArray) { _ = funcWithWrongArgType(x: x[12]) // expected-error@-1{{cannot convert value of type 'Any' to expected argument type 'NSObject'}} } } extension PettableContainer { @objc func doesntUseGenericParam(_ x: T, _ y: T.Type) { // TODO: rdar://problem/27796375--allocating entry points are emitted as // true generics. // _ = type(of: x).init(fur: x).other() _ = type(of: x).adopt().other() // _ = y.init(fur: x).other() _ = y.adopt().other() x.pet() x.pet(with: x) } // TODO: rdar://problem/27796375--allocating entry points are emitted as // true generics. // expected-error@+1{{extension of a generic Objective-C class cannot access the class's generic parameters}} @objc func usesGenericParamZ1(_ x: T, _ y: T.Type) { _ = type(of: x).init(fur: x).other() // expected-note{{used here}} } // expected-error@+1{{extension of a generic Objective-C class cannot access the class's generic parameters}} @objc func usesGenericParamZ2(_ x: T, _ y: T.Type) { _ = y.init(fur: x).other() // expected-note{{used here}} } // expected-error@+1{{extension of a generic Objective-C class cannot access the class's generic parameters}} @objc func usesGenericParamA(_ x: T) { _ = T(fur: x) // expected-note{{used here}} } // expected-error@+1{{extension of a generic Objective-C class cannot access the class's generic parameters}} @objc func usesGenericParamB(_ x: T) { _ = T.adopt() // expected-note{{used here}} } // expected-error@+1{{extension of a generic Objective-C class cannot access the class's generic parameters}} @objc func usesGenericParamC(_ x: T) { _ = T.needingMostPets // expected-note{{used here}} } // expected-error@+1{{extension of a generic Objective-C class cannot access the class's generic parameters}} @objc func usesGenericParamD(_ x: T) { T.needingMostPets = x // expected-note{{used here}} } @objc func checkThatMethodsAreObjC() { _ = #selector(PettableContainer.doesntUseGenericParam) } } // expected-error@+1{{inheritance from a generic Objective-C class 'GenericClass' must bind type parameters of 'GenericClass' to specific concrete types}} class SwiftGenericSubclassA: GenericClass {} // expected-error@+1{{inheritance from a generic Objective-C class 'GenericClass' must bind type parameters of 'GenericClass' to specific concrete types}} class SwiftGenericSubclassB: GenericClass> {} // expected-error@+1{{inheritance from a generic Objective-C class 'GenericClass' must bind type parameters of 'GenericClass' to specific concrete types}} class SwiftGenericSubclassC: GenericClass {} class SwiftConcreteSubclassA: GenericClass { override init(thing: AnyObject) { } override func thing() -> AnyObject? { } override func count() -> Int32 { } override class func classThing() -> AnyObject? { } override func arrayOfThings() -> [AnyObject] {} } class SwiftConcreteSubclassB: GenericClass { override init(thing: NSString) { } override func thing() -> NSString? { } override func count() -> Int32 { } override class func classThing() -> NSString? { } override func arrayOfThings() -> [NSString] {} } class SwiftConcreteSubclassC: GenericClass { override init(thing: NSString) { } override func thing() -> NSString? { } override func count() -> Int32 { } override class func classThing() -> NSString? { } override func arrayOfThings() -> [NSString] {} } // FIXME: Some generic ObjC APIs rely on covariance. We don't handle this well // in Swift yet, but ensure we don't emit spurious warnings when // `as!` is used to force types to line up. func foo(x: GenericClass) { let x2 = x as! GenericClass takeGenericClass(x2) takeGenericClass(unsafeBitCast(x, to: GenericClass.self)) } // Test type-erased bounds func getContainerForPanda() -> AnimalContainer { return Panda.getContainer() } func getContainerForFungiblePanda() -> FungibleAnimalContainer { return Panda.getFungibleContainer() } // rdar://problem/30832766 - Infinite recursion while checking conformance // to AnyObject let third: Third! = Third() func useThird() { _ = third.description } func testNonconforming(bnc: ObjCBridgeNonconforming) { let _: Int = bnc.foo // expected-error{{cannot convert value of type 'Set' to specified type 'Int'}} } func testHashableGenerics( any: ObjCBridgeGeneric, constrained: ObjCBridgeGenericConstrained, insufficient: ObjCBridgeGenericInsufficientlyConstrained, extra: ObjCBridgeGenericConstrainedExtra, existential: ObjCBridgeExistential) { let _: Int = any.foo // expected-error{{cannot convert value of type 'Set' to specified type 'Int'}} let _: Int = constrained.foo // expected-error{{cannot convert value of type 'Set' to specified type 'Int'}} let _: Int = insufficient.foo // expected-error{{cannot convert value of type 'Set' to specified type 'Int'}} let _: Int = extra.foo // expected-error{{cannot convert value of type 'Set' to specified type 'Int'}} let _: Int = existential.foo // expected-error{{cannot convert value of type 'Set' to specified type 'Int'}} } func testGenericsWithTypedefBlocks(hba: HasBlockArray) { let _: Int = hba.blockArray() // expected-error{{type '[@convention(block) () -> Void]'}} }