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,
@@ -2088,9 +2187,7 @@ swift::createDesignatedInitOverride(TypeChecker &tc,
2088
2187
ClassDecl *classDecl,
2089
2188
ConstructorDecl *superclassCtor,
2090
2189
DesignatedInitKind kind) {
2091
- // FIXME: Inheriting initializers that have their own generic parameters
2092
- if (superclassCtor->getGenericParams ())
2093
- return nullptr ;
2190
+ auto &ctx = tc.Context ;
2094
2191
2095
2192
// Lookup will sometimes give us initializers that are from the ancestors of
2096
2193
// our immediate superclass. So, from the superclass constructor, we look
@@ -2104,54 +2201,42 @@ swift::createDesignatedInitOverride(TypeChecker &tc,
2104
2201
superclassCtor->getDeclContext ()
2105
2202
->getAsNominalTypeOrNominalTypeExtensionContext ();
2106
2203
Type superclassTy = classDecl->getSuperclass ();
2107
- Type superclassTyInContext = classDecl->mapTypeIntoContext (superclassTy);
2108
2204
NominalTypeDecl *superclassDecl = superclassTy->getAnyNominal ();
2109
2205
if (superclassCtorDecl != superclassDecl) {
2110
2206
return nullptr ;
2111
2207
}
2112
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
+
2113
2220
// Determine the initializer parameters.
2114
- auto &ctx = tc.Context ;
2115
2221
2116
2222
// Create the 'self' declaration and patterns.
2117
2223
auto *selfDecl = ParamDecl::createSelf (SourceLoc (), classDecl);
2118
2224
2119
2225
// Create the initializer parameter patterns.
2120
2226
OptionSet<ParameterList::CloneFlags> options = ParameterList::Implicit;
2121
2227
options |= ParameterList::Inherited;
2122
- auto *bodyParams = superclassCtor->getParameterList (1 )->clone (ctx,options);
2228
+ auto *bodyParams = superclassCtor->getParameterList (1 )->clone (ctx, options);
2123
2229
2124
2230
// If the superclass is generic, we need to map the superclass constructor's
2125
2231
// parameter types into the generic context of our class.
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
- if (superclassDecl->getGenericSignatureOfContext ()) {
2130
- auto *moduleDecl = classDecl->getParentModule ();
2131
- auto subMap = superclassTyInContext->getContextSubstitutionMap (
2132
- moduleDecl,
2133
- superclassDecl,
2134
- classDecl->getGenericEnvironment ());
2135
-
2136
- for (auto *decl : *bodyParams) {
2137
- auto paramTy = decl->getInterfaceType ()->getInOutObjectType ();
2138
-
2139
- // Apply the superclass substitutions to produce a contextual
2140
- // type in terms of the derived class archetypes.
2141
- auto paramSubstTy = paramTy.subst (subMap);
2142
- decl->setType (paramSubstTy);
2143
-
2144
- // Map it to an interface type in terms of the derived class
2145
- // generic signature.
2146
- decl->setInterfaceType (paramSubstTy->mapTypeOutOfContext ());
2147
- }
2148
- } else {
2149
- for (auto *decl : *bodyParams) {
2150
- if (!decl->hasType ())
2151
- decl->setType (
2152
- classDecl->mapTypeIntoContext (
2153
- decl->getInterfaceType ()->getInOutObjectType ()));
2154
- }
2235
+ for (auto *decl : *bodyParams) {
2236
+ auto paramTy = decl->getInterfaceType ();
2237
+ auto substTy = paramTy.subst (subMap);
2238
+ decl->setInterfaceType (substTy);
2239
+ decl->setType (GenericEnvironment::mapTypeIntoContext (genericEnv, substTy));
2155
2240
}
2156
2241
2157
2242
// Create the initializer declaration, inheriting the name,
@@ -2164,13 +2249,14 @@ swift::createDesignatedInitOverride(TypeChecker &tc,
2164
2249
/* Throws=*/ superclassCtor->hasThrows (),
2165
2250
/* ThrowsLoc=*/ SourceLoc (),
2166
2251
selfDecl, bodyParams,
2167
- /* GenericParams= */ nullptr , classDecl);
2252
+ genericParams , classDecl);
2168
2253
2169
2254
ctor->setImplicit ();
2170
2255
2171
2256
// Set the interface type of the initializer.
2172
- ctor->setGenericEnvironment (classDecl->getGenericEnvironmentOfContext ());
2173
- tc.configureInterfaceType (ctor, ctor->getGenericSignature ());
2257
+ ctor->setGenericEnvironment (genericEnv);
2258
+
2259
+ tc.configureInterfaceType (ctor, genericSig);
2174
2260
ctor->setValidationStarted ();
2175
2261
2176
2262
configureDesignatedInitAttributes (tc, classDecl,
0 commit comments