Files
swift-mirror/test/Constraints/casts_objc.swift
Mark Lacey a61a6d536e Conditionalize warnings for IUO-to-Any coercion on Swift version.
These warnings are turning out to be pretty noisy for code that
declares IUOs (e.g. for @IBOutlets) and then passes them to
Objective-C APIs with parameters declared as _Nonnull id.

Since we bridge non-nil values successfully in most cases, and
previuosly written and correctly executing code is either not seeing
nil values passed in or are handling the nil (which is bridged as
NSNull), it seems like a nuisance to warn about these for existing
Swift versions.

We'll conditionalize the warning, and then users can deal with these
when moving to the new language version.

Fixes: rdar://problem/39886178
2018-05-07 15:49:56 -07:00

97 lines
3.6 KiB
Swift

// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -typecheck -verify %s
// REQUIRES: objc_interop
import Foundation
struct NotClass {}
class SomeClass {}
func nsobject_as_class_cast<T>(_ x: NSObject, _: T) {
let _ = x is AnyObject.Type
let _ = x as! AnyObject.Type
let _ = x as? AnyObject.Type
let _ = x is Any.Type
let _ = x as! Any.Type
let _ = x as? Any.Type
let _ = x is SomeClass.Type
let _ = x as! SomeClass.Type
let _ = x as? SomeClass.Type
let _ = x is T.Type
let _ = x as! T.Type
let _ = x as? T.Type
let _ = x is NotClass.Type // expected-warning{{cast from 'NSObject' to unrelated type 'NotClass.Type' always fails}}
let _ = x as! NotClass.Type // expected-warning{{cast from 'NSObject' to unrelated type 'NotClass.Type' always fails}}
let _ = x as? NotClass.Type // expected-warning{{cast from 'NSObject' to unrelated type 'NotClass.Type' always fails}}
}
// <rdar://problem/20294245> QoI: Error message mentions value rather than key for subscript
func test(_ a : CFString!, b : CFString) {
let dict = NSMutableDictionary()
let object = NSObject()
dict[a] = object
dict[b] = object
}
// <rdar://problem/22507759> QoI: poor error message for invalid unsafeDowncast()
let r22507759: NSObject! = "test" as NSString
let _: NSString! = unsafeDowncast(r22507759) // expected-error {{missing argument for parameter 'to' in call}}
// rdar://problem/29496775 / SR-3319
func sr3319(f: CGFloat, n: NSNumber) {
let _ = [f].map { $0 as NSNumber }
let _ = [n].map { $0 as! CGFloat }
}
func alwaysSucceedingConditionalCasts(f: CGFloat, n: NSNumber) {
let _ = f as? NSNumber // expected-warning{{conditional cast from 'CGFloat' to 'NSNumber' always succeeds}}
let _ = n as? CGFloat
}
func optionalityReducingCasts(f: CGFloat?, n: NSNumber?) {
let _ = f as? NSNumber // expected-warning{{conditional downcast from 'CGFloat?' to 'NSNumber' is a bridging conversion; did you mean to use 'as'?}}
let _ = f as! NSNumber // expected-warning{{forced cast from 'CGFloat?' to 'NSNumber' only unwraps and bridges; did you mean to use '!' with 'as'?}}
let _ = n as? CGFloat
let _ = n as! CGFloat
}
func optionalityMatchingCasts(f: CGFloat?, n: NSNumber?) {
let _ = f as NSNumber?
let _ = f as? NSNumber? // expected-warning{{conditional cast from 'CGFloat?' to 'NSNumber?' always succeeds}}
let _ = f as! NSNumber? // expected-warning{{forced cast from 'CGFloat?' to 'NSNumber?' always succeeds; did you mean to use 'as'?}}{{13-16=as}}
let _ = n as? CGFloat?
let _ = n as! CGFloat?
}
func optionalityMatchingCastsIUO(f: CGFloat?!, n: NSNumber?!) {
let _ = f as NSNumber?
let _ = f as? NSNumber? // expected-warning{{conditional downcast from 'CGFloat??' to 'NSNumber?' is a bridging conversion; did you mean to use 'as'?}}
let _ = f as! NSNumber? // expected-warning{{forced cast from 'CGFloat??' to 'NSNumber?' only unwraps and bridges; did you mean to use '!' with 'as'?}}
let _ = n as? CGFloat?
let _ = n as! CGFloat?
}
func optionalityMismatchingCasts(f: CGFloat, n: NSNumber, fooo: CGFloat???,
nooo: NSNumber???) {
_ = f as NSNumber?
_ = f as NSNumber??
let _ = fooo as NSNumber?? // expected-error{{'CGFloat???' is not convertible to 'NSNumber??'; did you mean to use 'as!' to force downcast?}}
let _ = fooo as NSNumber???? // okay: injects extra optionals
}
func anyObjectCasts(xo: [Int]?, xooo: [Int]???, x: [Int]) {
_ = x as AnyObject
_ = x as AnyObject?
_ = xo as AnyObject
_ = xo as AnyObject?
_ = xooo as AnyObject??
_ = xooo as AnyObject???
_ = xooo as AnyObject???? // okay: injects extra optionals
}