mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
To be safe, protocol witnesses need to be as available as their requirements.
Otherwise, the programmer could access an unavailable declaration by upcasting
to the protocol type and accessing the declaration via its requirement.
Prior to this commit, we enforced safety by requiring that the annotated
available range of a requirement must be completely contained within the
annotated available range of the witness.
However, there are cases where this requirement is too restrictive. Suppose
there is some super class Super with an availability-restricted method f():
class Super {
@availability(iOS, introduced=6.0)
void func f() { ... }
}
Further, suppose there is a protocol HasF with unrestricted availability:
protocol HasF {
void func f()
}
and then a limited-availability class Sub extends Super and declares a
conformance to HasF:
@availability(iOS, introduced=8.0)
class Sub: Super, HasF {
}
Sub does conform to HasF: the witness for HasF's f() requirement is Super's f().
But Super's f() is less available (iOS 6 and up) than HasF's f() requires
(all versions) and so--prior to this commit--the compiler would emit
an error.
This error is too conservative. The conforming type, Sub,
is only available on iOS 8.0 and later. And, given an environment of iOS 8.0
and later, the availability of the requirement and the witness is the same, so
the conformance is safe.
This false alarm arises in UIKit, where Super is UIView, HasF
is UIGestureRecognizerDelegate, and f() is gestureRecognizerShouldBegin().
The fix is to change the safety requirement for protocol witnesses:
we now require that the intersection of the availabilities of the conforming
type and the protocol requirement is fully contained in the intersection of the
availabilities of the conforming type and the witness. It does not matter if
the containment does not hold for versions on which the conforming type is not
available.
rdar://problem/20693144
Swift SVN r27712
6.5 KiB
6.5 KiB