@@ -179,6 +179,12 @@ SILType
179179SILFunctionType::getDirectFormalResultsType (SILModule &M,
180180 TypeExpansionContext context) {
181181 CanType type;
182+
183+ if (hasGuaranteedAddressResults ()) {
184+ assert (getNumDirectFormalResults () == 1 );
185+ return SILType::getPrimitiveAddressType (
186+ getSingleDirectFormalResult ().getReturnValueType (M, this , context));
187+ }
182188 if (getNumDirectFormalResults () == 0 ) {
183189 type = getASTContext ().TheEmptyTupleType ;
184190 } else if (getNumDirectFormalResults () == 1 ) {
@@ -1374,21 +1380,24 @@ class DestructureResults {
13741380 TypeExpansionContext context;
13751381 bool hasSendingResult;
13761382 bool isBorrowOrMutateAccessor;
1383+ bool hasSelfWithAddressType;
13771384
13781385public:
13791386 DestructureResults (TypeExpansionContext context, TypeConverter &TC,
13801387 const Conventions &conventions,
13811388 SmallVectorImpl<SILResultInfo> &results,
1382- bool hasSendingResult, bool isBorrowOrMutateAccessor)
1389+ bool hasSendingResult, bool isBorrowOrMutateAccessor,
1390+ bool hasSelfWithAddressType)
13831391 : TC(TC), Convs(conventions), Results(results), context(context),
13841392 hasSendingResult (hasSendingResult),
1385- isBorrowOrMutateAccessor(isBorrowOrMutateAccessor) {}
1393+ isBorrowOrMutateAccessor(isBorrowOrMutateAccessor),
1394+ hasSelfWithAddressType(hasSelfWithAddressType) {}
13861395
13871396 void destructure (AbstractionPattern origType, CanType substType) {
1388- bool hasAddressOnlyReturn = false ;
1389-
13901397 // Recur into tuples.
1391- if (origType.isTuple ()) {
1398+ // Do not explode tuples for borrow and mutate accessors since we cannot
1399+ // explode and reconstruct addresses.
1400+ if (origType.isTuple () && !isBorrowOrMutateAccessor) {
13921401 origType.forEachTupleElement (substType,
13931402 [&](TupleElementGenerator &elt) {
13941403 // If the original element type is not a pack expansion, just
@@ -1434,20 +1443,21 @@ class DestructureResults {
14341443
14351444 // Determine the result convention.
14361445 ResultConvention convention;
1437- if (isFormallyReturnedIndirectly (origType, substType,
1438- substResultTLForConvention)) {
1439- hasAddressOnlyReturn = true ;
1440- if (Convs.getResult (substResultTLForConvention) ==
1441- ResultConvention::Guaranteed) {
1446+
1447+ if (isBorrowOrMutateAccessor) {
1448+ if ((hasSelfWithAddressType && !substResultTL.isTrivial ()) ||
1449+ isFormallyReturnedIndirectly (origType, substType,
1450+ substResultTLForConvention)) {
1451+ assert (Convs.getResult (substResultTLForConvention) ==
1452+ ResultConvention::Guaranteed);
14421453 convention = ResultConvention::GuaranteedAddress;
14431454 } else {
1444- convention = ResultConvention::Indirect ;
1455+ convention = ResultConvention::Guaranteed ;
14451456 }
1457+ } else if (isFormallyReturnedIndirectly (origType, substType,
1458+ substResultTLForConvention)) {
1459+ convention = ResultConvention::Indirect;
14461460 } 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- }
14511461 convention = Convs.getResult (substResultTLForConvention);
14521462
14531463 // Reduce conventions for trivial types to an unowned convention.
@@ -1456,7 +1466,6 @@ class DestructureResults {
14561466 case ResultConvention::Indirect:
14571467 case ResultConvention::Unowned:
14581468 case ResultConvention::UnownedInnerPointer:
1459- case ResultConvention::Guaranteed:
14601469 // Leave these as-is.
14611470 break ;
14621471
@@ -1468,13 +1477,14 @@ class DestructureResults {
14681477
14691478 case ResultConvention::Autoreleased:
14701479 case ResultConvention::Owned:
1480+ case ResultConvention::Guaranteed:
14711481 // These aren't distinguishable from unowned for trivial types.
14721482 convention = ResultConvention::Unowned;
14731483 break ;
14741484 }
14751485 }
14761486 }
1477-
1487+
14781488 SILResultInfo result (substResultTL.getLoweredType ().getASTType (),
14791489 convention);
14801490 if (hasSendingResult)
@@ -2738,12 +2748,16 @@ static CanSILFunctionType getSILFunctionType(
27382748 coroutineOrigYieldType, coroutineSubstYieldType,
27392749 yields, coroutineKind);
27402750
2751+ bool hasSelfWithAddressType =
2752+ extInfoBuilder.hasSelfParam () &&
2753+ inputs.back ().getSILStorageInterfaceType ().isAddress ();
2754+
27412755 // Destructure the result tuple type.
27422756 SmallVector<SILResultInfo, 8 > results;
27432757 {
2744- DestructureResults destructurer (expansionContext, TC, conventions, results,
2745- hasSendingResult,
2746- isBorrowOrMutateAccessor (constant));
2758+ DestructureResults destructurer (
2759+ expansionContext, TC, conventions, results, hasSendingResult,
2760+ isBorrowOrMutateAccessor (constant), hasSelfWithAddressType );
27472761 destructurer.destructure (origResultType, substFormalResultType);
27482762 }
27492763
0 commit comments