Skip to content

Commit 4f33d52

Browse files
committed
Update SILFunctionType for borrow accessors
1 parent a798f21 commit 4f33d52

File tree

2 files changed

+61
-6
lines changed

2 files changed

+61
-6
lines changed

include/swift/SIL/SILFunctionConventions.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,24 @@ class SILFunctionConventions {
298298
IndirectSILResultFilter(silConv.loweredAddresses));
299299
}
300300

301+
bool hasGuaranteedResults() const {
302+
for (auto result : funcTy->getResults()) {
303+
if (result.getConvention() == ResultConvention::Guaranteed) {
304+
return true;
305+
}
306+
}
307+
return false;
308+
}
309+
310+
bool hasGuaranteedAddressResults() const {
311+
for (auto result : funcTy->getResults()) {
312+
if (result.getConvention() == ResultConvention::GuaranteedAddress) {
313+
return true;
314+
}
315+
}
316+
return false;
317+
}
318+
301319
struct SILResultTypeFunc;
302320

303321
// Gratuitous template parameter is to delay instantiating `mapped_iterator`

lib/SIL/IR/SILFunctionType.cpp

Lines changed: 43 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1373,16 +1373,20 @@ class DestructureResults {
13731373
SmallVectorImpl<SILResultInfo> &Results;
13741374
TypeExpansionContext context;
13751375
bool hasSendingResult;
1376+
bool isBorrowOrMutateAccessor;
13761377

13771378
public:
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+
23412371
static 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

Comments
 (0)