// 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 NSRange: Hashable {} 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