Skip to content

Commit 108cc64

Browse files
Merge pull request swiftlang#38633 from nate-chandler/cherrypick/rdar79383990/release/5.5
[5.5] [SILGen] Used formal type when bridging completion handler arguments.
2 parents 5c1a527 + 70dca91 commit 108cc64

File tree

14 files changed

+143
-63
lines changed

14 files changed

+143
-63
lines changed

include/swift/SIL/AbstractionPattern.h

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

13831390
void dump() const LLVM_ATTRIBUTE_USED;
13841391
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
@@ -661,6 +661,30 @@ AbstractionPattern::getObjCMethodAsyncCompletionHandlerType(
661661
}
662662
}
663663

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

lib/SIL/IR/SILFunctionType.cpp

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

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

lib/SIL/IR/SILInstructions.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2784,7 +2784,7 @@ SILType GetAsyncContinuationInstBase::getLoweredResumeType() const {
27842784
auto formalType = getFormalResumeType();
27852785
auto &M = getFunction()->getModule();
27862786
auto c = getFunction()->getTypeExpansionContext();
2787-
return M.Types.getLoweredType(AbstractionPattern::getOpaque(), formalType, c);
2787+
return M.Types.getLoweredType(AbstractionPattern(formalType), formalType, c);
27882788
}
27892789

27902790
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
@@ -185,10 +185,9 @@ class LLVM_LIBRARY_VISIBILITY SILGenModule : public ASTVisitor<SILGenModule> {
185185
/// implementation function for an ObjC API that was imported
186186
/// as `async` in Swift.
187187
SILFunction *getOrCreateForeignAsyncCompletionHandlerImplFunction(
188-
CanSILFunctionType blockType,
189-
CanType continuationTy,
190-
CanGenericSignature sig,
191-
ForeignAsyncConvention convention);
188+
CanSILFunctionType blockType, CanType continuationTy,
189+
AbstractionPattern origFormalType, CanGenericSignature sig,
190+
ForeignAsyncConvention convention);
192191

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

lib/SILGen/SILGenApply.cpp

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

3878+
calleeTypeInfo.origFormalType = origFormalType;
3879+
38783880
// In C language modes, substitute the type of the AbstractionPattern
38793881
// so that we won't see type parameters down when we try to form bridging
38803882
// conversions.
@@ -3892,6 +3894,8 @@ RValue CallEmission::applyNormalCall(SGFContext C) {
38923894
calleeTypeInfo.substResultType = formalType.getResult();
38933895

38943896
if (selfArg.hasValue() && callSite.hasValue()) {
3897+
calleeTypeInfo.origFormalType =
3898+
calleeTypeInfo.origFormalType->getFunctionResultType();
38953899
calleeTypeInfo.origResultType =
38963900
calleeTypeInfo.origResultType->getFunctionResultType();
38973901
calleeTypeInfo.substResultType =
@@ -4382,7 +4386,9 @@ RValue SILGenFunction::emitApply(
43824386
// we left during the first pass.
43834387
auto &completionArgSlot = const_cast<ManagedValue &>(args[completionIndex]);
43844388

4385-
completionArgSlot = resultPlan->emitForeignAsyncCompletionHandler(*this, loc);
4389+
auto origFormalType = *calleeTypeInfo.origFormalType;
4390+
completionArgSlot = resultPlan->emitForeignAsyncCompletionHandler(
4391+
*this, origFormalType, loc);
43864392

43874393
} else if (auto foreignError = calleeTypeInfo.foreign.error) {
43884394
unsigned errorParamIndex =

lib/SILGen/SILGenBridging.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2215,6 +2215,8 @@ void SILGenFunction::emitForeignToNativeThunk(SILDeclRef thunk) {
22152215
foreignError,
22162216
foreignAsync,
22172217
ImportAsMemberStatus());
2218+
calleeTypeInfo.origFormalType =
2219+
foreignCI.FormalPattern.getFunctionResultType();
22182220

22192221
auto init = indirectResult
22202222
? useBufferAsTemporary(indirectResult,

0 commit comments

Comments
 (0)