Update SILFunctionType for borrow accessors

This commit is contained in:
Meghana Gupta
2025-08-09 06:37:00 -07:00
parent a798f21fd2
commit 4f33d5201c
2 changed files with 61 additions and 6 deletions

View File

@@ -298,6 +298,24 @@ public:
IndirectSILResultFilter(silConv.loweredAddresses)); IndirectSILResultFilter(silConv.loweredAddresses));
} }
bool hasGuaranteedResults() const {
for (auto result : funcTy->getResults()) {
if (result.getConvention() == ResultConvention::Guaranteed) {
return true;
}
}
return false;
}
bool hasGuaranteedAddressResults() const {
for (auto result : funcTy->getResults()) {
if (result.getConvention() == ResultConvention::GuaranteedAddress) {
return true;
}
}
return false;
}
struct SILResultTypeFunc; struct SILResultTypeFunc;
// Gratuitous template parameter is to delay instantiating `mapped_iterator` // Gratuitous template parameter is to delay instantiating `mapped_iterator`

View File

@@ -1373,16 +1373,20 @@ class DestructureResults {
SmallVectorImpl<SILResultInfo> &Results; SmallVectorImpl<SILResultInfo> &Results;
TypeExpansionContext context; TypeExpansionContext context;
bool hasSendingResult; bool hasSendingResult;
bool isBorrowOrMutateAccessor;
public: public:
DestructureResults(TypeExpansionContext context, TypeConverter &TC, DestructureResults(TypeExpansionContext context, TypeConverter &TC,
const Conventions &conventions, const Conventions &conventions,
SmallVectorImpl<SILResultInfo> &results, SmallVectorImpl<SILResultInfo> &results,
bool hasSendingResult) bool hasSendingResult, bool isBorrowOrMutateAccessor)
: TC(TC), Convs(conventions), Results(results), context(context), : TC(TC), Convs(conventions), Results(results), context(context),
hasSendingResult(hasSendingResult) {} hasSendingResult(hasSendingResult),
isBorrowOrMutateAccessor(isBorrowOrMutateAccessor) {}
void destructure(AbstractionPattern origType, CanType substType) { void destructure(AbstractionPattern origType, CanType substType) {
bool hasAddressOnlyReturn = false;
// Recur into tuples. // Recur into tuples.
if (origType.isTuple()) { if (origType.isTuple()) {
origType.forEachTupleElement(substType, origType.forEachTupleElement(substType,
@@ -1394,6 +1398,11 @@ public:
return; return;
} }
if (isBorrowOrMutateAccessor) {
llvm_unreachable(
"Returning packs from borrow/mutate accessor is not implemented");
}
// If the original element type is a pack expansion, build a // If the original element type is a pack expansion, build a
// lowered pack type for the substituted components it expands to. // lowered pack type for the substituted components it expands to.
auto origExpansionType = elt.getOrigType(); auto origExpansionType = elt.getOrigType();
@@ -1427,8 +1436,18 @@ public:
ResultConvention convention; ResultConvention convention;
if (isFormallyReturnedIndirectly(origType, substType, if (isFormallyReturnedIndirectly(origType, substType,
substResultTLForConvention)) { substResultTLForConvention)) {
convention = ResultConvention::Indirect; hasAddressOnlyReturn = true;
if (Convs.getResult(substResultTLForConvention) ==
ResultConvention::Guaranteed) {
convention = ResultConvention::GuaranteedAddress;
} else {
convention = ResultConvention::Indirect;
}
} else { } else {
if (isBorrowOrMutateAccessor && hasAddressOnlyReturn) {
llvm_unreachable("Returning a tuple with address-only and loadable "
"types is not supported in borrow/mutate accessor");
}
convention = Convs.getResult(substResultTLForConvention); convention = Convs.getResult(substResultTLForConvention);
// Reduce conventions for trivial types to an unowned convention. // Reduce conventions for trivial types to an unowned convention.
@@ -2338,6 +2357,17 @@ getAsCoroutineAccessor(std::optional<SILDeclRef> constant) {
return accessor; return accessor;
} }
static bool isBorrowOrMutateAccessor(std::optional<SILDeclRef> constant) {
if (!constant || !constant->hasDecl())
return false;
auto accessor = dyn_cast<AccessorDecl>(constant->getDecl());
if (!accessor)
return false;
return accessor->isBorrowAccessor() || accessor->isMutateAccessor();
}
static void destructureYieldsForReadAccessor(TypeConverter &TC, static void destructureYieldsForReadAccessor(TypeConverter &TC,
TypeExpansionContext expansion, TypeExpansionContext expansion,
AbstractionPattern origType, AbstractionPattern origType,
@@ -2707,12 +2737,13 @@ static CanSILFunctionType getSILFunctionType(
destructureYieldsForCoroutine(TC, expansionContext, constant, destructureYieldsForCoroutine(TC, expansionContext, constant,
coroutineOrigYieldType, coroutineSubstYieldType, coroutineOrigYieldType, coroutineSubstYieldType,
yields, coroutineKind); yields, coroutineKind);
// Destructure the result tuple type. // Destructure the result tuple type.
SmallVector<SILResultInfo, 8> results; SmallVector<SILResultInfo, 8> results;
{ {
DestructureResults destructurer(expansionContext, TC, conventions, results, DestructureResults destructurer(expansionContext, TC, conventions, results,
hasSendingResult); hasSendingResult,
isBorrowOrMutateAccessor(constant));
destructurer.destructure(origResultType, substFormalResultType); destructurer.destructure(origResultType, substFormalResultType);
} }
@@ -3252,11 +3283,17 @@ static CanSILFunctionType getNativeSILFunctionType(
if (constant) { if (constant) {
if (constant->isSetter()) { if (constant->isSetter()) {
return getSILFunctionTypeForConventions(DefaultSetterConventions()); return getSILFunctionTypeForConventions(DefaultSetterConventions());
} else if (constant->isInitAccessor()) { }
if (constant->isInitAccessor()) {
return getSILFunctionTypeForInitAccessor( return getSILFunctionTypeForInitAccessor(
TC, context, origType, substInterfaceType, extInfoBuilder, TC, context, origType, substInterfaceType, extInfoBuilder,
DefaultSetterConventions(), *constant); DefaultSetterConventions(), *constant);
} }
if (constant->isBorrowAccessor()) {
return getSILFunctionTypeForConventions(
DefaultConventions(NormalParameterConvention::Guaranteed,
ResultConvention::Guaranteed));
}
} }
return getSILFunctionTypeForConventions( return getSILFunctionTypeForConventions(
DefaultConventions(NormalParameterConvention::Guaranteed)); DefaultConventions(NormalParameterConvention::Guaranteed));