@@ -128,7 +128,7 @@ ArgumentList *swift::buildForwardingArgumentList(ArrayRef<ParamDecl *> params,
128
128
}
129
129
130
130
static void maybeAddMemberwiseDefaultArg (ParamDecl *arg, VarDecl *var,
131
- unsigned paramSize, ASTContext &ctx) {
131
+ ASTContext &ctx) {
132
132
// First and foremost, if this is a constant don't bother.
133
133
if (var->isLet ())
134
134
return ;
@@ -250,6 +250,74 @@ enum class ImplicitConstructorKind {
250
250
TypeWrapper,
251
251
};
252
252
253
+ static ParamDecl *createMemberwiseInitParameter (DeclContext *DC,
254
+ SourceLoc paramLoc,
255
+ VarDecl *var) {
256
+ auto &ctx = var->getASTContext ();
257
+ auto varInterfaceType = var->getValueInterfaceType ();
258
+ bool isAutoClosure = false ;
259
+
260
+ if (var->getAttrs ().hasAttribute <LazyAttr>()) {
261
+ // If var is a lazy property, its value is provided for the underlying
262
+ // storage. We thus take an optional of the property's type. We only
263
+ // need to do this because the implicit initializer is added before all
264
+ // the properties are type checked. Perhaps init() synth should be
265
+ // moved later.
266
+ varInterfaceType = OptionalType::get (varInterfaceType);
267
+ } else if (Type backingPropertyType =
268
+ var->getPropertyWrapperBackingPropertyType ()) {
269
+ // For a property that has a wrapper, writing the initializer
270
+ // with an '=' implies that the memberwise initializer should also
271
+ // accept a value of the original property type. Otherwise, the
272
+ // memberwise initializer will be in terms of the backing storage
273
+ // type.
274
+ if (var->isPropertyMemberwiseInitializedWithWrappedType ()) {
275
+ varInterfaceType = var->getPropertyWrapperInitValueInterfaceType ();
276
+
277
+ auto initInfo = var->getPropertyWrapperInitializerInfo ();
278
+ isAutoClosure = initInfo.getWrappedValuePlaceholder ()->isAutoClosure ();
279
+ } else {
280
+ varInterfaceType = backingPropertyType;
281
+ }
282
+ }
283
+
284
+ Type resultBuilderType = var->getResultBuilderType ();
285
+ if (resultBuilderType) {
286
+ // If the variable's type is structurally a function type, use that
287
+ // type. Otherwise, form a non-escaping function type for the function
288
+ // parameter.
289
+ bool isStructuralFunctionType =
290
+ varInterfaceType->lookThroughAllOptionalTypes ()->is <AnyFunctionType>();
291
+ if (!isStructuralFunctionType) {
292
+ auto extInfo = ASTExtInfoBuilder ().withNoEscape ().build ();
293
+ varInterfaceType = FunctionType::get ({}, varInterfaceType, extInfo);
294
+ }
295
+ }
296
+
297
+ // Create the parameter.
298
+ auto *arg = new (ctx) ParamDecl (SourceLoc (), paramLoc, var->getName (),
299
+ paramLoc, var->getName (), DC);
300
+ arg->setSpecifier (ParamSpecifier::Default);
301
+ arg->setInterfaceType (varInterfaceType);
302
+ arg->setImplicit ();
303
+ arg->setAutoClosure (isAutoClosure);
304
+
305
+ // Don't allow the parameter to accept temporary pointer conversions.
306
+ arg->setNonEphemeralIfPossible ();
307
+
308
+ // Attach a result builder attribute if needed.
309
+ if (resultBuilderType) {
310
+ auto typeExpr = TypeExpr::createImplicit (resultBuilderType, ctx);
311
+ auto attr =
312
+ CustomAttr::create (ctx, SourceLoc (), typeExpr, /* implicit=*/ true );
313
+ arg->getAttrs ().add (attr);
314
+ }
315
+
316
+ maybeAddMemberwiseDefaultArg (arg, var, ctx);
317
+
318
+ return arg;
319
+ }
320
+
253
321
// / Create an implicit struct or class constructor.
254
322
// /
255
323
// / \param decl The struct or class for which a constructor will be created.
@@ -281,70 +349,7 @@ static ConstructorDecl *createImplicitConstructor(NominalTypeDecl *decl,
281
349
282
350
accessLevel = std::min (accessLevel, var->getFormalAccess ());
283
351
284
- auto varInterfaceType = var->getValueInterfaceType ();
285
- bool isAutoClosure = false ;
286
-
287
- if (var->getAttrs ().hasAttribute <LazyAttr>()) {
288
- // If var is a lazy property, its value is provided for the underlying
289
- // storage. We thus take an optional of the property's type. We only
290
- // need to do this because the implicit initializer is added before all
291
- // the properties are type checked. Perhaps init() synth should be
292
- // moved later.
293
- varInterfaceType = OptionalType::get (varInterfaceType);
294
- } else if (Type backingPropertyType =
295
- var->getPropertyWrapperBackingPropertyType ()) {
296
- // For a property that has a wrapper, writing the initializer
297
- // with an '=' implies that the memberwise initializer should also
298
- // accept a value of the original property type. Otherwise, the
299
- // memberwise initializer will be in terms of the backing storage
300
- // type.
301
- if (var->isPropertyMemberwiseInitializedWithWrappedType ()) {
302
- varInterfaceType = var->getPropertyWrapperInitValueInterfaceType ();
303
-
304
- auto initInfo = var->getPropertyWrapperInitializerInfo ();
305
- isAutoClosure = initInfo.getWrappedValuePlaceholder ()->isAutoClosure ();
306
- } else {
307
- varInterfaceType = backingPropertyType;
308
- }
309
- }
310
-
311
- Type resultBuilderType= var->getResultBuilderType ();
312
- if (resultBuilderType) {
313
- // If the variable's type is structurally a function type, use that
314
- // type. Otherwise, form a non-escaping function type for the function
315
- // parameter.
316
- bool isStructuralFunctionType =
317
- varInterfaceType->lookThroughAllOptionalTypes ()
318
- ->is <AnyFunctionType>();
319
- if (!isStructuralFunctionType) {
320
- auto extInfo = ASTExtInfoBuilder ().withNoEscape ().build ();
321
- varInterfaceType = FunctionType::get ({ }, varInterfaceType, extInfo);
322
- }
323
- }
324
-
325
- // Create the parameter.
326
- auto *arg = new (ctx)
327
- ParamDecl (SourceLoc (), Loc,
328
- var->getName (), Loc, var->getName (), decl);
329
- arg->setSpecifier (ParamSpecifier::Default);
330
- arg->setInterfaceType (varInterfaceType);
331
- arg->setImplicit ();
332
- arg->setAutoClosure (isAutoClosure);
333
-
334
- // Don't allow the parameter to accept temporary pointer conversions.
335
- arg->setNonEphemeralIfPossible ();
336
-
337
- // Attach a result builder attribute if needed.
338
- if (resultBuilderType) {
339
- auto typeExpr = TypeExpr::createImplicit (resultBuilderType, ctx);
340
- auto attr = CustomAttr::create (
341
- ctx, SourceLoc (), typeExpr, /* implicit=*/ true );
342
- arg->getAttrs ().add (attr);
343
- }
344
-
345
- maybeAddMemberwiseDefaultArg (arg, var, params.size (), ctx);
346
-
347
- params.push_back (arg);
352
+ params.push_back (createMemberwiseInitParameter (decl, Loc, var));
348
353
}
349
354
} else if (ICK == ImplicitConstructorKind::DefaultDistributedActor) {
350
355
auto classDecl = dyn_cast<ClassDecl>(decl);
0 commit comments