| // RUN: rm -rf %t |
| // RUN: mkdir -p %t |
| // RUN: %gyb %s -o %t/bridging-nsnumber-and-nsvalue.swift |
| // RUN: %target-swift-frontend -typecheck -verify %t/bridging-nsnumber-and-nsvalue.swift -swift-version 3 |
| |
| // REQUIRES: objc_interop |
| |
| // Swift 3.0 accepted "nsNumber as Int" or "nsValue as NSRect" as if they were |
| // safe coercions, when in fact they may fail if the object doesn't represent |
| // the right Swift type. |
| |
| import Foundation |
| import CoreGraphics |
| |
| %{ |
| coercionTypes = { |
| 'NSNumber': [ |
| 'Int', |
| 'UInt', |
| 'Int64', |
| 'UInt64', |
| 'Int32', |
| 'UInt32', |
| 'Int16', |
| 'UInt16', |
| 'Int8', |
| 'UInt8', |
| 'Float', |
| 'Double', |
| 'CGFloat', |
| ], |
| 'NSValue': [ |
| 'CGRect', |
| 'CGPoint', |
| 'CGSize', |
| 'NSRange', |
| ], |
| } |
| }% |
| |
| // For testing purposes, make everything Hashable. Don't do this at home |
| extension Equatable { |
| public static func ==(x: Self, y: Self) -> Bool { |
| fatalError("hella cray") |
| } |
| } |
| extension Hashable { public var hashValue: Int { fatalError("trill hiphy") } } |
| extension CGSize: Hashable {} |
| extension CGPoint: Hashable {} |
| extension CGRect: Hashable {} |
| |
| % for ObjectType, ValueTypes in coercionTypes.items(): |
| func bridgeNSNumberBackToSpecificType(object: ${ObjectType}, |
| optional: ${ObjectType}?, |
| array: [${ObjectType}], |
| dictKeys: [${ObjectType}: Any], |
| dictValues: [AnyHashable: ${ObjectType}], |
| dictBoth: [${ObjectType}: ${ObjectType}], |
| set: Set<${ObjectType}>) { |
| % for Type in ValueTypes: |
| _ = object as ${Type} // expected-warning{{use 'as!'}} |
| _ = object is ${Type} |
| _ = object as? ${Type} |
| _ = object as! ${Type} |
| |
| _ = optional as ${Type}? // expected-warning{{use 'as!'}} |
| _ = optional is ${Type}? |
| _ = optional as? ${Type}? |
| _ = optional as! ${Type}? |
| |
| // NB: This remains an error, since optional-to-nonoptional requires a |
| // nil check |
| _ = optional as ${Type} // expected-error{{use 'as!'}} |
| _ = optional is ${Type} |
| _ = optional as? ${Type} |
| _ = optional as! ${Type} |
| |
| _ = array as [${Type}] // expected-warning{{use 'as!'}} |
| _ = array is [${Type}] |
| _ = array as? [${Type}] |
| _ = array as! [${Type}] |
| |
| _ = dictKeys as [${Type}: Any] // expected-warning{{use 'as!'}} |
| _ = dictKeys is [${Type}: Any] |
| _ = dictKeys as? [${Type}: Any] |
| _ = dictKeys as! [${Type}: Any] |
| |
| _ = dictKeys as [${Type}: AnyObject] // expected-warning{{use 'as!'}} |
| _ = dictKeys is [${Type}: AnyObject] |
| _ = dictKeys as? [${Type}: AnyObject] |
| _ = dictKeys as! [${Type}: AnyObject] |
| |
| _ = dictValues as [AnyHashable: ${Type}] // expected-warning{{use 'as!'}} |
| _ = dictValues is [AnyHashable: ${Type}] |
| _ = dictValues as? [AnyHashable: ${Type}] |
| _ = dictValues as! [AnyHashable: ${Type}] |
| |
| _ = dictValues as [NSObject: ${Type}] // expected-warning{{use 'as!'}} |
| _ = dictValues is [NSObject: ${Type}] |
| _ = dictValues as? [NSObject: ${Type}] |
| _ = dictValues as! [NSObject: ${Type}] |
| |
| _ = dictBoth as [${ObjectType}: ${Type}] // expected-warning{{use 'as!'}} |
| _ = dictBoth is [${ObjectType}: ${Type}] |
| _ = dictBoth as? [${ObjectType}: ${Type}] |
| _ = dictBoth as! [${ObjectType}: ${Type}] |
| |
| _ = dictBoth as [${Type}: ${ObjectType}] // expected-warning{{use 'as!'}} |
| _ = dictBoth is [${Type}: ${ObjectType}] |
| _ = dictBoth as? [${Type}: ${ObjectType}] |
| _ = dictBoth as! [${Type}: ${ObjectType}] |
| |
| _ = dictBoth as [${Type}: ${Type}] // expected-warning{{use 'as!'}} |
| _ = dictBoth is [${Type}: ${Type}] |
| _ = dictBoth as? [${Type}: ${Type}] |
| _ = dictBoth as! [${Type}: ${Type}] |
| |
| _ = set as Set<${Type}> // expected-warning{{use 'as!'}} |
| _ = set is Set<${Type}> |
| _ = set as? Set<${Type}> |
| _ = set as! Set<${Type}> |
| % end |
| |
| _ = object is String // expected-warning{{always fails}} |
| _ = [object] is String // expected-warning{{always fails}} |
| _ = object as? String // expected-warning{{always fails}} |
| _ = object as! String // expected-warning{{always fails}} |
| } |
| % end |