@@ -107,6 +107,7 @@ static RValue maybeEmitPropertyWrapperInitFromValue(
107
107
SILGenFunction &SGF,
108
108
SILLocation loc,
109
109
VarDecl *field,
110
+ SubstitutionMap subs,
110
111
RValue &&arg) {
111
112
auto originalProperty = field->getOriginalWrappedProperty ();
112
113
if (!originalProperty ||
@@ -118,7 +119,33 @@ static RValue maybeEmitPropertyWrapperInitFromValue(
118
119
return std::move (arg);
119
120
120
121
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 ();
122
149
}
123
150
124
151
static void emitImplicitValueConstructor (SILGenFunction &SGF,
@@ -161,6 +188,8 @@ static void emitImplicitValueConstructor(SILGenFunction &SGF,
161
188
auto *decl = selfTy.getStructOrBoundGenericStruct ();
162
189
assert (decl && " not a struct?!" );
163
190
191
+ auto subs = getSubstitutionsForPropertyInitializer (decl, decl);
192
+
164
193
// If we have an indirect return slot, initialize it in-place.
165
194
if (resultSlot) {
166
195
auto elti = elements.begin (), eltEnd = elements.end ();
@@ -178,7 +207,8 @@ static void emitImplicitValueConstructor(SILGenFunction &SGF,
178
207
" number of args does not match number of fields" );
179
208
(void )eltEnd;
180
209
FullExpr scope (SGF.Cleanups , field->getParentPatternBinding ());
181
- maybeEmitPropertyWrapperInitFromValue (SGF, Loc, field, std::move (*elti))
210
+ maybeEmitPropertyWrapperInitFromValue (SGF, Loc, field, subs,
211
+ std::move (*elti))
182
212
.forwardInto (SGF, Loc, init.get ());
183
213
++elti;
184
214
} else {
@@ -213,7 +243,7 @@ static void emitImplicitValueConstructor(SILGenFunction &SGF,
213
243
assert (elti != eltEnd && " number of args does not match number of fields" );
214
244
(void )eltEnd;
215
245
v = maybeEmitPropertyWrapperInitFromValue (
216
- SGF, Loc, field, std::move (*elti))
246
+ SGF, Loc, field, subs, std::move (*elti))
217
247
.forwardAsSingleStorageValue (SGF, fieldTy, Loc);
218
248
++elti;
219
249
} else {
@@ -912,6 +942,8 @@ static Type getInitializationTypeInContext(
912
942
void SILGenFunction::emitMemberInitializers (DeclContext *dc,
913
943
VarDecl *selfDecl,
914
944
NominalTypeDecl *nominal) {
945
+ auto subs = getSubstitutionsForPropertyInitializer (dc, nominal);
946
+
915
947
for (auto member : nominal->getMembers ()) {
916
948
// Find instance pattern binding declarations that have initializers.
917
949
if (auto pbd = dyn_cast<PatternBindingDecl>(member)) {
@@ -925,30 +957,6 @@ void SILGenFunction::emitMemberInitializers(DeclContext *dc,
925
957
// Cleanup after this initialization.
926
958
FullExpr scope (Cleanups, varPattern);
927
959
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
-
952
960
// Get the type of the initialization result, in terms
953
961
// of the constructor context's archetypes.
954
962
CanType resultType = getInitializationTypeInContext (
@@ -970,7 +978,7 @@ void SILGenFunction::emitMemberInitializers(DeclContext *dc,
970
978
if (originalVar &&
971
979
originalVar->isPropertyMemberwiseInitializedWithWrappedType ()) {
972
980
result = maybeEmitPropertyWrapperInitFromValue (
973
- *this , init, singleVar, std::move (result));
981
+ *this , init, singleVar, subs, std::move (result));
974
982
}
975
983
}
976
984
0 commit comments