Skip to content

Commit f8fa2c0

Browse files
committed
Sema: Refactor computeDesignatedInitOverrideSignature()
1 parent 9bfe02e commit f8fa2c0

File tree

1 file changed

+88
-92
lines changed

1 file changed

+88
-92
lines changed

lib/Sema/CodeSynthesis.cpp

Lines changed: 88 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -434,8 +434,6 @@ computeDesignatedInitOverrideSignature(ASTContext &ctx,
434434
ClassDecl *classDecl,
435435
Type superclassTy,
436436
ConstructorDecl *superclassCtor) {
437-
auto *moduleDecl = classDecl->getParentModule();
438-
439437
auto *superclassDecl = superclassTy->getAnyNominal();
440438

441439
auto classSig = classDecl->getGenericSignature();
@@ -445,103 +443,101 @@ computeDesignatedInitOverrideSignature(ASTContext &ctx,
445443
// These are our outputs.
446444
GenericSignature genericSig = classSig;
447445
auto *genericParams = superclassCtor->getGenericParams();
448-
auto subMap = superclassTy->getContextSubstitutionMap(
449-
moduleDecl, superclassDecl);
450446

451-
if (superclassCtorSig.getPointer() != superclassSig.getPointer()) {
452-
// If the base initializer's generic signature is different
453-
// from that of the base class, the base class initializer either
454-
// has generic parameters or a 'where' clause.
455-
//
456-
// We need to "rebase" the requirements on top of the derived class's
457-
// generic signature.
447+
SmallVector<GenericTypeParamType *, 1> newParamTypes;
448+
449+
// If genericParams is non-null, the base class initializer has its own
450+
// generic parameters. Otherwise, it is non-generic with a contextual
451+
// 'where' clause.
452+
if (genericParams) {
453+
// First, clone the base class initializer's generic parameter list,
454+
// but change the depth of the generic parameters to be one greater
455+
// than the depth of the subclass.
456+
unsigned depth = 0;
457+
if (auto genericSig = classDecl->getGenericSignature())
458+
depth = genericSig.getGenericParams().back()->getDepth() + 1;
458459

459460
SmallVector<GenericTypeParamDecl *, 4> newParams;
460-
SmallVector<GenericTypeParamType *, 1> newParamTypes;
461-
462-
// If genericParams is non-null, the base class initializer has its own
463-
// generic parameters. Otherwise, it is non-generic with a contextual
464-
// 'where' clause.
465-
if (genericParams) {
466-
// First, clone the base class initializer's generic parameter list,
467-
// but change the depth of the generic parameters to be one greater
468-
// than the depth of the subclass.
469-
unsigned depth = 0;
470-
if (auto genericSig = classDecl->getGenericSignature())
471-
depth = genericSig.getGenericParams().back()->getDepth() + 1;
472-
473-
for (auto *param : genericParams->getParams()) {
474-
auto *newParam = GenericTypeParamDecl::create(
475-
classDecl, param->getName(), SourceLoc(), param->isTypeSequence(),
476-
depth, param->getIndex(), param->isOpaqueType(),
477-
/*opaqueTypeRepr=*/nullptr);
478-
newParams.push_back(newParam);
479-
}
461+
for (auto *param : genericParams->getParams()) {
462+
auto *newParam = GenericTypeParamDecl::create(
463+
classDecl, param->getName(), SourceLoc(), param->isTypeSequence(),
464+
depth, param->getIndex(), param->isOpaqueType(),
465+
/*opaqueTypeRepr=*/nullptr);
466+
newParams.push_back(newParam);
467+
}
480468

481-
// We don't have to clone the RequirementReprs, because they're not
482-
// used for anything other than SIL mode.
483-
genericParams = GenericParamList::create(ctx,
484-
SourceLoc(),
485-
newParams,
486-
SourceLoc(),
487-
ArrayRef<RequirementRepr>(),
488-
SourceLoc());
489-
490-
// Add the generic parameter types.
491-
for (auto *newParam : newParams) {
492-
newParamTypes.push_back(
493-
newParam->getDeclaredInterfaceType()->castTo<GenericTypeParamType>());
494-
}
469+
// We don't have to clone the RequirementReprs, because they're not
470+
// used for anything other than SIL mode.
471+
genericParams = GenericParamList::create(ctx,
472+
SourceLoc(),
473+
newParams,
474+
SourceLoc(),
475+
ArrayRef<RequirementRepr>(),
476+
SourceLoc());
477+
478+
// Add the generic parameter types.
479+
for (auto *newParam : newParams) {
480+
newParamTypes.push_back(
481+
newParam->getDeclaredInterfaceType()->castTo<GenericTypeParamType>());
495482
}
483+
}
484+
485+
auto baseSubMap = superclassTy->getContextSubstitutionMap(
486+
classDecl->getParentModule(), superclassDecl);
487+
488+
// The depth at which the initializer's own generic parameters start, if any.
489+
unsigned superclassDepth = 0;
490+
if (superclassSig)
491+
superclassDepth = superclassSig.getGenericParams().back()->getDepth() + 1;
492+
493+
// We're going to be substituting the requirements of the base class
494+
// initializer to form the requirements of the derived class initializer.
495+
auto substFn = [&](SubstitutableType *type) -> Type {
496+
auto *gp = cast<GenericTypeParamType>(type);
497+
// Generic parameters of the base class itself are mapped via the
498+
// substitution map of the superclass type.
499+
if (gp->getDepth() < superclassDepth)
500+
return Type(gp).subst(baseSubMap);
501+
502+
// Generic parameters added by the base class initializer map to the new
503+
// generic parameters of the derived initializer.
504+
return genericParams->getParams()[gp->getIndex()]
505+
->getDeclaredInterfaceType();
506+
};
507+
508+
auto lookupConformanceFn =
509+
[&](CanType depTy, Type substTy,
510+
ProtocolDecl *proto) -> ProtocolConformanceRef {
511+
if (depTy->getRootGenericParam()->getDepth() < superclassDepth)
512+
if (auto conf = baseSubMap.lookupConformance(depTy, proto))
513+
return conf;
514+
515+
return ProtocolConformanceRef(proto);
516+
};
496517

497-
// The depth at which the initializer's own generic parameters start, if any.
498-
unsigned superclassDepth = 0;
499-
if (superclassSig)
500-
superclassDepth = superclassSig.getGenericParams().back()->getDepth() + 1;
501-
502-
// We're going to be substituting the requirements of the base class
503-
// initializer to form the requirements of the derived class initializer.
504-
auto substFn = [&](SubstitutableType *type) -> Type {
505-
auto *gp = cast<GenericTypeParamType>(type);
506-
// Generic parameters of the base class itself are mapped via the
507-
// substitution map of the superclass type.
508-
if (gp->getDepth() < superclassDepth)
509-
return Type(gp).subst(subMap);
510-
511-
// Generic parameters added by the base class initializer map to the new
512-
// generic parameters of the derived initializer.
513-
return genericParams->getParams()[gp->getIndex()]
514-
->getDeclaredInterfaceType();
515-
};
516-
517-
// If we don't have any new generic parameters and the derived class is
518-
// not generic, the base class initializer's 'where' clause should already
519-
// be fully satisfied, and we can just drop it.
520-
if (genericParams != nullptr || classSig) {
521-
auto lookupConformanceFn =
522-
[&](CanType depTy, Type substTy,
523-
ProtocolDecl *proto) -> ProtocolConformanceRef {
524-
if (depTy->getRootGenericParam()->getDepth() < superclassDepth)
525-
if (auto conf = subMap.lookupConformance(depTy, proto))
526-
return conf;
527-
528-
return ProtocolConformanceRef(proto);
529-
};
530-
531-
SmallVector<Requirement, 2> requirements;
532-
for (auto reqt : superclassCtorSig.getRequirements())
533-
if (auto substReqt = reqt.subst(substFn, lookupConformanceFn))
534-
requirements.push_back(*substReqt);
535-
536-
// Now form the substitution map that will be used to remap parameter
537-
// types.
538-
subMap = SubstitutionMap::get(superclassCtorSig,
539-
substFn, lookupConformanceFn);
540-
541-
genericSig = buildGenericSignature(ctx, classSig,
542-
std::move(newParamTypes),
543-
std::move(requirements));
518+
// Now form the substitution map that will be used to remap parameter
519+
// types.
520+
auto subMap = SubstitutionMap::get(superclassCtorSig,
521+
substFn, lookupConformanceFn);
522+
523+
SmallVector<Requirement, 2> requirements;
524+
525+
// If the base initializer's generic signature is different
526+
// from that of the base class, the base class initializer either
527+
// has generic parameters or a 'where' clause.
528+
//
529+
// We need to "rebase" the requirements on top of the derived class's
530+
// generic signature.
531+
if (superclassSig.getPointer() != superclassCtorSig.getPointer() &&
532+
(classSig || newParamTypes.size() != 0)) {
533+
for (auto reqt : superclassCtorSig.getRequirements()) {
534+
if (auto substReqt = reqt.subst(substFn, lookupConformanceFn))
535+
requirements.push_back(*substReqt);
544536
}
537+
538+
genericSig = buildGenericSignature(ctx, classSig,
539+
std::move(newParamTypes),
540+
std::move(requirements));
545541
}
546542

547543
return DesignatedInitOverrideInfo{genericSig, genericParams, subMap};

0 commit comments

Comments
 (0)