I do have a thought what it will print in both versions.
For version 5.0, it prints:
URLError
proto hello
In version 5.3, it prints:
NSError
:(
And I have an answer why following expression works:
let error = URLError(.badURL) as NSError
print(type(of: a)) // NSError
This works for both versions of Swift.
It relates to autobridging in swift, there are a range of types that exist in swift which have counterparts in objective-c .. NSString <--> String is another example.
So, I believe this is because the struct URLError conforms to Error protocol, and the class NSError conforms to Error protocol, so it is like Error protocol is the bridge for this casting .. I kinda feel sense for it.
But,
I am a URLError
Casted up to Error
Asked at runtime what type you actually are
Should I reply I am NSError?!! is NSError is in the between anyway?
Swift 5.0 does see the actual object which is URLError, but Swift 5.3 doesn't.
When I pass the object already casted to NSError:
value(URLError(.badURL) as NSError)
Then both of them see it as NSError at then end:
print(type(of: error)) // NSError
Which I feel sense about this case.
After I finished this comment, I feel was it like a buggy behavior in 5.0 and fixed in later versions? And once you cast up any type conforming to Error protocol, its actual type gone hidden from runtime check?