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
Sema: Improve the 'protocol method can't impose new requirements on Self' check
This check had two problems. First, it would assert upon encountering
a layout requirement, due to an unimplemented code path.
A more fundamental issue is that the logic wasn't fully sound, because
it would miss certain cases, for example:
protocol P {
associatedtype A
func run<B: Equatable>(_: B) where B == Self.A
}
Here, the reduced type of `Self.A` is `B`, and at first glance, the
requirement `B: Equatable` appears to be fine. However, this
is actually a new requirement on `Self`, and the protocol be rejected.
Now that we can change the reduction order by assigning weights to
generic parameters, this check can be implemented in a better way,
by building a new generic signature first, where all generic
parameters introduced by the protocol method, like 'B' above, are
assigned a non-zero weight.
With this reduction order, any type that is equivalent to
a member type of `Self` will have a reduced type rooted in `Self`,
at which point the previous syntactic check becomes sound.
Since this may cause us to reject code we accepted previously,
the type checker now performs the check once: first on the original
signature, which may miss certain cases, and then again on the new
signature built with the weighted reduction order.
If the first check fails, we diagnose an error. If the second
check fails, we only diagnose a warning.
However, this warning will become an error soon, and it really
can cause compiler crashes and miscompiles to have a malformed
protocol like this.
Fixes rdar://116938972.
// expected-warning@-1 {{instance method requirement 'bad1' cannot add constraint 'Self.A1: Equatable' on 'Self'; this will be an error in a future Swift language mode}}
120
+
121
+
func bad2<B>(_:B)where A1 ==[B]
122
+
// expected-warning@-1 {{instance method requirement 'bad2' cannot add constraint 'Self.A1 == [B]' on 'Self'; this will be an error in a future Swift language mode}}
123
+
124
+
func good<B>(_:B)where A2 ==B // This is fine
125
+
126
+
func bad3<B, C>(_:B, _:C)where A2 ==B, B.A3 ==[C]
127
+
// expected-warning@-1 {{instance method requirement 'bad3' cannot add constraint 'Self.A2.A3 == Array<C>' on 'Self'; this will be an error in a future Swift language mode}}
0 commit comments