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,109 @@ 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
+ // We don't have to clone the requirements, because they're not
2046
+ // used for anything.
2047
+ genericParams = GenericParamList::create (ctx,
2048
+ SourceLoc (),
2049
+ newParams,
2050
+ SourceLoc (),
2051
+ ArrayRef<RequirementRepr>(),
2052
+ SourceLoc ());
2053
+ genericParams->setOuterParameters (classDecl->getGenericParamsOfContext ());
2054
+
2055
+ // Build a generic signature for the derived class initializer.
2056
+ GenericSignatureBuilder builder (ctx);
2057
+ builder.addGenericSignature (classDecl->getGenericSignature ());
2058
+
2059
+ // Add the generic parameters.
2060
+ for (auto *newParam : newParams)
2061
+ builder.addGenericParameter (newParam);
2062
+
2063
+ auto source =
2064
+ 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
+
2094
+ for (auto reqt : superclassSig->getRequirements ())
2095
+ if (auto substReqt = reqt.subst (substFn, lookupConformanceFn))
2096
+ builder.addRequirement (*substReqt, source, nullptr );
2097
+
2098
+ // Now form the substitution map that will be used to remap parameter
2099
+ // types.
2100
+ subMap = superclassSig->getSubstitutionMap (substFn, lookupConformanceFn);
2101
+
2102
+ genericSig = std::move (builder).computeGenericSignature (SourceLoc ());
2103
+ genericEnv = genericSig->createGenericEnvironment ();
2104
+ } else {
2105
+ genericEnv = classDecl->getGenericEnvironment ();
2106
+ genericSig = classDecl->getGenericSignature ();
2107
+ }
2108
+
2109
+ return std::make_tuple (genericSig, genericEnv, genericParams, subMap);
2110
+ }
2111
+
2008
2112
static void configureDesignatedInitAttributes (TypeChecker &tc,
2009
2113
ClassDecl *classDecl,
2010
2114
ConstructorDecl *ctor,
@@ -2082,9 +2186,7 @@ swift::createDesignatedInitOverride(TypeChecker &tc,
2082
2186
ClassDecl *classDecl,
2083
2187
ConstructorDecl *superclassCtor,
2084
2188
DesignatedInitKind kind) {
2085
- // FIXME: Inheriting initializers that have their own generic parameters
2086
- if (superclassCtor->getGenericParams ())
2087
- return nullptr ;
2189
+ auto &ctx = tc.Context ;
2088
2190
2089
2191
// Lookup will sometimes give us initializers that are from the ancestors of
2090
2192
// our immediate superclass. So, from the superclass constructor, we look
@@ -2098,54 +2200,42 @@ swift::createDesignatedInitOverride(TypeChecker &tc,
2098
2200
superclassCtor->getDeclContext ()
2099
2201
->getAsNominalTypeOrNominalTypeExtensionContext ();
2100
2202
Type superclassTy = classDecl->getSuperclass ();
2101
- Type superclassTyInContext = classDecl->mapTypeIntoContext (superclassTy);
2102
2203
NominalTypeDecl *superclassDecl = superclassTy->getAnyNominal ();
2103
2204
if (superclassCtorDecl != superclassDecl) {
2104
2205
return nullptr ;
2105
2206
}
2106
2207
2208
+ GenericSignature *genericSig;
2209
+ GenericEnvironment *genericEnv;
2210
+ GenericParamList *genericParams;
2211
+ SubstitutionMap subMap;
2212
+
2213
+ std::tie (genericSig, genericEnv, genericParams, subMap) =
2214
+ configureGenericDesignatedInitOverride (ctx,
2215
+ classDecl,
2216
+ superclassTy,
2217
+ superclassCtor);
2218
+
2107
2219
// Determine the initializer parameters.
2108
- auto &ctx = tc.Context ;
2109
2220
2110
2221
// Create the 'self' declaration and patterns.
2111
2222
auto *selfDecl = ParamDecl::createSelf (SourceLoc (), classDecl);
2112
2223
2113
2224
// Create the initializer parameter patterns.
2114
2225
OptionSet<ParameterList::CloneFlags> options = ParameterList::Implicit;
2115
2226
options |= ParameterList::Inherited;
2116
- auto *bodyParams = superclassCtor->getParameterList (1 )->clone (ctx,options);
2227
+ auto *bodyParams = superclassCtor->getParameterList (1 )->clone (ctx, options);
2117
2228
2118
2229
// If the superclass is generic, we need to map the superclass constructor's
2119
2230
// parameter types into the generic context of our class.
2120
2231
//
2121
2232
// We might have to apply substitutions, if for example we have a declaration
2122
2233
// like 'class A : B<Int>'.
2123
- if (superclassDecl->getGenericSignatureOfContext ()) {
2124
- auto *moduleDecl = classDecl->getParentModule ();
2125
- auto subMap = superclassTyInContext->getContextSubstitutionMap (
2126
- moduleDecl,
2127
- superclassDecl,
2128
- classDecl->getGenericEnvironment ());
2129
-
2130
- for (auto *decl : *bodyParams) {
2131
- auto paramTy = decl->getInterfaceType ()->getInOutObjectType ();
2132
-
2133
- // Apply the superclass substitutions to produce a contextual
2134
- // type in terms of the derived class archetypes.
2135
- auto paramSubstTy = paramTy.subst (subMap);
2136
- decl->setType (paramSubstTy);
2137
-
2138
- // Map it to an interface type in terms of the derived class
2139
- // generic signature.
2140
- decl->setInterfaceType (paramSubstTy->mapTypeOutOfContext ());
2141
- }
2142
- } else {
2143
- for (auto *decl : *bodyParams) {
2144
- if (!decl->hasType ())
2145
- decl->setType (
2146
- classDecl->mapTypeIntoContext (
2147
- decl->getInterfaceType ()->getInOutObjectType ()));
2148
- }
2234
+ for (auto *decl : *bodyParams) {
2235
+ auto paramTy = decl->getInterfaceType ()->getInOutObjectType ();
2236
+ auto substTy = paramTy.subst (subMap);
2237
+ decl->setInterfaceType (substTy);
2238
+ decl->setType (GenericEnvironment::mapTypeIntoContext (genericEnv, substTy));
2149
2239
}
2150
2240
2151
2241
// Create the initializer declaration, inheriting the name,
@@ -2158,13 +2248,14 @@ swift::createDesignatedInitOverride(TypeChecker &tc,
2158
2248
/* Throws=*/ superclassCtor->hasThrows (),
2159
2249
/* ThrowsLoc=*/ SourceLoc (),
2160
2250
selfDecl, bodyParams,
2161
- /* GenericParams= */ nullptr , classDecl);
2251
+ genericParams , classDecl);
2162
2252
2163
2253
ctor->setImplicit ();
2164
2254
2165
2255
// Set the interface type of the initializer.
2166
- ctor->setGenericEnvironment (classDecl->getGenericEnvironmentOfContext ());
2167
- tc.configureInterfaceType (ctor, ctor->getGenericSignature ());
2256
+ ctor->setGenericEnvironment (genericEnv);
2257
+
2258
+ tc.configureInterfaceType (ctor, genericSig);
2168
2259
ctor->setValidationStarted ();
2169
2260
2170
2261
configureDesignatedInitAttributes (tc, classDecl,
0 commit comments