Skip to content

Commit db3f708

Browse files
committed
Sema: Diagnose invalid overrides involving contextual where clauses
1 parent f14604e commit db3f708

File tree

2 files changed

+74
-20
lines changed

2 files changed

+74
-20
lines changed

lib/AST/ASTContext.cpp

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4470,19 +4470,22 @@ ASTContext::getOverrideGenericSignature(const ValueDecl *base,
44704470
assert(isa<AbstractFunctionDecl>(base) || isa<SubscriptDecl>(base));
44714471
assert(isa<AbstractFunctionDecl>(derived) || isa<SubscriptDecl>(derived));
44724472

4473-
auto baseClass = base->getDeclContext()->getSelfClassDecl();
4474-
auto derivedClass = derived->getDeclContext()->getSelfClassDecl();
4473+
const auto baseClass = base->getDeclContext()->getSelfClassDecl();
4474+
const auto derivedClass = derived->getDeclContext()->getSelfClassDecl();
44754475

44764476
assert(baseClass != nullptr);
44774477
assert(derivedClass != nullptr);
44784478

4479-
auto baseGenericSig = base->getAsGenericContext()->getGenericSignature();
4480-
auto derivedGenericSig = derived->getAsGenericContext()->getGenericSignature();
4479+
const auto baseGenericSig =
4480+
base->getAsGenericContext()->getGenericSignature();
4481+
const auto derivedGenericSig =
4482+
derived->getAsGenericContext()->getGenericSignature();
44814483

44824484
if (base == derived)
44834485
return derivedGenericSig;
44844486

4485-
if (derivedClass->getSuperclass().isNull())
4487+
const auto derivedSuperclass = derivedClass->getSuperclass();
4488+
if (derivedSuperclass.isNull())
44864489
return nullptr;
44874490

44884491
if (derivedGenericSig.isNull())
@@ -4491,12 +4494,6 @@ ASTContext::getOverrideGenericSignature(const ValueDecl *base,
44914494
if (baseGenericSig.isNull())
44924495
return derivedGenericSig;
44934496

4494-
auto baseClassSig = baseClass->getGenericSignature();
4495-
auto subMap = derivedClass->getSuperclass()->getContextSubstitutionMap(
4496-
derivedClass->getModuleContext(), baseClass);
4497-
4498-
unsigned derivedDepth = 0;
4499-
45004497
auto key = OverrideSignatureKey(baseGenericSig,
45014498
derivedGenericSig,
45024499
derivedClass);
@@ -4506,22 +4503,25 @@ ASTContext::getOverrideGenericSignature(const ValueDecl *base,
45064503
return getImpl().overrideSigCache.lookup(key);
45074504
}
45084505

4509-
if (auto derivedSig = derivedClass->getGenericSignature())
4510-
derivedDepth = derivedSig->getGenericParams().back()->getDepth() + 1;
4506+
const auto derivedClassSig = derivedClass->getGenericSignature();
4507+
4508+
unsigned derivedDepth = 0;
4509+
unsigned baseDepth = 0;
4510+
if (derivedClassSig)
4511+
derivedDepth = derivedClassSig->getGenericParams().back()->getDepth() + 1;
4512+
if (const auto baseClassSig = baseClass->getGenericSignature())
4513+
baseDepth = baseClassSig->getGenericParams().back()->getDepth() + 1;
45114514

45124515
SmallVector<GenericTypeParamType *, 2> addedGenericParams;
4513-
if (auto *gpList = derived->getAsGenericContext()->getGenericParams()) {
4516+
if (const auto *gpList = derived->getAsGenericContext()->getGenericParams()) {
45144517
for (auto gp : *gpList) {
45154518
addedGenericParams.push_back(
45164519
gp->getDeclaredInterfaceType()->castTo<GenericTypeParamType>());
45174520
}
45184521
}
45194522

4520-
unsigned baseDepth = 0;
4521-
4522-
if (baseClassSig) {
4523-
baseDepth = baseClassSig->getGenericParams().back()->getDepth() + 1;
4524-
}
4523+
const auto subMap = derivedSuperclass->getContextSubstitutionMap(
4524+
derivedClass->getModuleContext(), baseClass);
45254525

45264526
auto substFn = [&](SubstitutableType *type) -> Type {
45274527
auto *gp = cast<GenericTypeParamType>(type);
@@ -4553,7 +4553,7 @@ ASTContext::getOverrideGenericSignature(const ValueDecl *base,
45534553
auto genericSig = evaluateOrDefault(
45544554
evaluator,
45554555
AbstractGenericSignatureRequest{
4556-
derivedClass->getGenericSignature().getPointer(),
4556+
derivedClassSig.getPointer(),
45574557
std::move(addedGenericParams),
45584558
std::move(addedRequirements)},
45594559
GenericSignature());

test/attr/attr_override.swift

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -579,6 +579,60 @@ class SR_4206_DerivedGeneric_6<T>: SR_4206_BaseConcrete_6 {
579579
override func foo<T: SR_4206_Protocol_1>(arg: T) {} // expected-error {{overridden method 'foo' has generic signature <T, T where T : SR_4206_Protocol_1> which is incompatible with base method's generic signature <T where T : SR_4206_Protocol_2>; expected generic signature to be <T, T where T : SR_4206_Protocol_2>}}
580580
}
581581

582+
// Where clauses on contextually generic declarations
583+
584+
class SR_4206_Base_7<T> {
585+
func foo1() where T: SR_4206_Protocol_1 {} // expected-note {{overridden declaration is here}}
586+
func foo2() where T: SR_4206_Protocol_1 {}
587+
}
588+
589+
class SR_4206_Derived_7<T>: SR_4206_Base_7<T> {
590+
override func foo1() where T: SR_4206_Protocol_2 {} // expected-error {{overridden method 'foo1' has generic signature <T where T : SR_4206_Protocol_2> which is incompatible with base method's generic signature <T where T : SR_4206_Protocol_1>; expected generic signature to be <T where τ_0_0 : SR_4206_Protocol_1>}}
591+
592+
override func foo2() {} // OK
593+
}
594+
595+
// Subclass with new constraint on inherited generic param
596+
597+
class SR_4206_Base_8<T> {
598+
func foo() where T: SR_4206_Protocol_1 {}
599+
}
600+
class SR_4206_Derived_8<T: SR_4206_Protocol_2, U>: SR_4206_Base_8<T> {
601+
override func foo() where T: SR_4206_Protocol_1 {} // OK
602+
}
603+
604+
// Same-type to conformance visibility reabstraction
605+
606+
class SR_4206_Base_9<T> {
607+
func foo() where T == Int {}
608+
}
609+
class SR_4206_Derived_9<T>: SR_4206_Base_9<T> {
610+
override func foo() where T: FixedWidthInteger {} // OK
611+
}
612+
613+
// Override with constraint on a non-inherited generic param
614+
615+
class SR_4206_Base_10<T> {
616+
func foo() where T: SR_4206_Protocol_1 {} // expected-note {{overridden declaration is here}}
617+
}
618+
class SR_4206_Derived_10<T, U>: SR_4206_Base_10<T> {
619+
override func foo() where U: SR_4206_Protocol_1 {} // expected-error {{overridden method 'foo' has generic signature <T, U where U : SR_4206_Protocol_1> which is incompatible with base method's generic signature <T where T : SR_4206_Protocol_1>; expected generic signature to be <T, U where τ_0_0 : SR_4206_Protocol_1>}}
620+
}
621+
622+
// Override with return type specialization
623+
624+
class SR_4206_Base_11<T> {
625+
// The fact that the return type matches the substitution
626+
// for T must hold across overrides.
627+
func foo() -> T where T: FixedWidthInteger { fatalError() } // expected-note {{potential overridden instance method 'foo()' here}}
628+
}
629+
class SR_4206_Derived_11: SR_4206_Base_11<Int> {
630+
override func foo() -> Int { return .zero } // OK
631+
}
632+
class SR_4206_Derived2_11: SR_4206_Base_11<Bool> {
633+
override func foo() -> Int { return .zero } // expected-error {{method does not override any method from its superclass}}
634+
}
635+
582636
// Misc //
583637

584638
protocol SR_4206_Key {}

0 commit comments

Comments
 (0)