@@ -107,6 +107,7 @@ static RValue maybeEmitPropertyWrapperInitFromValue(
107107 SILGenFunction &SGF,
108108 SILLocation loc,
109109 VarDecl *field,
110+ SubstitutionMap subs,
110111 RValue &&arg) {
111112 auto originalProperty = field->getOriginalWrappedProperty ();
112113 if (!originalProperty ||
@@ -118,7 +119,33 @@ static RValue maybeEmitPropertyWrapperInitFromValue(
118119 return std::move (arg);
119120
120121 return SGF.emitApplyOfPropertyWrapperBackingInitializer (loc, originalProperty,
121- std::move (arg));
122+ subs, std::move (arg));
123+ }
124+
125+ static SubstitutionMap getSubstitutionsForPropertyInitializer (
126+ DeclContext *dc,
127+ NominalTypeDecl *nominal) {
128+ // We want a substitution list written in terms of the generic
129+ // signature of the type, with replacement archetypes from the
130+ // constructor's context (which might be in an extension of
131+ // the type, which adds additional generic requirements).
132+ if (auto *genericEnv = dc->getGenericEnvironmentOfContext ()) {
133+ // Generate a set of substitutions for the initialization function,
134+ // whose generic signature is that of the type context, and whose
135+ // replacement types are the archetypes of the initializer itself.
136+ return SubstitutionMap::get (
137+ nominal->getGenericSignatureOfContext (),
138+ [&](SubstitutableType *type) {
139+ if (auto gp = type->getAs <GenericTypeParamType>()) {
140+ return genericEnv->mapTypeIntoContext (gp);
141+ }
142+
143+ return Type (type);
144+ },
145+ LookUpConformanceInModule (dc->getParentModule ()));
146+ }
147+
148+ return SubstitutionMap ();
122149}
123150
124151static void emitImplicitValueConstructor (SILGenFunction &SGF,
@@ -161,6 +188,8 @@ static void emitImplicitValueConstructor(SILGenFunction &SGF,
161188 auto *decl = selfTy.getStructOrBoundGenericStruct ();
162189 assert (decl && " not a struct?!" );
163190
191+ auto subs = getSubstitutionsForPropertyInitializer (decl, decl);
192+
164193 // If we have an indirect return slot, initialize it in-place.
165194 if (resultSlot) {
166195 auto elti = elements.begin (), eltEnd = elements.end ();
@@ -178,7 +207,8 @@ static void emitImplicitValueConstructor(SILGenFunction &SGF,
178207 " number of args does not match number of fields" );
179208 (void )eltEnd;
180209 FullExpr scope (SGF.Cleanups , field->getParentPatternBinding ());
181- maybeEmitPropertyWrapperInitFromValue (SGF, Loc, field, std::move (*elti))
210+ maybeEmitPropertyWrapperInitFromValue (SGF, Loc, field, subs,
211+ std::move (*elti))
182212 .forwardInto (SGF, Loc, init.get ());
183213 ++elti;
184214 } else {
@@ -213,7 +243,7 @@ static void emitImplicitValueConstructor(SILGenFunction &SGF,
213243 assert (elti != eltEnd && " number of args does not match number of fields" );
214244 (void )eltEnd;
215245 v = maybeEmitPropertyWrapperInitFromValue (
216- SGF, Loc, field, std::move (*elti))
246+ SGF, Loc, field, subs, std::move (*elti))
217247 .forwardAsSingleStorageValue (SGF, fieldTy, Loc);
218248 ++elti;
219249 } else {
@@ -912,6 +942,8 @@ static Type getInitializationTypeInContext(
912942void SILGenFunction::emitMemberInitializers (DeclContext *dc,
913943 VarDecl *selfDecl,
914944 NominalTypeDecl *nominal) {
945+ auto subs = getSubstitutionsForPropertyInitializer (dc, nominal);
946+
915947 for (auto member : nominal->getMembers ()) {
916948 // Find instance pattern binding declarations that have initializers.
917949 if (auto pbd = dyn_cast<PatternBindingDecl>(member)) {
@@ -925,30 +957,6 @@ void SILGenFunction::emitMemberInitializers(DeclContext *dc,
925957 // Cleanup after this initialization.
926958 FullExpr scope (Cleanups, varPattern);
927959
928- // We want a substitution list written in terms of the generic
929- // signature of the type, with replacement archetypes from the
930- // constructor's context (which might be in an extension of
931- // the type, which adds additional generic requirements).
932- SubstitutionMap subs;
933- auto *genericEnv = dc->getGenericEnvironmentOfContext ();
934- auto typeGenericSig = nominal->getGenericSignatureOfContext ();
935-
936- if (genericEnv && typeGenericSig) {
937- // Generate a set of substitutions for the initialization function,
938- // whose generic signature is that of the type context, and whose
939- // replacement types are the archetypes of the initializer itself.
940- subs = SubstitutionMap::get (
941- typeGenericSig,
942- [&](SubstitutableType *type) {
943- if (auto gp = type->getAs <GenericTypeParamType>()) {
944- return genericEnv->mapTypeIntoContext (gp);
945- }
946-
947- return Type (type);
948- },
949- LookUpConformanceInModule (dc->getParentModule ()));
950- }
951-
952960 // Get the type of the initialization result, in terms
953961 // of the constructor context's archetypes.
954962 CanType resultType = getInitializationTypeInContext (
@@ -970,7 +978,7 @@ void SILGenFunction::emitMemberInitializers(DeclContext *dc,
970978 if (originalVar &&
971979 originalVar->isPropertyMemberwiseInitializedWithWrappedType ()) {
972980 result = maybeEmitPropertyWrapperInitFromValue (
973- *this , init, singleVar, std::move (result));
981+ *this , init, singleVar, subs, std::move (result));
974982 }
975983 }
976984
0 commit comments