@@ -1295,29 +1295,26 @@ namespace {
1295
1295
1296
1296
bool hasPropertyWrapper () const {
1297
1297
if (auto *VD = dyn_cast<VarDecl>(Storage)) {
1298
- // FIXME: Handle composition of property wrappers.
1299
- if (VD->getAttachedPropertyWrappers ().size () == 1 ) {
1300
- auto wrapperInfo = VD->getAttachedPropertyWrapperTypeInfo (0 );
1301
-
1302
- // If there is no init(wrapperValue:), we cannot rewrite an
1303
- // assignment into an initialization.
1304
- if (!wrapperInfo.wrappedValueInit )
1305
- return false ;
1306
-
1307
- // If we have a nonmutating setter on a value type, the call
1308
- // captures all of 'self' and we cannot rewrite an assignment
1309
- // into an initialization.
1310
- if (!VD->isSetterMutating () &&
1311
- VD->getDeclContext ()->getSelfNominalTypeDecl () &&
1312
- VD->isInstanceMember () &&
1313
- !VD->getDeclContext ()->getDeclaredInterfaceType ()
1314
- ->hasReferenceSemantics ()) {
1315
- return false ;
1316
- }
1317
-
1318
- return true ;
1298
+ // If this is not a wrapper property that can be initialized from
1299
+ // a value of the wrapped type, we can't perform the initialization.
1300
+ auto wrapperInfo = VD->getPropertyWrapperBackingPropertyInfo ();
1301
+ if (!wrapperInfo.initializeFromOriginal )
1302
+ return false ;
1303
+
1304
+ // If we have a nonmutating setter on a value type, the call
1305
+ // captures all of 'self' and we cannot rewrite an assignment
1306
+ // into an initialization.
1307
+ if (!VD->isSetterMutating () &&
1308
+ VD->getDeclContext ()->getSelfNominalTypeDecl () &&
1309
+ VD->isInstanceMember () &&
1310
+ !VD->getDeclContext ()->getDeclaredInterfaceType ()
1311
+ ->hasReferenceSemantics ()) {
1312
+ return false ;
1319
1313
}
1314
+
1315
+ return true ;
1320
1316
}
1317
+
1321
1318
return false ;
1322
1319
}
1323
1320
@@ -1404,25 +1401,32 @@ namespace {
1404
1401
proj = std::move (SEC).project (SGF, loc, base);
1405
1402
}
1406
1403
1407
- // Create the allocating initializer function. It captures the metadata.
1408
- // FIXME: Composition.
1409
- assert (field->getAttachedPropertyWrappers ().size () == 1 );
1410
- auto wrapperInfo = field->getAttachedPropertyWrapperTypeInfo (0 );
1411
- auto ctor = wrapperInfo.wrappedValueInit ;
1412
- SubstitutionMap subs = ValType->getMemberSubstitutionMap (
1413
- SGF.getModule ().getSwiftModule (), ctor);
1414
-
1415
- Type ity = ctor->getInterfaceType ();
1416
- AnyFunctionType *substIty =
1417
- ity.subst (subs)->getCanonicalType ()->castTo <AnyFunctionType>();
1418
-
1419
- auto initRef = SILDeclRef (ctor, SILDeclRef::Kind::Allocator)
1420
- .asForeign (requiresForeignEntryPoint (ctor));
1421
- RValue initFuncRV =
1422
- SGF.emitApplyPropertyWrapperAllocator (loc, subs,initRef,
1423
- ValType,
1424
- CanAnyFunctionType (substIty));
1425
- ManagedValue initFn = std::move (initFuncRV).getAsSingleValue (SGF, loc);
1404
+ // The property wrapper backing initializer forms an instance of
1405
+ // the backing storage type from a wrapped value.
1406
+ SILDeclRef initConstant (
1407
+ field, SILDeclRef::Kind::PropertyWrapperBackingInitializer);
1408
+ SILValue initFRef = SGF.emitGlobalFunctionRef (loc, initConstant);
1409
+
1410
+ SubstitutionMap initSubs;
1411
+ if (auto genericSig = field->getInnermostDeclContext ()
1412
+ ->getGenericSignatureOfContext ()) {
1413
+ initSubs = SubstitutionMap::get (
1414
+ genericSig,
1415
+ [&](SubstitutableType *type) {
1416
+ if (auto gp = type->getAs <GenericTypeParamType>()) {
1417
+ return SGF.F .mapTypeIntoContext (gp);
1418
+ }
1419
+
1420
+ return Type (type);
1421
+ },
1422
+ LookUpConformanceInModule (SGF.SGM .M .getSwiftModule ()));
1423
+ }
1424
+
1425
+ PartialApplyInst *initPAI =
1426
+ SGF.B .createPartialApply (loc, initFRef,
1427
+ initSubs, ArrayRef<SILValue>(),
1428
+ ParameterConvention::Direct_Guaranteed);
1429
+ ManagedValue initFn = SGF.emitManagedRValueWithCleanup (initPAI);
1426
1430
1427
1431
// Create the allocating setter function. It captures the base address.
1428
1432
auto setterInfo = SGF.getConstantInfo (setter);
0 commit comments