@@ -179,6 +179,12 @@ SILType
179
179
SILFunctionType::getDirectFormalResultsType (SILModule &M,
180
180
TypeExpansionContext context) {
181
181
CanType type;
182
+
183
+ if (hasGuaranteedAddressResults ()) {
184
+ assert (getNumDirectFormalResults () == 1 );
185
+ return SILType::getPrimitiveAddressType (
186
+ getSingleDirectFormalResult ().getReturnValueType (M, this , context));
187
+ }
182
188
if (getNumDirectFormalResults () == 0 ) {
183
189
type = getASTContext ().TheEmptyTupleType ;
184
190
} else if (getNumDirectFormalResults () == 1 ) {
@@ -1374,21 +1380,24 @@ class DestructureResults {
1374
1380
TypeExpansionContext context;
1375
1381
bool hasSendingResult;
1376
1382
bool isBorrowOrMutateAccessor;
1383
+ bool hasSelfWithAddressType;
1377
1384
1378
1385
public:
1379
1386
DestructureResults (TypeExpansionContext context, TypeConverter &TC,
1380
1387
const Conventions &conventions,
1381
1388
SmallVectorImpl<SILResultInfo> &results,
1382
- bool hasSendingResult, bool isBorrowOrMutateAccessor)
1389
+ bool hasSendingResult, bool isBorrowOrMutateAccessor,
1390
+ bool hasSelfWithAddressType)
1383
1391
: TC(TC), Convs(conventions), Results(results), context(context),
1384
1392
hasSendingResult (hasSendingResult),
1385
- isBorrowOrMutateAccessor(isBorrowOrMutateAccessor) {}
1393
+ isBorrowOrMutateAccessor(isBorrowOrMutateAccessor),
1394
+ hasSelfWithAddressType(hasSelfWithAddressType) {}
1386
1395
1387
1396
void destructure (AbstractionPattern origType, CanType substType) {
1388
- bool hasAddressOnlyReturn = false ;
1389
-
1390
1397
// 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) {
1392
1401
origType.forEachTupleElement (substType,
1393
1402
[&](TupleElementGenerator &elt) {
1394
1403
// If the original element type is not a pack expansion, just
@@ -1434,20 +1443,21 @@ class DestructureResults {
1434
1443
1435
1444
// Determine the result convention.
1436
1445
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);
1442
1453
convention = ResultConvention::GuaranteedAddress;
1443
1454
} else {
1444
- convention = ResultConvention::Indirect ;
1455
+ convention = ResultConvention::Guaranteed ;
1445
1456
}
1457
+ } else if (isFormallyReturnedIndirectly (origType, substType,
1458
+ substResultTLForConvention)) {
1459
+ convention = ResultConvention::Indirect;
1446
1460
} 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
- }
1451
1461
convention = Convs.getResult (substResultTLForConvention);
1452
1462
1453
1463
// Reduce conventions for trivial types to an unowned convention.
@@ -1456,7 +1466,6 @@ class DestructureResults {
1456
1466
case ResultConvention::Indirect:
1457
1467
case ResultConvention::Unowned:
1458
1468
case ResultConvention::UnownedInnerPointer:
1459
- case ResultConvention::Guaranteed:
1460
1469
// Leave these as-is.
1461
1470
break ;
1462
1471
@@ -1468,13 +1477,14 @@ class DestructureResults {
1468
1477
1469
1478
case ResultConvention::Autoreleased:
1470
1479
case ResultConvention::Owned:
1480
+ case ResultConvention::Guaranteed:
1471
1481
// These aren't distinguishable from unowned for trivial types.
1472
1482
convention = ResultConvention::Unowned;
1473
1483
break ;
1474
1484
}
1475
1485
}
1476
1486
}
1477
-
1487
+
1478
1488
SILResultInfo result (substResultTL.getLoweredType ().getASTType (),
1479
1489
convention);
1480
1490
if (hasSendingResult)
@@ -2738,12 +2748,16 @@ static CanSILFunctionType getSILFunctionType(
2738
2748
coroutineOrigYieldType, coroutineSubstYieldType,
2739
2749
yields, coroutineKind);
2740
2750
2751
+ bool hasSelfWithAddressType =
2752
+ extInfoBuilder.hasSelfParam () &&
2753
+ inputs.back ().getSILStorageInterfaceType ().isAddress ();
2754
+
2741
2755
// Destructure the result tuple type.
2742
2756
SmallVector<SILResultInfo, 8 > results;
2743
2757
{
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 );
2747
2761
destructurer.destructure (origResultType, substFormalResultType);
2748
2762
}
2749
2763
0 commit comments