@@ -1373,16 +1373,20 @@ class DestructureResults {
13731373 SmallVectorImpl<SILResultInfo> &Results;
13741374 TypeExpansionContext context;
13751375 bool hasSendingResult;
1376+ bool isBorrowOrMutateAccessor;
13761377
13771378public:
13781379 DestructureResults (TypeExpansionContext context, TypeConverter &TC,
13791380 const Conventions &conventions,
13801381 SmallVectorImpl<SILResultInfo> &results,
1381- bool hasSendingResult)
1382+ bool hasSendingResult, bool isBorrowOrMutateAccessor )
13821383 : TC(TC), Convs(conventions), Results(results), context(context),
1383- hasSendingResult (hasSendingResult) {}
1384+ hasSendingResult (hasSendingResult),
1385+ isBorrowOrMutateAccessor(isBorrowOrMutateAccessor) {}
13841386
13851387 void destructure (AbstractionPattern origType, CanType substType) {
1388+ bool hasAddressOnlyReturn = false ;
1389+
13861390 // Recur into tuples.
13871391 if (origType.isTuple ()) {
13881392 origType.forEachTupleElement (substType,
@@ -1394,6 +1398,11 @@ class DestructureResults {
13941398 return ;
13951399 }
13961400
1401+ if (isBorrowOrMutateAccessor) {
1402+ llvm_unreachable (
1403+ " Returning packs from borrow/mutate accessor is not implemented" );
1404+ }
1405+
13971406 // If the original element type is a pack expansion, build a
13981407 // lowered pack type for the substituted components it expands to.
13991408 auto origExpansionType = elt.getOrigType ();
@@ -1427,8 +1436,18 @@ class DestructureResults {
14271436 ResultConvention convention;
14281437 if (isFormallyReturnedIndirectly (origType, substType,
14291438 substResultTLForConvention)) {
1430- convention = ResultConvention::Indirect;
1439+ hasAddressOnlyReturn = true ;
1440+ if (Convs.getResult (substResultTLForConvention) ==
1441+ ResultConvention::Guaranteed) {
1442+ convention = ResultConvention::GuaranteedAddress;
1443+ } else {
1444+ convention = ResultConvention::Indirect;
1445+ }
14311446 } else {
1447+ if (isBorrowOrMutateAccessor && hasAddressOnlyReturn) {
1448+ llvm_unreachable (" Returning a tuple with address-only and loadable "
1449+ " types is not supported in borrow/mutate accessor" );
1450+ }
14321451 convention = Convs.getResult (substResultTLForConvention);
14331452
14341453 // Reduce conventions for trivial types to an unowned convention.
@@ -2338,6 +2357,17 @@ getAsCoroutineAccessor(std::optional<SILDeclRef> constant) {
23382357 return accessor;
23392358}
23402359
2360+ static bool isBorrowOrMutateAccessor (std::optional<SILDeclRef> constant) {
2361+ if (!constant || !constant->hasDecl ())
2362+ return false ;
2363+
2364+ auto accessor = dyn_cast<AccessorDecl>(constant->getDecl ());
2365+ if (!accessor)
2366+ return false ;
2367+
2368+ return accessor->isBorrowAccessor () || accessor->isMutateAccessor ();
2369+ }
2370+
23412371static void destructureYieldsForReadAccessor (TypeConverter &TC,
23422372 TypeExpansionContext expansion,
23432373 AbstractionPattern origType,
@@ -2707,12 +2737,13 @@ static CanSILFunctionType getSILFunctionType(
27072737 destructureYieldsForCoroutine (TC, expansionContext, constant,
27082738 coroutineOrigYieldType, coroutineSubstYieldType,
27092739 yields, coroutineKind);
2710-
2740+
27112741 // Destructure the result tuple type.
27122742 SmallVector<SILResultInfo, 8 > results;
27132743 {
27142744 DestructureResults destructurer (expansionContext, TC, conventions, results,
2715- hasSendingResult);
2745+ hasSendingResult,
2746+ isBorrowOrMutateAccessor (constant));
27162747 destructurer.destructure (origResultType, substFormalResultType);
27172748 }
27182749
@@ -3252,11 +3283,17 @@ static CanSILFunctionType getNativeSILFunctionType(
32523283 if (constant) {
32533284 if (constant->isSetter ()) {
32543285 return getSILFunctionTypeForConventions (DefaultSetterConventions ());
3255- } else if (constant->isInitAccessor ()) {
3286+ }
3287+ if (constant->isInitAccessor ()) {
32563288 return getSILFunctionTypeForInitAccessor (
32573289 TC, context, origType, substInterfaceType, extInfoBuilder,
32583290 DefaultSetterConventions (), *constant);
32593291 }
3292+ if (constant->isBorrowAccessor ()) {
3293+ return getSILFunctionTypeForConventions (
3294+ DefaultConventions (NormalParameterConvention::Guaranteed,
3295+ ResultConvention::Guaranteed));
3296+ }
32603297 }
32613298 return getSILFunctionTypeForConventions (
32623299 DefaultConventions (NormalParameterConvention::Guaranteed));
0 commit comments