Skip to content

Commit ab03052

Browse files
authored
Merge pull request #35727 from slavapestov/inherited-designated-init-with-where-clause
Sema: Fix inherited designated init synthesis when there's a 'where' clause but no new generic parameters
2 parents 94f0e21 + 3dfbf15 commit ab03052

File tree

2 files changed

+63
-39
lines changed

2 files changed

+63
-39
lines changed

lib/Sema/CodeSynthesis.cpp

Lines changed: 41 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -424,51 +424,53 @@ configureGenericDesignatedInitOverride(ASTContext &ctx,
424424
moduleDecl, superclassDecl);
425425

426426
GenericSignature genericSig;
427-
428-
// Inheriting initializers that have their own generic parameters
429427
auto *genericParams = superclassCtor->getGenericParams();
430-
if (genericParams) {
431-
SmallVector<GenericTypeParamDecl *, 4> newParams;
432428

433-
// First, clone the superclass constructor's generic parameter list,
434-
// but change the depth of the generic parameters to be one greater
435-
// than the depth of the subclass.
436-
unsigned depth = 0;
437-
if (auto genericSig = classDecl->getGenericSignature())
438-
depth = genericSig->getGenericParams().back()->getDepth() + 1;
439-
440-
for (auto *param : genericParams->getParams()) {
441-
auto *newParam = new (ctx) GenericTypeParamDecl(classDecl,
442-
param->getName(),
443-
SourceLoc(),
444-
depth,
445-
param->getIndex());
446-
newParams.push_back(newParam);
447-
}
429+
auto superclassCtorSig = superclassCtor->getGenericSignature();
430+
auto superclassSig = superclassDecl->getGenericSignature();
448431

449-
// We don't have to clone the requirements, because they're not
450-
// used for anything.
451-
genericParams = GenericParamList::create(ctx,
452-
SourceLoc(),
453-
newParams,
454-
SourceLoc(),
455-
ArrayRef<RequirementRepr>(),
456-
SourceLoc());
432+
if (superclassCtorSig.getPointer() != superclassSig.getPointer()) {
433+
SmallVector<GenericTypeParamDecl *, 4> newParams;
434+
SmallVector<GenericTypeParamType *, 1> newParamTypes;
457435

458-
// Build a generic signature for the derived class initializer.
436+
// Inheriting initializers that have their own generic parameters
437+
if (genericParams) {
438+
// First, clone the superclass constructor's generic parameter list,
439+
// but change the depth of the generic parameters to be one greater
440+
// than the depth of the subclass.
441+
unsigned depth = 0;
442+
if (auto genericSig = classDecl->getGenericSignature())
443+
depth = genericSig->getGenericParams().back()->getDepth() + 1;
444+
445+
for (auto *param : genericParams->getParams()) {
446+
auto *newParam = new (ctx) GenericTypeParamDecl(classDecl,
447+
param->getName(),
448+
SourceLoc(),
449+
depth,
450+
param->getIndex());
451+
newParams.push_back(newParam);
452+
}
459453

460-
// Add the generic parameters.
461-
SmallVector<GenericTypeParamType *, 1> newParamTypes;
462-
for (auto *newParam : newParams) {
463-
newParamTypes.push_back(
464-
newParam->getDeclaredInterfaceType()->castTo<GenericTypeParamType>());
454+
// We don't have to clone the requirements, because they're not
455+
// used for anything.
456+
genericParams = GenericParamList::create(ctx,
457+
SourceLoc(),
458+
newParams,
459+
SourceLoc(),
460+
ArrayRef<RequirementRepr>(),
461+
SourceLoc());
462+
463+
// Add the generic parameter types.
464+
for (auto *newParam : newParams) {
465+
newParamTypes.push_back(
466+
newParam->getDeclaredInterfaceType()->castTo<GenericTypeParamType>());
467+
}
465468
}
466469

467-
auto superclassSig = superclassCtor->getGenericSignature();
468-
470+
// Build a generic signature for the derived class initializer.
469471
unsigned superclassDepth = 0;
470-
if (auto genericSig = superclassDecl->getGenericSignature())
471-
superclassDepth = genericSig->getGenericParams().back()->getDepth() + 1;
472+
if (superclassSig)
473+
superclassDepth = superclassSig->getGenericParams().back()->getDepth() + 1;
472474

473475
// We're going to be substituting the requirements of the base class
474476
// initializer to form the requirements of the derived class initializer.
@@ -490,13 +492,13 @@ configureGenericDesignatedInitOverride(ASTContext &ctx,
490492
};
491493

492494
SmallVector<Requirement, 2> requirements;
493-
for (auto reqt : superclassSig->getRequirements())
495+
for (auto reqt : superclassCtorSig->getRequirements())
494496
if (auto substReqt = reqt.subst(substFn, lookupConformanceFn))
495497
requirements.push_back(*substReqt);
496498

497499
// Now form the substitution map that will be used to remap parameter
498500
// types.
499-
subMap = SubstitutionMap::get(superclassSig,
501+
subMap = SubstitutionMap::get(superclassCtorSig,
500502
substFn, lookupConformanceFn);
501503

502504
genericSig = evaluateOrDefault(
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// RUN: %target-swift-emit-silgen -primary-file %s | %FileCheck %s
2+
3+
public protocol Ungulate {}
4+
public protocol Domesticated {}
5+
6+
public class Horse<U: Ungulate> {
7+
// CHECK-LABEL: sil [serialized] [exact_self_class] [ossa] @$s45designated_init_inheritance_with_where_clause5HorseCACyxGycfC : $@convention(method) <U where U : Ungulate> (@thick Horse<U>.Type) -> @owned Horse<U> {
8+
// CHECK-LABEL: sil [ossa] @$s45designated_init_inheritance_with_where_clause5HorseCACyxGycfc : $@convention(method) <U where U : Ungulate> (@owned Horse<U>) -> @owned Horse<U> {
9+
public init() { }
10+
11+
// CHECK-LABEL: sil [serialized] [exact_self_class] [ossa] @$s45designated_init_inheritance_with_where_clause5HorseCACyxGycAA12DomesticatedRzrlufC : $@convention(method) <U where U : Domesticated, U : Ungulate> (@thick Horse<U>.Type) -> @owned Horse<U> {
12+
// CHECK-LABEL: sil [ossa] @$s45designated_init_inheritance_with_where_clause5HorseCACyxGycAA12DomesticatedRzrlufc : $@convention(method) <U where U : Domesticated, U : Ungulate> (@owned Horse<U>) -> @owned Horse<U> {
13+
public init() where U: Domesticated { }
14+
}
15+
16+
public class Pony<U : Ungulate> : Horse<U> {
17+
// CHECK-LABEL: sil [serialized] [exact_self_class] [ossa] @$s45designated_init_inheritance_with_where_clause4PonyCACyxGycfC : $@convention(method) <U where U : Ungulate> (@thick Pony<U>.Type) -> @owned Pony<U> {
18+
// CHECK-LABEL: sil [ossa] @$s45designated_init_inheritance_with_where_clause4PonyCACyxGycfc : $@convention(method) <U where U : Ungulate> (@owned Pony<U>) -> @owned Pony<U> {
19+
20+
// CHECK-LABEL: sil [serialized] [exact_self_class] [ossa] @$s45designated_init_inheritance_with_where_clause4PonyCACyxGycAA12DomesticatedRzrlufC : $@convention(method) <U where U : Domesticated, U : Ungulate> (@thick Pony<U>.Type) -> @owned Pony<U> {
21+
// CHECK-LABEL: sil [ossa] @$s45designated_init_inheritance_with_where_clause4PonyCACyxGycAA12DomesticatedRzrlufc : $@convention(method) <U where U : Domesticated, U : Ungulate> (@owned Pony<U>) -> @owned Pony<U> {
22+
}

0 commit comments

Comments
 (0)