mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
SILGen: Bitcast indirect returns that differ only in concurrency annotations.
A call to a `@preconcurrency` function goes through a function conversion that removes `Sendable` from existentials among other things. Implement support for this by bitcasting indirect return slots whose type differs from the formal indirect return type in concurrency markings only. Fixes rdar://154240007
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -1966,15 +1966,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)
|
||||
|
||||
10
test/SILGen/preconcurrency_indirect_return.swift
Normal file
10
test/SILGen/preconcurrency_indirect_return.swift
Normal 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()
|
||||
}
|
||||
Reference in New Issue
Block a user