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"
@@ -2011,6 +2012,104 @@ static void createStubBody(TypeChecker &tc, ConstructorDecl *ctor) {
2011
2012
ctor->setStubImplementation (true );
2012
2013
}
2013
2014
2015
+ static std::tuple<GenericSignature *, GenericEnvironment *,
2016
+ GenericParamList *, SubstitutionMap>
2017
+ configureGenericDesignatedInitOverride (ASTContext &ctx,
2018
+ ClassDecl *classDecl,
2019
+ Type superclassTy,
2020
+ ConstructorDecl *superclassCtor) {
2021
+ auto *superclassDecl = superclassTy->getAnyNominal ();
2022
+
2023
+ auto *moduleDecl = classDecl->getParentModule ();
2024
+ auto subMap = superclassTy->getContextSubstitutionMap (
2025
+ moduleDecl, superclassDecl);
2026
+
2027
+ GenericSignature *genericSig;
2028
+ GenericEnvironment *genericEnv;
2029
+
2030
+ // Inheriting initializers that have their own generic parameters
2031
+ auto *genericParams = superclassCtor->getGenericParams ();
2032
+ if (genericParams) {
2033
+ SmallVector<GenericTypeParamDecl *, 4 > newParams;
2034
+
2035
+ // First, clone the superclass constructor's generic parameter list,
2036
+ // but change the depth of the generic parameters to be one greater
2037
+ // than the depth of the subclass.
2038
+ unsigned depth = 0 ;
2039
+ if (auto *genericSig = classDecl->getGenericSignature ())
2040
+ depth = genericSig->getGenericParams ().back ()->getDepth () + 1 ;
2041
+
2042
+ for (auto *param : genericParams->getParams ()) {
2043
+ auto *newParam = new (ctx) GenericTypeParamDecl (classDecl,
2044
+ param->getName (),
2045
+ SourceLoc (),
2046
+ depth,
2047
+ param->getIndex ());
2048
+ newParams.push_back (newParam);
2049
+ }
2050
+
2051
+ // Substitution map that maps the generic parameters of the superclass
2052
+ // to the generic parameters of the derived class, and the generic
2053
+ // parameters of the superclass initializer to the generic parameters
2054
+ // of the derived class initializer.
2055
+ auto *superclassSig = superclassCtor->getGenericSignature ();
2056
+ if (superclassSig) {
2057
+ unsigned superclassDepth = 0 ;
2058
+ if (auto *genericSig = superclassDecl->getGenericSignature ())
2059
+ superclassDepth = genericSig->getGenericParams ().back ()->getDepth () + 1 ;
2060
+
2061
+ subMap = SubstitutionMap::get (
2062
+ superclassSig,
2063
+ [&](SubstitutableType *type) -> Type {
2064
+ auto *gp = cast<GenericTypeParamType>(type);
2065
+ if (gp->getDepth () < superclassDepth)
2066
+ return Type (gp).subst (subMap);
2067
+ return CanGenericTypeParamType::get (
2068
+ gp->getDepth () - superclassDepth + depth,
2069
+ gp->getIndex (),
2070
+ ctx);
2071
+ },
2072
+ [&](CanType depTy, Type substTy, ProtocolDecl *proto)
2073
+ -> Optional<ProtocolConformanceRef> {
2074
+ if (auto conf = subMap.lookupConformance (depTy, proto))
2075
+ return conf;
2076
+
2077
+ return ProtocolConformanceRef (proto);
2078
+ });
2079
+ }
2080
+
2081
+ // We don't have to clone the requirements, because they're not
2082
+ // used for anything.
2083
+ genericParams = GenericParamList::create (ctx,
2084
+ SourceLoc (),
2085
+ newParams,
2086
+ SourceLoc (),
2087
+ ArrayRef<RequirementRepr>(),
2088
+ SourceLoc ());
2089
+ genericParams->setOuterParameters (classDecl->getGenericParamsOfContext ());
2090
+
2091
+ GenericSignatureBuilder builder (ctx);
2092
+ builder.addGenericSignature (classDecl->getGenericSignature ());
2093
+
2094
+ for (auto *newParam : newParams)
2095
+ builder.addGenericParameter (newParam);
2096
+
2097
+ auto source =
2098
+ GenericSignatureBuilder::FloatingRequirementSource::forAbstract ();
2099
+ for (auto reqt : superclassSig->getRequirements ())
2100
+ if (auto substReqt = reqt.subst (subMap))
2101
+ builder.addRequirement (*substReqt, source, nullptr );
2102
+
2103
+ genericSig = std::move (builder).computeGenericSignature (SourceLoc ());
2104
+ genericEnv = genericSig->createGenericEnvironment ();
2105
+ } else {
2106
+ genericEnv = classDecl->getGenericEnvironment ();
2107
+ genericSig = classDecl->getGenericSignature ();
2108
+ }
2109
+
2110
+ return std::make_tuple (genericSig, genericEnv, genericParams, subMap);
2111
+ }
2112
+
2014
2113
static void configureDesignatedInitAttributes (TypeChecker &tc,
2015
2114
ClassDecl *classDecl,
2016
2115
ConstructorDecl *ctor,
@@ -2090,10 +2189,6 @@ swift::createDesignatedInitOverride(TypeChecker &tc,
2090
2189
DesignatedInitKind kind) {
2091
2190
auto &ctx = tc.Context ;
2092
2191
2093
- // FIXME: Inheriting initializers that have their own generic parameters
2094
- if (superclassCtor->getGenericParams ())
2095
- return nullptr ;
2096
-
2097
2192
// Lookup will sometimes give us initializers that are from the ancestors of
2098
2193
// our immediate superclass. So, from the superclass constructor, we look
2099
2194
// one level up to the enclosing type context which will either be a class
@@ -2111,6 +2206,17 @@ swift::createDesignatedInitOverride(TypeChecker &tc,
2111
2206
return nullptr ;
2112
2207
}
2113
2208
2209
+ GenericSignature *genericSig;
2210
+ GenericEnvironment *genericEnv;
2211
+ GenericParamList *genericParams;
2212
+ SubstitutionMap subMap;
2213
+
2214
+ std::tie (genericSig, genericEnv, genericParams, subMap) =
2215
+ configureGenericDesignatedInitOverride (ctx,
2216
+ classDecl,
2217
+ superclassTy,
2218
+ superclassCtor);
2219
+
2114
2220
// Determine the initializer parameters.
2115
2221
2116
2222
// Create the 'self' declaration and patterns.
@@ -2126,15 +2232,11 @@ swift::createDesignatedInitOverride(TypeChecker &tc,
2126
2232
//
2127
2233
// We might have to apply substitutions, if for example we have a declaration
2128
2234
// like 'class A : B<Int>'.
2129
- auto *moduleDecl = classDecl->getParentModule ();
2130
- auto subMap = superclassTy->getContextSubstitutionMap (
2131
- moduleDecl, superclassDecl);
2132
-
2133
2235
for (auto *decl : *bodyParams) {
2134
2236
auto paramTy = decl->getInterfaceType ();
2135
2237
auto substTy = paramTy.subst (subMap);
2136
2238
decl->setInterfaceType (substTy);
2137
- decl->setType (classDecl-> mapTypeIntoContext (substTy));
2239
+ decl->setType (GenericEnvironment:: mapTypeIntoContext (genericEnv, substTy));
2138
2240
}
2139
2241
2140
2242
// Create the initializer declaration, inheriting the name,
@@ -2147,13 +2249,14 @@ swift::createDesignatedInitOverride(TypeChecker &tc,
2147
2249
/* Throws=*/ superclassCtor->hasThrows (),
2148
2250
/* ThrowsLoc=*/ SourceLoc (),
2149
2251
selfDecl, bodyParams,
2150
- /* GenericParams= */ nullptr , classDecl);
2252
+ genericParams , classDecl);
2151
2253
2152
2254
ctor->setImplicit ();
2153
2255
2154
2256
// Set the interface type of the initializer.
2155
- ctor->setGenericEnvironment (classDecl->getGenericEnvironmentOfContext ());
2156
- tc.configureInterfaceType (ctor, ctor->getGenericSignature ());
2257
+ ctor->setGenericEnvironment (genericEnv);
2258
+
2259
+ tc.configureInterfaceType (ctor, genericSig);
2157
2260
ctor->setValidationStarted ();
2158
2261
2159
2262
configureDesignatedInitAttributes (tc, classDecl,
0 commit comments