mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
_BridgedNSError conformances can affect the runtime behavior of dynamic casts (e.g. 'is'). Unfortunately, the conformance is not always emitted, in an effort to save space when not used. This change forces the conformance witness tables to be emitted when we can detect a dynamic cast to an _BridgedNSError conforming enum. Test cases included, as well as a note about a potentially erroneous path that is not currently handled: when the dynamic cast occurs in a generic function to a generic type (and thus we are unsure which conformances we need to pull in).
91 lines
3.1 KiB
Swift
91 lines
3.1 KiB
Swift
// REQUIRES: OS=macosx
|
|
|
|
// RUN: %target-swift-frontend -DNONE -emit-sil %s -import-objc-header %S/Inputs/enum-error.h | FileCheck %s -check-prefix=NONE
|
|
// RUN: %target-swift-frontend -DEMPTYCATCH -emit-sil %s -import-objc-header %S/Inputs/enum-error.h | FileCheck %s -check-prefix=EMPTYCATCH
|
|
// RUN: %target-swift-frontend -DASQEXPR -emit-sil %s -import-objc-header %S/Inputs/enum-error.h | FileCheck %s -check-prefix=ASQEXPR
|
|
// RUN: %target-swift-frontend -DASBANGEXPR -emit-sil %s -import-objc-header %S/Inputs/enum-error.h | FileCheck %s -check-prefix=ASBANGEXPR
|
|
// RUN: %target-swift-frontend -DCATCHIS -emit-sil %s -import-objc-header %S/Inputs/enum-error.h | FileCheck %s -check-prefix=CATCHIS
|
|
// RUN: %target-swift-frontend -DCATCHAS -emit-sil %s -import-objc-header %S/Inputs/enum-error.h | FileCheck %s -check-prefix=CATCHAS
|
|
// RUN: %target-swift-frontend -DGENERICONLY -emit-sil %s -import-objc-header %S/Inputs/enum-error.h | FileCheck %s -check-prefix=GENERICONLY
|
|
|
|
// RUN: %target-swift-frontend -emit-sil %s -import-objc-header %S/Inputs/enum-error.h -verify
|
|
|
|
import Foundation
|
|
|
|
|
|
func testError() {
|
|
let testErrorNSError = NSError(domain: TestErrorDomain,
|
|
code: Int(TestError.TENone.rawValue),
|
|
userInfo: nil)
|
|
|
|
// Below are a number of test cases to make sure that various pattern and cast
|
|
// expression forms are sufficient in pulling in th _NSBridgedError
|
|
// conformance.
|
|
#if NONE
|
|
// NONE-NOT: TestError: _BridgedNSError
|
|
let terr = getErr(); terr
|
|
|
|
#elseif EMPTYCATCH
|
|
// EMPTYCATCH-NOT: TestError: _BridgedNSError
|
|
do {
|
|
throw TestError.TENone
|
|
} catch {}
|
|
|
|
#elseif ASQEXPR
|
|
// ASQEXPR: sil_witness_table shared TestError: _BridgedNSError module __ObjC
|
|
let wasTestError = testErrorNSError as? TestError; wasTestError
|
|
|
|
#elseif ASBANGEXPR
|
|
// ASBANGEXPR: sil_witness_table shared TestError: _BridgedNSError module __ObjC
|
|
let terr2 = testErrorNSError as! TestError; terr2
|
|
|
|
#elseif ISEXPR
|
|
// ISEXPR: sil_witness_table shared TestError: _BridgedNSError module __ObjC
|
|
if (testErrorNSError is TestError) {
|
|
print("true")
|
|
} else {
|
|
print("false")
|
|
}
|
|
|
|
#elseif CATCHIS
|
|
// CATCHIS: sil_witness_table shared TestError: _BridgedNSError module __ObjC
|
|
do {
|
|
throw TestError.TETwo
|
|
} catch is TestError {
|
|
} catch {}
|
|
|
|
#elseif CATCHAS
|
|
// CATCHAS: sil_witness_table shared TestError: _BridgedNSError module __ObjC
|
|
do {
|
|
throw TestError.TETwo
|
|
} catch let err as TestError {
|
|
err
|
|
} catch {}
|
|
|
|
#elseif GENERICONLY
|
|
// FIXME: THE BELOW IS WRONG! This alone doesn't pull in the conformance, but it should.
|
|
// GENERICONLY-NOT: TestError: _BridgedNSError
|
|
func dyncast<T, U>(x: T) -> U {
|
|
return x as! U
|
|
}
|
|
let _ : TestError = dyncast(testErrorNSError)
|
|
|
|
#else
|
|
// CHECK: sil_witness_table shared TestError: _BridgedNSError module __ObjC
|
|
let terr = getErr()
|
|
switch (terr) { case .TENone, .TEOne, .TETwo: break } // ok
|
|
|
|
switch (terr) { case .TENone, .TEOne: break }
|
|
// expected-error@-1 {{switch must be exhaustive, consider adding a default clause}}
|
|
|
|
let _ = TestError(rawValue: 2)!
|
|
|
|
do {
|
|
throw TestError.TEOne
|
|
} catch is TestError {
|
|
} catch {}
|
|
|
|
#endif
|
|
|
|
}
|