Merge pull request #82916 from jckarter/preconcurrency-indirect-return-6.2

[6.2] SILGen: Bitcast indirect returns that differ only in concurrency annotations.
This commit is contained in:
Joe Groff
2025-07-10 12:05:35 -07:00
committed by GitHub
3 changed files with 30 additions and 7 deletions

View File

@@ -754,6 +754,13 @@ public:
SILType subst(SILModule &M, SubstitutionMap subs,
TypeExpansionContext context) const;
/// Strip concurrency annotations from the representation type.
SILType stripConcurrency(bool recursive, bool dropGlobalActor) {
auto strippedASTTy = getASTType()->stripConcurrency(recursive, dropGlobalActor);
return SILType::getPrimitiveType(strippedASTTy->getCanonicalType(),
getCategory());
}
/// Return true if this type references a "ref" type that has a single pointer
/// representation. Class existentials do not always qualify.
bool isHeapObjectReferenceType() const;

View File

@@ -1967,15 +1967,21 @@ static void emitRawApply(SILGenFunction &SGF,
SmallVector<SILValue, 4> argValues;
// Add the buffers for the indirect results if needed.
#ifndef NDEBUG
assert(indirectResultAddrs.size() == substFnConv.getNumIndirectSILResults());
unsigned resultIdx = 0;
for (auto indResultTy :
substFnConv.getIndirectSILResultTypes(SGF.getTypeExpansionContext())) {
assert(indResultTy == indirectResultAddrs[resultIdx++]->getType());
for (auto indResultTy : substFnConv.getIndirectSILResultTypes(SGF.getTypeExpansionContext())) {
auto indResultAddr = indirectResultAddrs[resultIdx++];
if (indResultAddr->getType() != indResultTy) {
// Bitcast away differences in Sendable, global actor, etc.
if (indResultAddr->getType().stripConcurrency(/*recursive*/ true, /*dropGlobalActor*/ true)
== indResultTy.stripConcurrency(/*recursive*/ true, /*dropGlobalActor*/ true)) {
indResultAddr = SGF.B.createUncheckedAddrCast(loc, indResultAddr, indResultTy);
}
}
assert(indResultTy == indResultAddr->getType());
argValues.push_back(indResultAddr);
}
#endif
argValues.append(indirectResultAddrs.begin(), indirectResultAddrs.end());
assert(!!indirectErrorAddr == substFnConv.hasIndirectSILErrorResults());
if (indirectErrorAddr)

View File

@@ -0,0 +1,10 @@
// RUN: %target-swift-emit-silgen %s | %FileCheck %s
@preconcurrency
func test() -> (any Sendable)? { nil }
// CHECK-LABEL: sil {{.*}} @$s{{.*}}callWithPreconcurrency
func callWithPreconcurrency() {
// CHECK: unchecked_addr_cast {{.*}} to $*Optional<any Sendable>
let x = test()
}