Skip to content

Commit 8345174

Browse files
Merge pull request swiftlang#38370 from nate-chandler/rdar79383990
[SILGen] Used formal type when bridging completion handler arguments.
2 parents 41a1761 + c493632 commit 8345174

File tree

14 files changed

+132
-63
lines changed

14 files changed

+132
-63
lines changed

include/swift/SIL/AbstractionPattern.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1378,6 +1378,13 @@ class AbstractionPattern {
13781378
/// Swift type.
13791379
AbstractionPattern getObjCMethodAsyncCompletionHandlerType(
13801380
CanType swiftCompletionHandlerType) const;
1381+
1382+
/// If this pattern refers to a foreign ObjC method that was imported as
1383+
/// async, return the bridged-back-to-ObjC completion handler type.
1384+
CanType getObjCMethodAsyncCompletionHandlerForeignType(
1385+
ForeignAsyncConvention convention,
1386+
Lowering::TypeConverter &TC
1387+
) const;
13811388

13821389
void dump() const LLVM_ATTRIBUTE_USED;
13831390
void print(raw_ostream &OS) const;

lib/SIL/IR/AbstractionPattern.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -662,6 +662,30 @@ AbstractionPattern::getObjCMethodAsyncCompletionHandlerType(
662662
llvm_unreachable("covered switch");
663663
}
664664

665+
666+
CanType AbstractionPattern::getObjCMethodAsyncCompletionHandlerForeignType(
667+
ForeignAsyncConvention convention,
668+
Lowering::TypeConverter &TC
669+
) const {
670+
auto nativeCHTy = convention.completionHandlerType();
671+
672+
// Use the abstraction pattern we're lowering against in order to lower
673+
// the completion handler type, so we can preserve C/ObjC distinctions that
674+
// normally get abstracted away by the importer.
675+
auto completionHandlerNativeOrigTy = getObjCMethodAsyncCompletionHandlerType(nativeCHTy);
676+
677+
// Bridge the Swift completion handler type back to its
678+
// foreign representation.
679+
auto foreignCHTy = TC.getLoweredBridgedType(completionHandlerNativeOrigTy,
680+
nativeCHTy,
681+
Bridgeability::Full,
682+
SILFunctionTypeRepresentation::ObjCMethod,
683+
TypeConverter::ForArgument)
684+
->getCanonicalType();
685+
686+
return foreignCHTy;
687+
}
688+
665689
AbstractionPattern
666690
AbstractionPattern::getFunctionParamType(unsigned index) const {
667691
switch (getKind()) {

lib/SIL/IR/SILFunctionType.cpp

Lines changed: 3 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1674,25 +1674,9 @@ class DestructureInputs {
16741674
|| NextOrigParamIndex != Foreign.Async->completionHandlerParamIndex())
16751675
return false;
16761676

1677-
auto nativeCHTy = Foreign.Async->completionHandlerType();
1678-
1679-
// Use the abstraction pattern we're lowering against in order to lower
1680-
// the completion handler type, so we can preserve C/ObjC distinctions that
1681-
// normally get abstracted away by the importer.
1682-
auto completionHandlerNativeOrigTy = TopLevelOrigType
1683-
.getObjCMethodAsyncCompletionHandlerType(nativeCHTy);
1684-
1685-
// Bridge the Swift completion handler type back to its
1686-
// foreign representation.
1687-
auto foreignCHTy = TC.getLoweredBridgedType(completionHandlerNativeOrigTy,
1688-
nativeCHTy,
1689-
Bridgeability::Full,
1690-
SILFunctionTypeRepresentation::ObjCMethod,
1691-
TypeConverter::ForArgument)
1692-
->getCanonicalType();
1693-
1694-
auto completionHandlerOrigTy = TopLevelOrigType
1695-
.getObjCMethodAsyncCompletionHandlerType(foreignCHTy);
1677+
CanType foreignCHTy = TopLevelOrigType
1678+
.getObjCMethodAsyncCompletionHandlerForeignType(Foreign.Async.getValue(), TC);
1679+
auto completionHandlerOrigTy = TopLevelOrigType.getObjCMethodAsyncCompletionHandlerType(foreignCHTy);
16961680
auto completionHandlerTy = TC.getLoweredType(completionHandlerOrigTy,
16971681
foreignCHTy, expansion)
16981682
.getASTType();

lib/SIL/IR/SILInstructions.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2822,7 +2822,7 @@ SILType GetAsyncContinuationInstBase::getLoweredResumeType() const {
28222822
auto formalType = getFormalResumeType();
28232823
auto &M = getFunction()->getModule();
28242824
auto c = getFunction()->getTypeExpansionContext();
2825-
return M.Types.getLoweredType(AbstractionPattern::getOpaque(), formalType, c);
2825+
return M.Types.getLoweredType(AbstractionPattern(formalType), formalType, c);
28262826
}
28272827

28282828
ReturnInst::ReturnInst(SILFunction &func, SILDebugLocation debugLoc,

lib/SILGen/Callee.h

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ namespace Lowering {
2323

2424
class CalleeTypeInfo {
2525
public:
26+
Optional<AbstractionPattern> origFormalType;
2627
CanSILFunctionType substFnType;
2728
Optional<AbstractionPattern> origResultType;
2829
CanType substResultType;
@@ -45,17 +46,18 @@ class CalleeTypeInfo {
4546
const Optional<ForeignAsyncConvention> &foreignAsync,
4647
ImportAsMemberStatus foreignSelf,
4748
Optional<SILFunctionTypeRepresentation> overrideRep = None)
48-
: substFnType(substFnType), origResultType(origResultType),
49-
substResultType(substResultType),
50-
foreign{foreignError, foreignAsync, foreignSelf},
49+
: origFormalType(llvm::None), substFnType(substFnType),
50+
origResultType(origResultType),
51+
substResultType(substResultType), foreign{foreignError, foreignAsync,
52+
foreignSelf},
5153
overrideRep(overrideRep) {}
5254

5355
CalleeTypeInfo(CanSILFunctionType substFnType,
5456
AbstractionPattern origResultType, CanType substResultType,
5557
Optional<SILFunctionTypeRepresentation> overrideRep = None)
56-
: substFnType(substFnType), origResultType(origResultType),
57-
substResultType(substResultType), foreign(),
58-
overrideRep(overrideRep) {}
58+
: origFormalType(llvm::None), substFnType(substFnType),
59+
origResultType(origResultType), substResultType(substResultType),
60+
foreign(), overrideRep(overrideRep) {}
5961

6062
SILFunctionTypeRepresentation getOverrideRep() const {
6163
return overrideRep.getValueOr(substFnType->getRepresentation());

lib/SILGen/ResultPlan.cpp

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -465,8 +465,9 @@ class ForeignAsyncInitializationPlan final : public ResultPlan {
465465
{
466466
// Allocate space to receive the resume value when the continuation is
467467
// resumed.
468-
opaqueResumeType = SGF.getLoweredType(AbstractionPattern::getOpaque(),
469-
calleeTypeInfo.substResultType);
468+
opaqueResumeType =
469+
SGF.getLoweredType(AbstractionPattern(calleeTypeInfo.substResultType),
470+
calleeTypeInfo.substResultType);
470471
resumeBuf = SGF.emitTemporaryAllocation(loc, opaqueResumeType);
471472
}
472473

@@ -475,10 +476,11 @@ class ForeignAsyncInitializationPlan final : public ResultPlan {
475476
SmallVectorImpl<SILValue> &outList) const override {
476477
// A foreign async function shouldn't have any indirect results.
477478
}
478-
479+
479480
ManagedValue
480-
emitForeignAsyncCompletionHandler(SILGenFunction &SGF, SILLocation loc)
481-
override {
481+
emitForeignAsyncCompletionHandler(SILGenFunction &SGF,
482+
AbstractionPattern origFormalType,
483+
SILLocation loc) override {
482484
// Get the current continuation for the task.
483485
bool throws = calleeTypeInfo.foreign.async
484486
->completionHandlerErrorParamIndex().hasValue();
@@ -527,13 +529,12 @@ class ForeignAsyncInitializationPlan final : public ResultPlan {
527529
auto env = SGF.F.getGenericEnvironment();
528530
auto sig = env ? env->getGenericSignature().getCanonicalSignature()
529531
: CanGenericSignature();
530-
SILFunction *impl = SGF.SGM
531-
.getOrCreateForeignAsyncCompletionHandlerImplFunction(
532-
cast<SILFunctionType>(impFnTy->mapTypeOutOfContext()
533-
->getCanonicalType(sig)),
534-
continuationTy->mapTypeOutOfContext()->getCanonicalType(sig),
535-
sig,
536-
*calleeTypeInfo.foreign.async);
532+
SILFunction *impl =
533+
SGF.SGM.getOrCreateForeignAsyncCompletionHandlerImplFunction(
534+
cast<SILFunctionType>(
535+
impFnTy->mapTypeOutOfContext()->getCanonicalType(sig)),
536+
continuationTy->mapTypeOutOfContext()->getCanonicalType(sig),
537+
origFormalType, sig, *calleeTypeInfo.foreign.async);
537538
auto impRef = SGF.B.createFunctionRef(loc, impl);
538539

539540
// Initialize the block object for the completion handler.
@@ -551,7 +552,7 @@ class ForeignAsyncInitializationPlan final : public ResultPlan {
551552
// _Block_copy-ing it.
552553
return ManagedValue::forUnmanaged(block);
553554
}
554-
555+
555556
RValue finish(SILGenFunction &SGF, SILLocation loc, CanType substType,
556557
ArrayRef<ManagedValue> &directResults) override {
557558
// There should be no direct results from the call.

lib/SILGen/ResultPlan.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,9 @@ class ResultPlan {
4949
emitForeignErrorArgument(SILGenFunction &SGF, SILLocation loc) {
5050
return None;
5151
}
52-
53-
virtual ManagedValue
54-
emitForeignAsyncCompletionHandler(SILGenFunction &SGF, SILLocation loc) {
52+
53+
virtual ManagedValue emitForeignAsyncCompletionHandler(
54+
SILGenFunction &SGF, AbstractionPattern origFormalType, SILLocation loc) {
5555
return {};
5656
}
5757
};

lib/SILGen/SILGen.h

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -182,10 +182,9 @@ class LLVM_LIBRARY_VISIBILITY SILGenModule : public ASTVisitor<SILGenModule> {
182182
/// implementation function for an ObjC API that was imported
183183
/// as `async` in Swift.
184184
SILFunction *getOrCreateForeignAsyncCompletionHandlerImplFunction(
185-
CanSILFunctionType blockType,
186-
CanType continuationTy,
187-
CanGenericSignature sig,
188-
ForeignAsyncConvention convention);
185+
CanSILFunctionType blockType, CanType continuationTy,
186+
AbstractionPattern origFormalType, CanGenericSignature sig,
187+
ForeignAsyncConvention convention);
189188

190189
/// Determine whether the given class has any instance variables that
191190
/// need to be destroyed.

lib/SILGen/SILGenApply.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3894,6 +3894,8 @@ RValue CallEmission::applyNormalCall(SGFContext C) {
38943894
// Get the callee type information.
38953895
auto calleeTypeInfo = callee.getTypeInfo(SGF);
38963896

3897+
calleeTypeInfo.origFormalType = origFormalType;
3898+
38973899
// In C language modes, substitute the type of the AbstractionPattern
38983900
// so that we won't see type parameters down when we try to form bridging
38993901
// conversions.
@@ -3911,6 +3913,8 @@ RValue CallEmission::applyNormalCall(SGFContext C) {
39113913
calleeTypeInfo.substResultType = formalType.getResult();
39123914

39133915
if (selfArg.hasValue() && callSite.hasValue()) {
3916+
calleeTypeInfo.origFormalType =
3917+
calleeTypeInfo.origFormalType->getFunctionResultType();
39143918
calleeTypeInfo.origResultType =
39153919
calleeTypeInfo.origResultType->getFunctionResultType();
39163920
calleeTypeInfo.substResultType =
@@ -4401,7 +4405,9 @@ RValue SILGenFunction::emitApply(
44014405
// we left during the first pass.
44024406
auto &completionArgSlot = const_cast<ManagedValue &>(args[completionIndex]);
44034407

4404-
completionArgSlot = resultPlan->emitForeignAsyncCompletionHandler(*this, loc);
4408+
auto origFormalType = *calleeTypeInfo.origFormalType;
4409+
completionArgSlot = resultPlan->emitForeignAsyncCompletionHandler(
4410+
*this, origFormalType, loc);
44054411

44064412
} else if (auto foreignError = calleeTypeInfo.foreign.error) {
44074413
unsigned errorParamIndex =

lib/SILGen/SILGenBridging.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2389,6 +2389,8 @@ void SILGenFunction::emitForeignToNativeThunk(SILDeclRef thunk) {
23892389
foreignError,
23902390
foreignAsync,
23912391
ImportAsMemberStatus());
2392+
calleeTypeInfo.origFormalType =
2393+
foreignCI.FormalPattern.getFunctionResultType();
23922394

23932395
auto init = indirectResult
23942396
? useBufferAsTemporary(indirectResult,

0 commit comments

Comments
 (0)