mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
The type checker implements logic for handling checked casts in two
places: the constraint solver (for type-checking expressions
containing "as!" or "as?") and as a top-level entrypoint for
type-checking as?/as! for diagnostics and is/as patterns. Needless to
say, the two implementations were inconsistent, and in fact both were
wrong, leading to various problems---rejecting perfectly-valid "as!"
and "as?" casts outright, bogus warnings that particular as!/as? casts
always-succeed or always-fail when they wouldn't, and so on.
Start detangling the mess in two ways. First, drastically simplify the
handling of checked casts in the constraint solver, eliminating the
unprincipled "subtype" constraint checks that (among other things)
broke the handling of checked casts that involved bridging or optional
unwrapping. The simpler code is more permissive and more correct; it
essentially accepts that the user knows what she is doing with the
cast.
Second, make the type checker's checking of casts far more thorough,
which includes:
* When we're performing a collection cast, actually check that the
element types (and key types, for a dictionary) are castable, rather
than assuming all collection casts are legitimate. This means we'll
get more useful "always fails" and "always succeeds" diagnostics for
array/set/dictionary.
* Handle casts from a bridged value type to a subclass of the
corresponding bridged class type. Previously, these would be
incorrectly classified as "always fails".
While I'm here, eliminate a spurious diagnostic that occurs when using
a conditional cast ("as?") that could have been a coercion/bridging
conversion ("as"). The optional injection we synthesize to get the
resulting type correct was getting diagnosed as an implicit coercion,
but shouldn't have been.
161 KiB
161 KiB