mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
A protocol extension initializer creates a new instance of the static type of Self at the call site. However a convenience initializer in a class is expected to initialize an instance of the dynamic type of the 'self' value, because convenience initializers can be inherited by subclasses. This means that when a convenience initializer delegates to a protocol extension initializer, we have to substitute the 'Self' type in the protocol extension generic signature with the DynamicSelfType, and not the static type. Since the substitution is formed from the type of the 'self' parameter in the class convenience initializer, the solution is to change the type of 'self' in a class convenience initializer to DynamicSelfType, just like we do for methods that return 'Self'. This fixes cases where we allowed code to type check that should not type check (if the protocol extension initializer has 'Self' in contravariant position, and we pass in an instance of the static type). It also fixes a miscompile with valid code -- if the protocol extension initializer was implemented by calling 'Self()', it would again use the static type and not the dynamic type. Note that the SILGen change is necessary because Sema now creates CovariantReturnExprs that convert a static class type to DynamicSelfType, but the latter lowers to the former at the SIL level, so we have to peephole away unnecessary unchecked_ref_cast instructions in this case. Because this change breaks source compatibility, it is guarded by a '-swift-version 5' check.
10 KiB
10 KiB