Skip to content

Commit 38d188b

Browse files
committed
Sema: Bake in the old broken behavior for protocol overrides
To avoid breaking the ABI of the standard library and possibly other modules, we can't actually enable the new accurate logic for checking protocol requirement overrides after all. Just skip the check if the protocol requirement is generic to get back the old behavior.
1 parent 345185f commit 38d188b

File tree

2 files changed

+40
-4
lines changed

2 files changed

+40
-4
lines changed

lib/Sema/TypeCheckDeclOverride.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,15 @@ bool swift::isOverrideBasedOnType(const ValueDecl *decl, Type declTy,
165165
// We can still succeed with a subtype match later in
166166
// OverrideMatcher::match().
167167
if (auto declCtx = decl->getAsGenericContext()) {
168+
// The below logic now works correctly for protocol requirements which are
169+
// themselves generic, but that would be an ABI break, since we would now
170+
// drop the protocol requirements from witness tables. Simulate the old
171+
// behavior by not considering generic declarations in protocols as
172+
// overrides at all.
173+
if (decl->getDeclContext()->getSelfProtocolDecl() &&
174+
declCtx->isGeneric())
175+
return false;
176+
168177
auto *parentCtx = parentDecl->getAsGenericContext();
169178

170179
if (declCtx->isGeneric() != parentCtx->isGeneric())
Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
1-
// RUN: %target-typecheck-verify-swift
1+
// RUN: %target-swift-frontend -emit-silgen %s -verify -warn-implicit-overrides | %FileCheck %s
22

33
protocol Base {
4-
func foo1<T : P>(_: T, _: T.T)
4+
func foo1<T : P>(_: T)
55
func foo2<T : P>(_: T, _: T.T)
6+
func foo3<T : P>(_: T, _: T.T)
67
}
78

89
protocol Derived : Base {
9-
func foo1<T : P>(_: T, _: T.T)
10-
func foo2<T : Q>(_: T, _: T.T)
10+
func foo1<T : P>(_: T)
11+
func foo2<T : P>(_: T, _: T.T)
12+
func foo3<T : Q>(_: T, _: T.T)
1113
}
1214

1315
protocol P {
@@ -17,3 +19,28 @@ protocol P {
1719
protocol Q {
1820
associatedtype T
1921
}
22+
23+
struct S : Derived {
24+
func foo1<T : P>(_: T) {}
25+
func foo2<T : P>(_: T, _: T.T) {}
26+
func foo3<T : P>(_: T, _: T.T) {}
27+
func foo3<T : Q>(_: T, _: T.T) {}
28+
}
29+
30+
// Make sure that Derived.foo1 and Derived.foo2 are not counted as overrides of
31+
// Base.foo1 and Base.foo2 respectively. Even though their types match, bugs
32+
// in Swift 5.6 and earlier prevented them from being overrides. We can't fix
33+
// it now because it would be an ABI break.
34+
35+
// CHECK-LABEL: sil_witness_table hidden S: Derived module override_generic {
36+
// CHECK-NEXT: base_protocol Base: S: Base module override_generic
37+
// CHECK-NEXT: method #Derived.foo1: <Self where Self : Derived><T where T : P> (Self) -> (T) -> () : @$s16override_generic1SVAA7DerivedA2aDP4foo1yyqd__AA1PRd__lFTW
38+
// CHECK-NEXT: method #Derived.foo2: <Self where Self : Derived><T where T : P> (Self) -> (T, T.T) -> () : @$s16override_generic1SVAA7DerivedA2aDP4foo2yyqd___1TQyd__tAA1PRd__lFTW
39+
// CHECK-NEXT: method #Derived.foo3: <Self where Self : Derived><T where T : Q> (Self) -> (T, T.T) -> () : @$s16override_generic1SVAA7DerivedA2aDP4foo3yyqd___1TQyd__tAA1QRd__lFTW
40+
// CHECK-NEXT: }
41+
42+
// CHECK-LABEL: sil_witness_table hidden S: Base module override_generic {
43+
// CHECK-NEXT: method #Base.foo1: <Self where Self : Base><T where T : P> (Self) -> (T) -> () : @$s16override_generic1SVAA4BaseA2aDP4foo1yyqd__AA1PRd__lFTW
44+
// CHECK-NEXT: method #Base.foo2: <Self where Self : Base><T where T : P> (Self) -> (T, T.T) -> () : @$s16override_generic1SVAA4BaseA2aDP4foo2yyqd___1TQyd__tAA1PRd__lFTW
45+
// CHECK-NEXT: method #Base.foo3: <Self where Self : Base><T where T : P> (Self) -> (T, T.T) -> () : @$s16override_generic1SVAA4BaseA2aDP4foo3yyqd___1TQyd__tAA1PRd__lFTW
46+
// CHECK-NEXT: }

0 commit comments

Comments
 (0)