@@ -1822,35 +1822,46 @@ void SILGenFunction::emitPropertyWrappedFieldInitAccessor(
18221822 RegularLocation Loc (value);
18231823 Loc.markAutoGenerated ();
18241824
1825- auto loweredFuncDeclTy = F.getLoweredFunctionType ();
1826- bool isLocalContext = vd->getDeclContext ()->isLocalContext ();
1827-
1828- auto createArgument = [&](VarDecl *property, SILType type,
1829- bool markUninitialized = false ) {
1830- auto *arg = ParamDecl::createImplicit (
1831- getASTContext (), property->getBaseIdentifier (),
1832- property->getBaseIdentifier (), property->getInterfaceType (),
1833- declContext, ParamSpecifier::InOut);
1834-
1835- RegularLocation loc (property);
1836- loc.markAutoGenerated ();
1837-
1838- SILValue argValue = F.begin ()->createFunctionArgument (type, arg);
1839- if (markUninitialized) {
1840- argValue = B.createMarkUninitializedOut (loc, argValue);
1841- }
1825+ auto backingStorage = vd->getPropertyWrapperBackingProperty ();
1826+ Type returnTy = vd->getPropertyWrapperBackingPropertyType ();
1827+
1828+ // / This thunk uses its own return convention, unlike a usual function,
1829+ // / by always returning its result indirect, even if the type is trivial.
1830+ // /
1831+ // / Because of that, much of the work that would normally be handled in SILGen
1832+ // / using standard function conventions is done manually here, when
1833+ // / -enable-sil-opaque-values is disabled. Part of the reason for this is
1834+ // / that calls to this accessor are lowered after DefiniteInitialization.
1835+ if (useLoweredAddresses ()) {
1836+ returnTy = TupleType::getEmpty (F.getASTContext ());
1837+
1838+ auto loweredFuncDeclTy = F.getLoweredFunctionType ();
1839+ auto createArgument = [&](VarDecl *property, SILType type,
1840+ bool markUninitialized = false ) {
1841+ auto *arg = ParamDecl::createImplicit (
1842+ getASTContext (), property->getBaseIdentifier (),
1843+ property->getBaseIdentifier (), property->getInterfaceType (),
1844+ declContext, ParamSpecifier::InOut);
1845+
1846+ RegularLocation loc (property);
1847+ loc.markAutoGenerated ();
1848+
1849+ SILValue argValue = F.begin ()->createFunctionArgument (type, arg);
1850+ if (markUninitialized) {
1851+ argValue = B.createMarkUninitializedOut (loc, argValue);
1852+ }
18421853
1843- VarLocs[arg] = VarLoc (argValue, SILAccessEnforcement::Static);
1844- InitAccessorArgumentMappings[property] = arg;
1845- };
1854+ VarLocs[arg] = VarLoc (argValue, SILAccessEnforcement::Static);
1855+ InitAccessorArgumentMappings[property] = arg;
1856+ };
18461857
1847- // Emit @out backing storage argument
1848- auto backingStorage = vd-> getPropertyWrapperBackingProperty ();
1849- auto backingStorageTy = getSILTypeInContext (
1850- loweredFuncDeclTy-> getResults ()[ 0 ], loweredFuncDeclTy );
1851- createArgument (backingStorage, backingStorageTy, /* markUninitialized= */ true );
1858+ // Emit @out backing storage argument
1859+ auto backingStorageTy = getSILTypeInContext (
1860+ loweredFuncDeclTy-> getResults ()[ 0 ], loweredFuncDeclTy);
1861+ createArgument (backingStorage, backingStorageTy, /* markUninitialized= */ true );
1862+ }
18521863
1853- // Emit `newValue` argument
1864+ // Create the `newValue` argument
18541865 ParameterList *params = nullptr ;
18551866 auto newValueParam = new (ctx)
18561867 ParamDecl (SourceLoc (), SourceLoc (), ctx.getIdentifier (" $input_value" ),
@@ -1864,9 +1875,10 @@ void SILGenFunction::emitPropertyWrappedFieldInitAccessor(
18641875
18651876 // Nominal contexts have an extra trailing metatype argument,
18661877 // local contexts do not
1878+ const bool isLocalContext = vd->getDeclContext ()->isLocalContext ();
18671879 auto numIgnoredParams = isLocalContext ? 0 : 1 ;
18681880 emitBasicProlog (declContext, params,
1869- /* selfParam=*/ nullptr , TupleType::getEmpty (F. getASTContext ()) ,
1881+ /* selfParam=*/ nullptr , returnTy ,
18701882 /* errorType=*/ std::nullopt ,
18711883 /* throwsLoc=*/ SourceLoc (),
18721884 /* ignored parameters*/ numIgnoredParams);
@@ -1875,9 +1887,14 @@ void SILGenFunction::emitPropertyWrappedFieldInitAccessor(
18751887 if (!isLocalContext)
18761888 emitConstructorMetatypeArg (*this , vd);
18771889
1878- prepareEpilog (declContext, TupleType::getEmpty (F. getASTContext ()) ,
1890+ prepareEpilog (declContext, returnTy ,
18791891 std::nullopt , CleanupLocation (Loc));
18801892
1893+ if (EmitProfilerIncrement)
1894+ emitProfilerIncrement (value);
1895+
1896+ FullExpr scope (Cleanups, CleanupLocation (value));
1897+
18811898 // Create an opaque value binding that maps 'newValue' to the wrapper's
18821899 // wrappedValue AST placeholder. This makes the argument available when
18831900 // init(wrappedValue:) is emitted
@@ -1889,16 +1906,19 @@ void SILGenFunction::emitPropertyWrappedFieldInitAccessor(
18891906 maybeEmitValueOfLocalVarDecl (newValueParam, AccessKind::Read));
18901907 assert (value == initInfo.getInitFromWrappedValue ());
18911908
1892- // Prepare InitializationPtr for the @out return buffer
1893- FullExpr scope (Cleanups, CleanupLocation (value));
1894- auto backingStorageArg = InitAccessorArgumentMappings[backingStorage];
1895- auto backingStorageAddr = VarLocs[backingStorageArg].value ;
1896- InitializationPtr init (new KnownAddressInitialization (backingStorageAddr));
1909+ if ( useLoweredAddresses ()) {
1910+ // Prepare InitializationPtr for the @out return buffer
1911+ auto backingStorageArg = InitAccessorArgumentMappings[backingStorage];
1912+ auto backingStorageAddr = VarLocs[backingStorageArg].value ;
1913+ InitializationPtr init (new KnownAddressInitialization (backingStorageAddr));
18971914
1898- // Intialize the @out buffer with the given expression
1899- emitExprInto (value, init.get ());
1915+ // Intialize the @out buffer with the given expression
1916+ emitExprInto (value, init.get ());
1917+ } else {
1918+ emitReturnExpr (Loc, value);
1919+ }
19001920
19011921 // Emit epilog/cleanups
19021922 emitEpilog (Loc);
19031923 mergeCleanupBlocks ();
1904- }
1924+ }
0 commit comments