Skip to content

Commit f709192

Browse files
authored
Merge pull request #70990 from slavapestov/check-conformance-invariant
Enforce that checkConformance() is not called with interface types
2 parents 0842787 + 9835a6f commit f709192

File tree

4 files changed

+27
-4
lines changed

4 files changed

+27
-4
lines changed

lib/AST/ConformanceLookup.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -728,6 +728,8 @@ LookupConformanceInModuleRequest::evaluate(
728728
ProtocolConformanceRef
729729
ModuleDecl::checkConformance(Type type, ProtocolDecl *proto,
730730
bool allowMissing) {
731+
assert(!type->hasTypeParameter());
732+
731733
auto lookupResult = lookupConformance(type, proto, allowMissing);
732734
if (lookupResult.isInvalid()) {
733735
return ProtocolConformanceRef::forInvalid();

lib/IDE/ConformingMethodList.cpp

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -174,8 +174,19 @@ void ConformingMethodListCallbacks::getMatchingMethods(
174174
if (FD->isStatic() || FD->isOperator())
175175
return false;
176176

177-
auto resultTy = T->getTypeOfMember(CurModule, FD,
178-
FD->getResultInterfaceType());
177+
assert(!T->hasTypeParameter());
178+
179+
// T may contain primary archetypes from some fixed generic signature G.
180+
// This might be unrelated to the generic signature of FD. However if
181+
// FD has a generic parameter of its own and it returns a type containing
182+
// that parameter, we want to map it to the corresponding archetype
183+
// from the generic environment of FD, because all we do with the
184+
// resulting type is check conformance. If the conformance is conditional,
185+
// we might run into trouble with really complicated cases but the fake
186+
// archetype setup will mostly work.
187+
auto substitutions = T->getMemberSubstitutionMap(
188+
CurModule, FD, FD->getGenericEnvironment());
189+
auto resultTy = FD->getResultInterfaceType().subst(substitutions);
179190
if (resultTy->is<ErrorType>())
180191
return false;
181192

lib/Sema/TypeCheckDeclPrimary.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1396,7 +1396,7 @@ static void diagnoseClassWithoutInitializers(ClassDecl *classDecl) {
13961396
if (auto *superclassDecl = classDecl->getSuperclassDecl()) {
13971397
auto *decodableProto = C.getProtocol(KnownProtocolKind::Decodable);
13981398
auto superclassType = superclassDecl->getDeclaredInterfaceType();
1399-
auto ref = classDecl->getParentModule()->checkConformance(
1399+
auto ref = classDecl->getParentModule()->lookupConformance(
14001400
superclassType, decodableProto);
14011401
if (ref) {
14021402
// super conforms to Decodable, so we've failed to inherit init(from:).
@@ -1425,7 +1425,7 @@ static void diagnoseClassWithoutInitializers(ClassDecl *classDecl) {
14251425
// likely that the user forgot to override its encode(to:). In this case,
14261426
// we can produce a slightly different diagnostic to suggest doing so.
14271427
auto *encodableProto = C.getProtocol(KnownProtocolKind::Encodable);
1428-
auto ref = classDecl->getParentModule()->checkConformance(
1428+
auto ref = classDecl->getParentModule()->lookupConformance(
14291429
superclassType, encodableProto);
14301430
if (ref) {
14311431
// We only want to produce this version of the diagnostic if the

test/decl/protocol/special/coding/class_codable_inheritance_diagnostics.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,3 +97,13 @@ class EncodableSubWithoutInitialValue : CodableSuper { // expected-error {{class
9797
class CodableSubWithInitialValue : CodableSuper {
9898
var value2 = 10
9999
}
100+
101+
class GenericCodableSuper<T>: Decodable {}
102+
103+
class GenericCodableSub<T>: GenericCodableSuper<T> {
104+
// expected-error@-1 {{class 'GenericCodableSub' has no initializers}}
105+
// expected-note@-2 {{did you mean to override 'init(from:)'?}}
106+
// expected-warning@-2 {{'required' initializer 'init(from:)' must be provided by subclass of 'GenericCodableSuper<T>'; this is an error in Swift 6}}
107+
var t: T
108+
// expected-note@-1 {{stored property 't' without initial value prevents synthesized initializers}}
109+
}

0 commit comments

Comments
 (0)