Skip to content

Commit 345185f

Browse files
committed
Sema: Fix isOverrideBasedOnType() to check protocol generic signatures
This avoids feeding invalid type parameters to the Requirement Machine when a protocol requirement looks similar to a protocol requirement in the inherited protocol but has an incompatible type. Fixes https://bugs.swift.org/browse/SR-15826 / rdar://problem/89641535.
1 parent abac604 commit 345185f

File tree

3 files changed

+56
-16
lines changed

3 files changed

+56
-16
lines changed

lib/Sema/TypeCheckDeclOverride.cpp

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -164,25 +164,23 @@ bool swift::isOverrideBasedOnType(const ValueDecl *decl, Type declTy,
164164
//
165165
// We can still succeed with a subtype match later in
166166
// OverrideMatcher::match().
167-
if (decl->getDeclContext()->getSelfClassDecl()) {
168-
if (auto declCtx = decl->getAsGenericContext()) {
169-
auto *parentCtx = parentDecl->getAsGenericContext();
167+
if (auto declCtx = decl->getAsGenericContext()) {
168+
auto *parentCtx = parentDecl->getAsGenericContext();
170169

171-
if (declCtx->isGeneric() != parentCtx->isGeneric())
172-
return false;
170+
if (declCtx->isGeneric() != parentCtx->isGeneric())
171+
return false;
173172

174-
if (declCtx->isGeneric() &&
175-
(declCtx->getGenericParams()->size() !=
176-
parentCtx->getGenericParams()->size()))
177-
return false;
173+
if (declCtx->isGeneric() &&
174+
(declCtx->getGenericParams()->size() !=
175+
parentCtx->getGenericParams()->size()))
176+
return false;
178177

179-
auto &ctx = decl->getASTContext();
180-
auto sig = ctx.getOverrideGenericSignature(parentDecl, decl);
181-
if (sig &&
182-
declCtx->getGenericSignature().getCanonicalSignature() !=
183-
sig.getCanonicalSignature()) {
184-
return false;
185-
}
178+
auto &ctx = decl->getASTContext();
179+
auto sig = ctx.getOverrideGenericSignature(parentDecl, decl);
180+
if (sig &&
181+
declCtx->getGenericSignature().getCanonicalSignature() !=
182+
sig.getCanonicalSignature()) {
183+
return false;
186184
}
187185
}
188186

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// RUN: %target-typecheck-verify-swift
2+
3+
protocol Base {
4+
func foo1<T : P>(_: T, _: T.T)
5+
func foo2<T : P>(_: T, _: T.T)
6+
}
7+
8+
protocol Derived : Base {
9+
func foo1<T : P>(_: T, _: T.T)
10+
func foo2<T : Q>(_: T, _: T.T)
11+
}
12+
13+
protocol P {
14+
associatedtype T
15+
}
16+
17+
protocol Q {
18+
associatedtype T
19+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// RUN: %target-swift-frontend -emit-ir %s
2+
3+
public struct Observable<T> {}
4+
5+
public protocol BaseVariant: CaseIterable, Equatable {}
6+
7+
public protocol FeatureGate {
8+
associatedtype Variant: BaseVariant
9+
}
10+
11+
public enum FeatureVariantState<T: BaseVariant>: Equatable {}
12+
13+
public protocol BaseGatingProvider {
14+
func exposeFeatureVariantState<G: FeatureGate>(for featureGate: G)
15+
-> Observable<FeatureVariantState<G.Variant>>
16+
}
17+
18+
public struct UserFeatureGate<Variant: BaseVariant>: FeatureGate {}
19+
20+
public protocol UserGatingProvider: BaseGatingProvider {
21+
func exposeFeatureVariantState<V>(for featureGate: UserFeatureGate<V>)
22+
-> Observable<FeatureVariantState<V>>
23+
}

0 commit comments

Comments
 (0)