22
22
#include " swift/AST/Availability.h"
23
23
#include " swift/AST/Expr.h"
24
24
#include " swift/AST/GenericEnvironment.h"
25
+ #include " swift/AST/GenericSignatureBuilder.h"
25
26
#include " swift/AST/Initializer.h"
26
27
#include " swift/AST/ParameterList.h"
27
28
#include " swift/AST/ProtocolConformance.h"
@@ -2005,6 +2006,104 @@ static void createStubBody(TypeChecker &tc, ConstructorDecl *ctor) {
2005
2006
ctor->setStubImplementation (true );
2006
2007
}
2007
2008
2009
+ static std::tuple<GenericSignature *, GenericEnvironment *,
2010
+ GenericParamList *, SubstitutionMap>
2011
+ configureGenericDesignatedInitOverride (ASTContext &ctx,
2012
+ ClassDecl *classDecl,
2013
+ Type superclassTy,
2014
+ ConstructorDecl *superclassCtor) {
2015
+ auto *superclassDecl = superclassTy->getAnyNominal ();
2016
+
2017
+ auto *moduleDecl = classDecl->getParentModule ();
2018
+ auto subMap = superclassTy->getContextSubstitutionMap (
2019
+ moduleDecl, superclassDecl);
2020
+
2021
+ GenericSignature *genericSig;
2022
+ GenericEnvironment *genericEnv;
2023
+
2024
+ // Inheriting initializers that have their own generic parameters
2025
+ auto *genericParams = superclassCtor->getGenericParams ();
2026
+ if (genericParams) {
2027
+ SmallVector<GenericTypeParamDecl *, 4 > newParams;
2028
+
2029
+ // First, clone the superclass constructor's generic parameter list,
2030
+ // but change the depth of the generic parameters to be one greater
2031
+ // than the depth of the subclass.
2032
+ unsigned depth = 0 ;
2033
+ if (auto *genericSig = classDecl->getGenericSignature ())
2034
+ depth = genericSig->getGenericParams ().back ()->getDepth () + 1 ;
2035
+
2036
+ for (auto *param : genericParams->getParams ()) {
2037
+ auto *newParam = new (ctx) GenericTypeParamDecl (classDecl,
2038
+ param->getName (),
2039
+ SourceLoc (),
2040
+ depth,
2041
+ param->getIndex ());
2042
+ newParams.push_back (newParam);
2043
+ }
2044
+
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
+
2075
+ // We don't have to clone the requirements, because they're not
2076
+ // used for anything.
2077
+ genericParams = GenericParamList::create (ctx,
2078
+ SourceLoc (),
2079
+ newParams,
2080
+ SourceLoc (),
2081
+ ArrayRef<RequirementRepr>(),
2082
+ SourceLoc ());
2083
+ genericParams->setOuterParameters (classDecl->getGenericParamsOfContext ());
2084
+
2085
+ GenericSignatureBuilder builder (ctx);
2086
+ builder.addGenericSignature (classDecl->getGenericSignature ());
2087
+
2088
+ for (auto *newParam : newParams)
2089
+ builder.addGenericParameter (newParam);
2090
+
2091
+ auto source =
2092
+ GenericSignatureBuilder::FloatingRequirementSource::forAbstract ();
2093
+ for (auto reqt : superclassSig->getRequirements ())
2094
+ if (auto substReqt = reqt.subst (subMap))
2095
+ builder.addRequirement (*substReqt, source, nullptr );
2096
+
2097
+ genericSig = std::move (builder).computeGenericSignature (SourceLoc ());
2098
+ genericEnv = genericSig->createGenericEnvironment ();
2099
+ } else {
2100
+ genericEnv = classDecl->getGenericEnvironment ();
2101
+ genericSig = classDecl->getGenericSignature ();
2102
+ }
2103
+
2104
+ return std::make_tuple (genericSig, genericEnv, genericParams, subMap);
2105
+ }
2106
+
2008
2107
static void configureDesignatedInitAttributes (TypeChecker &tc,
2009
2108
ClassDecl *classDecl,
2010
2109
ConstructorDecl *ctor,
@@ -2084,10 +2183,6 @@ swift::createDesignatedInitOverride(TypeChecker &tc,
2084
2183
DesignatedInitKind kind) {
2085
2184
auto &ctx = tc.Context ;
2086
2185
2087
- // FIXME: Inheriting initializers that have their own generic parameters
2088
- if (superclassCtor->getGenericParams ())
2089
- return nullptr ;
2090
-
2091
2186
// Lookup will sometimes give us initializers that are from the ancestors of
2092
2187
// our immediate superclass. So, from the superclass constructor, we look
2093
2188
// one level up to the enclosing type context which will either be a class
@@ -2105,6 +2200,17 @@ swift::createDesignatedInitOverride(TypeChecker &tc,
2105
2200
return nullptr ;
2106
2201
}
2107
2202
2203
+ GenericSignature *genericSig;
2204
+ GenericEnvironment *genericEnv;
2205
+ GenericParamList *genericParams;
2206
+ SubstitutionMap subMap;
2207
+
2208
+ std::tie (genericSig, genericEnv, genericParams, subMap) =
2209
+ configureGenericDesignatedInitOverride (ctx,
2210
+ classDecl,
2211
+ superclassTy,
2212
+ superclassCtor);
2213
+
2108
2214
// Determine the initializer parameters.
2109
2215
2110
2216
// Create the 'self' declaration and patterns.
@@ -2120,15 +2226,11 @@ swift::createDesignatedInitOverride(TypeChecker &tc,
2120
2226
//
2121
2227
// We might have to apply substitutions, if for example we have a declaration
2122
2228
// like 'class A : B<Int>'.
2123
- auto *moduleDecl = classDecl->getParentModule ();
2124
- auto subMap = superclassTy->getContextSubstitutionMap (
2125
- moduleDecl, superclassDecl);
2126
-
2127
2229
for (auto *decl : *bodyParams) {
2128
2230
auto paramTy = decl->getInterfaceType ()->getInOutObjectType ();
2129
2231
auto substTy = paramTy.subst (subMap);
2130
2232
decl->setInterfaceType (substTy);
2131
- decl->setType (classDecl-> mapTypeIntoContext (substTy));
2233
+ decl->setType (GenericEnvironment:: mapTypeIntoContext (genericEnv, substTy));
2132
2234
}
2133
2235
2134
2236
// Create the initializer declaration, inheriting the name,
@@ -2141,13 +2243,14 @@ swift::createDesignatedInitOverride(TypeChecker &tc,
2141
2243
/* Throws=*/ superclassCtor->hasThrows (),
2142
2244
/* ThrowsLoc=*/ SourceLoc (),
2143
2245
selfDecl, bodyParams,
2144
- /* GenericParams= */ nullptr , classDecl);
2246
+ genericParams , classDecl);
2145
2247
2146
2248
ctor->setImplicit ();
2147
2249
2148
2250
// Set the interface type of the initializer.
2149
- ctor->setGenericEnvironment (classDecl->getGenericEnvironmentOfContext ());
2150
- tc.configureInterfaceType (ctor, ctor->getGenericSignature ());
2251
+ ctor->setGenericEnvironment (genericEnv);
2252
+
2253
+ tc.configureInterfaceType (ctor, genericSig);
2151
2254
ctor->setValidationStarted ();
2152
2255
2153
2256
configureDesignatedInitAttributes (tc, classDecl,
0 commit comments