@@ -190,23 +190,44 @@ static void maybeAddMemberwiseDefaultArg(ParamDecl *arg, VarDecl *var,
190
190
191
191
static void maybeAddTypeWrapperDefaultArg (ParamDecl *arg, VarDecl *var,
192
192
ASTContext &ctx) {
193
- assert (var->isAccessedViaTypeWrapper ());
193
+ assert (var->isAccessedViaTypeWrapper () || var-> hasAttachedPropertyWrapper () );
194
194
195
- if (!var->getParentPattern ()-> getSingleVar ())
195
+ if (!( var->getParentPattern () && var-> getParentPattern ()-> getSingleVar () ))
196
196
return ;
197
197
198
198
auto *PBD = var->getParentPatternBinding ();
199
199
200
- auto *initExpr = PBD->getInit (/* index=*/ 0 );
200
+ Expr *initExpr = nullptr ;
201
+
202
+ if (var->hasAttachedPropertyWrapper ()) {
203
+ auto initInfo = var->getPropertyWrapperInitializerInfo ();
204
+
205
+ if (initInfo.hasInitFromWrappedValue ()) {
206
+ initExpr =
207
+ initInfo.getWrappedValuePlaceholder ()->getOriginalWrappedValue ();
208
+ }
209
+ } else {
210
+ initExpr = PBD->getInit (/* index=*/ 0 );
211
+ }
212
+
201
213
if (!initExpr)
202
214
return ;
203
215
204
216
// Type wrapper variables are never initialized directly,
205
217
// initialization expression (if any) becomes an default
206
218
// argument of the initializer synthesized by the type wrapper.
207
- PBD->setInitializerSubsumed (/* index=*/ 0 );
219
+ {
220
+ // Since type wrapper is applied to backing property, that's
221
+ // the the initializer it subsumes.
222
+ if (var->hasAttachedPropertyWrapper ()) {
223
+ auto *backingVar = var->getPropertyWrapperBackingProperty ();
224
+ PBD = backingVar->getParentPatternBinding ();
225
+ }
208
226
209
- arg->setDefaultExpr (initExpr, /* isTypeChecked=*/ false );
227
+ PBD->setInitializerSubsumed (/* index=*/ 0 );
228
+ }
229
+
230
+ arg->setDefaultExpr (initExpr, PBD->isInitializerChecked (/* index=*/ 0 ));
210
231
arg->setDefaultArgumentKind (DefaultArgumentKind::Normal);
211
232
}
212
233
@@ -354,11 +375,51 @@ static ConstructorDecl *createImplicitConstructor(NominalTypeDecl *decl,
354
375
if (!(var && var->isAccessedViaTypeWrapper ()))
355
376
continue ;
356
377
357
- auto *arg = new (ctx) ParamDecl (SourceLoc (), Loc, var->getName (), Loc,
358
- var->getName (), decl);
378
+ Identifier argName = var->getName ();
379
+ Identifier paramName = argName;
380
+
381
+ auto paramInterfaceType = var->getValueInterfaceType ();
382
+ DeclAttributes attrs;
383
+
384
+ // If this is a backing storage of a property wrapped property
385
+ // let's use wrapped property as a parameter and synthesize
386
+ // appropriate property wrapper initialization upon assignment.
387
+ if (auto *wrappedVar = var->getOriginalWrappedProperty (
388
+ PropertyWrapperSynthesizedPropertyKind::Backing)) {
389
+ // If there is `init(wrappedValue:)` or default value for a wrapped
390
+ // property we should use wrapped type, otherwise let's proceed with
391
+ // wrapper type.
392
+ if (wrappedVar->isPropertyMemberwiseInitializedWithWrappedType ()) {
393
+ var = wrappedVar;
394
+ // If parameter have to get wrapped type, let's re-map both argument
395
+ // and parameter name to match wrapped property and let property
396
+ // wrapper attributes generate wrapped value and projection variables.
397
+ argName = wrappedVar->getName ();
398
+ paramName = argName;
399
+
400
+ paramInterfaceType = var->getPropertyWrapperInitValueInterfaceType ();
401
+ // The parameter needs to have all of the property wrapper
402
+ // attributes to generate projection and wrapper variables.
403
+ for (auto *attr : wrappedVar->getAttachedPropertyWrappers ())
404
+ attrs.add (attr);
405
+ } else {
406
+ // If parameter has to have wrapper type then argument type should
407
+ // match that of a wrapped property but parameter name stays the same
408
+ // since it represents the type of backing storage and could be passed
409
+ // to `$Storage` constructor directly.
410
+ argName = wrappedVar->getName ();
411
+ }
412
+ }
413
+
414
+ if (!paramInterfaceType || paramInterfaceType->hasError ())
415
+ continue ;
416
+
417
+ auto *arg =
418
+ new (ctx) ParamDecl (SourceLoc (), Loc, argName, Loc, paramName, decl);
359
419
420
+ arg->getAttrs ().add (attrs);
360
421
arg->setSpecifier (ParamSpecifier::Default);
361
- arg->setInterfaceType (var-> getValueInterfaceType () );
422
+ arg->setInterfaceType (paramInterfaceType );
362
423
arg->setImplicit ();
363
424
364
425
maybeAddTypeWrapperDefaultArg (arg, var, ctx);
0 commit comments