Skip to content

Commit 09aea61

Browse files
committed
Sema: Use a different strategy for computing derived initializer generic signature
1 parent 2f0c8a8 commit 09aea61

File tree

2 files changed

+39
-32
lines changed

2 files changed

+39
-32
lines changed

lib/Sema/CodeSynthesis.cpp

Lines changed: 36 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -2042,36 +2042,6 @@ configureGenericDesignatedInitOverride(ASTContext &ctx,
20422042
newParams.push_back(newParam);
20432043
}
20442044

2045-
// Substitution map that maps the generic parameters of the superclass
2046-
// to the generic parameters of the derived class, and the generic
2047-
// parameters of the superclass initializer to the generic parameters
2048-
// of the derived class initializer.
2049-
auto *superclassSig = superclassCtor->getGenericSignature();
2050-
if (superclassSig) {
2051-
unsigned superclassDepth = 0;
2052-
if (auto *genericSig = superclassDecl->getGenericSignature())
2053-
superclassDepth = genericSig->getGenericParams().back()->getDepth() + 1;
2054-
2055-
subMap = superclassSig->getSubstitutionMap(
2056-
[&](SubstitutableType *type) -> Type {
2057-
auto *gp = cast<GenericTypeParamType>(type);
2058-
if (gp->getDepth() < superclassDepth)
2059-
return Type(gp).subst(subMap);
2060-
return CanGenericTypeParamType::get(
2061-
gp->getDepth() - superclassDepth + depth,
2062-
gp->getIndex(),
2063-
ctx);
2064-
},
2065-
[&](CanType depTy, Type substTy, ProtocolType *protoType)
2066-
-> Optional<ProtocolConformanceRef> {
2067-
auto *proto = protoType->getDecl();
2068-
if (auto conf = subMap.lookupConformance(depTy, proto))
2069-
return conf;
2070-
2071-
return ProtocolConformanceRef(proto);
2072-
});
2073-
}
2074-
20752045
// We don't have to clone the requirements, because they're not
20762046
// used for anything.
20772047
genericParams = GenericParamList::create(ctx,
@@ -2082,18 +2052,53 @@ configureGenericDesignatedInitOverride(ASTContext &ctx,
20822052
SourceLoc());
20832053
genericParams->setOuterParameters(classDecl->getGenericParamsOfContext());
20842054

2055+
// Build a generic signature for the derived class initializer.
20852056
GenericSignatureBuilder builder(ctx);
20862057
builder.addGenericSignature(classDecl->getGenericSignature());
20872058

2059+
// Add the generic parameters.
20882060
for (auto *newParam : newParams)
20892061
builder.addGenericParameter(newParam);
20902062

20912063
auto source =
20922064
GenericSignatureBuilder::FloatingRequirementSource::forAbstract();
2065+
auto *superclassSig = superclassCtor->getGenericSignature();
2066+
2067+
unsigned superclassDepth = 0;
2068+
if (auto *genericSig = superclassDecl->getGenericSignature())
2069+
superclassDepth = genericSig->getGenericParams().back()->getDepth() + 1;
2070+
2071+
// We're going to be substituting the requirements of the base class
2072+
// initializer to form the requirements of the derived class initializer.
2073+
auto substFn = [&](SubstitutableType *type) -> Type {
2074+
auto *gp = cast<GenericTypeParamType>(type);
2075+
if (gp->getDepth() < superclassDepth)
2076+
return Type(gp).subst(subMap);
2077+
return CanGenericTypeParamType::get(
2078+
gp->getDepth() - superclassDepth + depth,
2079+
gp->getIndex(),
2080+
ctx);
2081+
};
2082+
2083+
auto lookupConformanceFn =
2084+
[&](CanType depTy, Type substTy, ProtocolType *protoType)
2085+
-> Optional<ProtocolConformanceRef> {
2086+
auto *proto = protoType->getDecl();
2087+
if (!subMap.empty())
2088+
if (auto conf = subMap.lookupConformance(depTy, proto))
2089+
return conf;
2090+
2091+
return ProtocolConformanceRef(proto);
2092+
};
2093+
20932094
for (auto reqt : superclassSig->getRequirements())
2094-
if (auto substReqt = reqt.subst(subMap))
2095+
if (auto substReqt = reqt.subst(substFn, lookupConformanceFn))
20952096
builder.addRequirement(*substReqt, source, nullptr);
20962097

2098+
// Now form the substitution map that will be used to remap parameter
2099+
// types.
2100+
subMap = superclassSig->getSubstitutionMap(substFn, lookupConformanceFn);
2101+
20972102
genericSig = std::move(builder).computeGenericSignature(SourceLoc());
20982103
genericEnv = genericSig->createGenericEnvironment();
20992104
} else {

test/SILGen/inherit_initializers.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,4 +122,6 @@ class Twice<X, Y> {
122122
init<Z>(_: Z) where Z : Q, Z.A == X, Z.B == Y, X == Y {}
123123
}
124124

125-
class Once<T> : Twice<T, T> {}
125+
class Pair<T, U> : Twice<T, U> {}
126+
127+
class Once<T> : Twice<T, T> {}

0 commit comments

Comments
 (0)