You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Consider a concrete type T extending a protocol P (class T : protocol P)
Cast an instance of T? (optional) to Any, and then downcast it :
it seems valid to downcast to T (i.e : it works)
on the contrary, downcasting to P yields a runtime exception :
Could not cast value of type 'Swift.Optional<T>' to 'P'
Is there any reason why downcasting to a class and downcasting to a protocol implemented by the same class should yield different results ?
I think one should either get an exception in both cases, or no exception at all.
Rmq : this issue is not purely theoretical ; I bumped into it when sending optional values to a Swift pod making heavy use of generics (and heavy use of downcasts...)
Test case
Paste this in the main.swift of an XCode 7.3 OSX Command Line Tool project :
protocolFooProtocol {
funcdoSomething()
}
classFoo: FooProtocol {
funcdoSomething() {
print("hello")
}
}
letoptionalFoo : Foo? = Foo()
letanyValue: Any = optionalFooletfoo1 = anyValueas! Foofoo1.doSomething() // prints 'hello', okletfoo2 = anyValueas! FooProtocol// Could not cast value of type 'Swift.Optional<Foo>' to 'FooProtocol'foo2.doSomething()
The text was updated successfully, but these errors were encountered:
Yeah, there are definitely some funny edge-cases around optionals. I would stay away from casts that inject or eliminate optionality altogether, and use other constructs, such as pattern matching, instead.
Having said that, we should definitely address these issues, it is just that at this point it is not even completely clear what the correct behavior should be.
Thanks a lot for your quick feedback.
I guess it's related to other issues such as SR-912.
I'll try to workaround this using pattern matching as you suggest.
#33561 should fix this for the non-optimized case (where the cast is being handled by the runtime). There may still be issues with optimized casts, though.
Environment
XCode 7.3
Swift 2.2
OSX 10.11.5
(also crashes with Swift 3)
Additional Detail from JIRA
md5: a4bc4c2e8aa88d6efc7c6a9cfcd04be5
relates to:
Issue Description:
Description
Consider a concrete type
T
extending a protocolP
(class T : protocol P
)Cast an instance of
T?
(optional) toAny
, and then downcast it :it seems valid to downcast to
T
(i.e : it works)on the contrary, downcasting to
P
yields a runtime exception :Is there any reason why downcasting to a class and downcasting to a protocol implemented by the same class should yield different results ?
I think one should either get an exception in both cases, or no exception at all.
Rmq : this issue is not purely theoretical ; I bumped into it when sending optional values to a Swift pod making heavy use of generics (and heavy use of downcasts...)
Test case
Paste this in the main.swift of an XCode 7.3 OSX Command Line Tool project :
The text was updated successfully, but these errors were encountered: