mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
[Runtime] Have swift_dynamicCast unwrap multiple levels of optionals in the source.
The real work is done in checkDynamicCastFromOptional. This code tried to unwrap the source and returned the payload on success. It only did this once, so a type like Optional<Optional<Int>> would come out as Optional<Int> and then a cast to Int would fail. This change makes checkDynamicCastFromOptional recursive, which makes it unwrap as many levels of Optional as it encounters. Fixes rdar://problem/40171034 and SR-7664.
This commit is contained in:
@@ -50,6 +50,26 @@ CastsTests.test("No overrelease of existential boxes in failed casts") {
|
||||
|
||||
extension Int : P {}
|
||||
|
||||
// Test for SR-7664: Inconsistent optional casting behaviour with generics
|
||||
// Runtime failed to unwrap multiple levels of Optional when casting.
|
||||
CastsTests.test("Multi-level optionals can be casted") {
|
||||
func testSuccess<From, To>(_ x: From, from: From.Type, to: To.Type) {
|
||||
expectNotNil(x as? To)
|
||||
}
|
||||
func testFailure<From, To>(_ x: From, from: From.Type, to: To.Type) {
|
||||
expectNil(x as? To)
|
||||
}
|
||||
testSuccess(42, from: Int?.self, to: Int.self)
|
||||
testSuccess(42, from: Int??.self, to: Int.self)
|
||||
testSuccess(42, from: Int???.self, to: Int.self)
|
||||
testSuccess(42, from: Int???.self, to: Int?.self)
|
||||
testSuccess(42, from: Int???.self, to: Int??.self)
|
||||
testSuccess(42, from: Int???.self, to: Int???.self)
|
||||
testFailure(42, from: Int?.self, to: String.self)
|
||||
testFailure(42, from: Int??.self, to: String.self)
|
||||
testFailure(42, from: Int???.self, to: String.self)
|
||||
}
|
||||
|
||||
#if _runtime(_ObjC)
|
||||
extension CFBitVector : P {
|
||||
static func makeImmutable(from values: Array<UInt8>) -> CFBitVector {
|
||||
|
||||
Reference in New Issue
Block a user